当前位置: 首页 > news >正文

沈阳百度网站的优点嵌入式培训机构

沈阳百度网站的优点,嵌入式培训机构,企业展厅布展设计,个人简介代码网页制作一#xff1a;背景1. 讲故事最近也是奇怪#xff0c;在社区里看到好几篇文章聊static 的玩法以及怎么拿这个和面试官扯半个小时#xff0c;有点意思#xff0c;点进去看都是java版的#xff0c;这就没意思了#xff0c;怎么也得有一篇和面试官扯C# 中的 static用法撒背景1. 讲故事最近也是奇怪在社区里看到好几篇文章聊static 的玩法以及怎么拿这个和面试官扯半个小时有点意思点进去看都是java版的这就没意思了怎么也得有一篇和面试官扯C# 中的 static用法撒既然没有人开这个头那我就献丑了。。。下面以QA的方式记述大家可以代入一下能回答几个问题。二QA环节面试官请问您都是在什么场景下用static的         解析可能面试官潜意识的想问问你会不会使用本地缓存。码农先不说我的场景纵观C#的底层FCL源码你会发现很多的 static修饰的集合如ThreadPool:[SecurityCritical]private static bool QueueUserWorkItemHelper(WaitCallback callBack, object state, ref StackCrawlMark stackMark, bool compressStack){QueueUserWorkItemCallback callback new QueueUserWorkItemCallback(callBack, state, compressStack, ref stackMark);ThreadPoolGlobals.workQueue.Enqueue(callback, forceGlobal: true);result true;} 其中的 workQueue 就是一个静态队列不仅如此还有Quartz底层自研的线程池还有web中的SessionApplication无非就是想用static做一个池化技术和AppDomain级的本地缓存所以我的应用场景也无非是这些了。面试官您会几种实现单例的方式        解析既然面试官想和你扯static就是想看看你会不会用 static cctor静态构                        造器构建单例!码农实不相瞒不管是用懒汉式还是饿汉式大体上也就这几种 双检锁, static cctor, LazyT, 不知道您想让我细说哪一种面试官那就说一下静态构造函数为什么可以实现单例        解析可能觉得码农回答的有点拽问深一点看看是不是唬人的。码农说到单例每一个人都会提到在多线程场景下的并发问题导致多个单例的尴尬所以有了给代码加上各种花哨的锁比如刚才我提到的双检索,所以说没有锁。。。这个问题是搞不定的换句话说 静态构造函数 也是用了锁机制。面试官你确定用到了锁有证据吗         解析有戏了对你产生感兴趣了愿听其详。码农既然要证据那我先构思一段如下代码class Program{static void Main(string[] args){Person person new Person();Console.ReadLine();}}class Person{static Person(){Console.WriteLine(正在处理静态函数);Console.ReadLine();}}然后抓一个dump文件用windbg 看一下主线程的托管和非托管堆栈。 C#0:000 ~0s ntdll!NtReadFile0x14: 00007ff88d2eaa64 c3 ret 0:000 !dumpstack OS Thread Id: 0x4ac0 (0) Current frame: ntdll!NtReadFile0x14 Child-SP RetAddr Caller, Callee 000000c119bfdcd0 00007ff817090957 (MethodDesc 00007ff816f85aa8 0x37 ConsoleApp6.Person..cctor()), calling (MethodDesc 00007ff8741140b8 0 System.Console.ReadLine()) 000000c119bfdd10 00007ff8765e6c93 clr!CallDescrWorkerInternal0x83 000000c119bfdd18 00007ff87660a51c clr!ListLockEntry::FinishDeadlockAwareEnter0x40, calling clr!GetThread 000000c119bfdd50 00007ff8765e6b79 clr!CallDescrWorkerWithHandler0x4e, calling clr!CallDescrWorkerInternal 000000c119bfdd80 00007ff87390d663 clrjit0x1d663, calling clrjit0x1be60 000000c119bfdd90 00007ff87660c56b clr!DispatchCallDebuggerWrapper0x1f, calling clr!CallDescrWorkerWithHandler 000000c119bfddf0 00007ff87660c535 clr!DispatchCallSimple0x93, calling clr!DispatchCallDebuggerWrapper 000000c119bfde40 00007ff87660a5b9 clr!MethodTable::EnsureInstanceActive0x110, calling clr!DomainFile::EnsureLoadLevel 000000c119bfde90 00007ff87660bf65 clr!MethodTable::RunClassInitEx0x111, calling clr!DispatchCallSimple 000000c119bfdec0 00007ff88d350119 ntdll!RtlDebugFreeHeap0x2a9, calling ntdll!RtlLeaveCriticalSection 000000c119bfdee0 00007ff88d2b77a2 ntdll!RtlInitializeCriticalSection0xa2, calling ntdll!_security_check_cookie 000000c119bfdf80 00007ff87660a51c clr!ListLockEntry::FinishDeadlockAwareEnter0x40, calling clr!GetThread 000000c119bfdfc0 00007ff87660c15c clr!MethodTable::DoRunClassInitThrowing0x3b9, calling clr!MethodTable::RunClassInitEx 000000c119bfe810 00007ff8765f08b4 clr!ListLockEntry::scalar deleting destructor0xd4, calling clr!operator delete 000000c119bfff10 00007ff88d044034 KERNEL32!BaseThreadInitThunk0x14, calling KERNEL32!guard_dispatch_icall_nop 000000c119bfff40 00007ff88d2c3691 ntdll!RtlUserThreadStart0x21, calling ntdll!guard_dispatch_icall_nop 仔细看上面的代码你会发现有很多处 ListLockEntry这就和锁扯上了关系哈这算证据不面试官小伙子windbg玩的挺溜那请回答一下静态变量是存在哪的有什么证据吗         解析转变思路开始证据先行了????????????。码农犹记得 CLR via C# 中说静态变量是存放在类型对象中这就好办了我去挖一下不就可以了哈其实CLR内部用了两个数据结构来表示 类型对象 和 对象类型一个叫做 EEClass一个叫做 方法表下面我定义一个 lockMe 的静态变量代码如下 class Person{public static object lockMe new object();static Person(){Console.WriteLine(正在处理静态函数);Console.ReadLine();}} 然后祭出杀器 windbg 用 name2ee 找到Person的EEClass将它打出来。 0:000 !name2ee ConsoleApp6.exe!ConsoleApp6.Person Module: 00007ff816fb4140 Assembly: ConsoleApp6.exe Token: 0000000002000003 MethodTable: 00007ff816fb5ae8 EEClass: 00007ff816fb2558 Name: ConsoleApp6.Person0:000 !DumpClass /d 00007ff816fb2558 Class Name: ConsoleApp6.Person mdToken: 0000000002000003 File: C:\dream\Csharp\ConsoleApp1\ConsoleApp6\bin\x64\Debug\ConsoleApp6.exe Parent Class: 00007ff873f52f68 Module: 00007ff816fb4140 Method Table: 00007ff816fb5ae8 Vtable Slots: 4 Total Method Slots: 6 Class Attributes: 0 Transparency: Critical NumInstanceFields: 0 NumStaticFields: 1MT Field Offset Type VT Attr Value Name 00007ff873f75dd8 4000001 8 System.Object 0 static 0000020ae5c42d90 lockMe 可以看到最后一行的 lockMe就是那本书中所说的类型对象存储的静态字段。面试官那既然 static 属于类型对象为什么GC不回收它呢        解析开启三连击看你沉浮有多深码农为什么GC不回收它这里我有两个个人观点1 clr的底层机制决定的clr在启动gc组件进行回收前会先在堆中找几类root对象从而开启标记引用链之路常见的root对象有第一个方法的局部变量这个JIT在编译方法的时候最清楚它通过维护一个表给GC参谋。第二个static变量这是天然的root根与AppDomain共存亡。第三个其他乱七八糟的root根。2 static地址是在启动堆而不是在托管堆理应不受GC管控这句话的证据在哪里呢在 C# via CLR 那本书中说JIT开始编译方法内代码的时候会判断当前的类型Pereson是否已经在AppDomain中加载了如果没有很显然会抛异常如果有此类型那就从程序集的元数据中找到该类型的所有描述构建Person的 EEClass数据结构。使用 ILDasm 查看程序集中关于构建EEClass的Person元数据。可以看到确实有 lockMe 的元数据表示有了这些EEClass就可以构建出来然后JIT编译器可以将其分配在加载堆和AppDomain绑定接下来的问题是怎么去看是在加载堆用什么命令去看当然是windbg啦,用 !eeheap -loader 即可。 0:000 !eeheap -loader Loader Heap: -------------------------------------- System Domain: 00007ff877002af0 LowFrequencyHeap: 00007ff816f80000(3000:3000) Size: 0x3000 (12288) bytes. HighFrequencyHeap: 00007ff816f84000(9000:1000) Size: 0x1000 (4096) bytes. StubHeap: 00007ff816f8d000(3000:2000) Size: 0x2000 (8192) bytes. Total size: Size: 0xa000 (40960) bytes. -------------------------------------- Shared Domain: 00007ff877002520 LowFrequencyHeap: 00007ff816f80000(3000:3000) Size: 0x3000 (12288) bytes. HighFrequencyHeap: 00007ff816f84000(9000:1000) Size: 0x1000 (4096) bytes. StubHeap: 00007ff816f8d000(3000:2000) Size: 0x2000 (8192) bytes. Total size: Size: 0xa000 (40960) bytes. -------------------------------------- Domain 1: 000001246cae21f0 LowFrequencyHeap: 00007ff816f90000(3000:3000) Size: 0x3000 (12288) bytes. HighFrequencyHeap: 00007ff816f93000(a000:3000) Size: 0x3000 (12288) bytes. StubHeap: Size: 0x0 (0) bytes. Total size: Size: 0x6000 (24576) bytes. -------------------------------------- Total LoaderHeap size: Size: 0x1a000 (106496) bytes.从上图中可以看到C#应用程序会有三个应用程序域 System Domain,Shared Domain, Domain1每一个AppDomain都有自己的私有加载堆我们的 Person 类型不出意外就是在 Domain 1 上了哈如果你好奇可以看看这个AppDomain都有啥。 0:000 !DumpDomain /d 000001246cae21f0 -------------------------------------- Domain 1: 000001246cae21f0 LowFrequencyHeap: 000001246cae29e8 HighFrequencyHeap: 000001246cae2a78 StubHeap: 000001246cae2b08 Stage: OPEN SecurityDescriptor: 000001246cae4870 Name: ConsoleApp6.exe Assembly: 000001246cb7f990 [C:\WINDOWS\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll] ClassLoader: 000001246cb7fae0 SecurityDescriptor: 000001246cb7e230Module Name 00007ff873f51000 C:\WINDOWS\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dllAssembly: 000001246cb954c0 [C:\dream\Csharp\ConsoleApp1\ConsoleApp6\bin\x64\Debug\ConsoleApp6.exe] ClassLoader: 000001246cb95610 SecurityDescriptor: 000001246cb933f0Module Name 00007ff816f94140 C:\dream\Csharp\ConsoleApp1\ConsoleApp6\bin\x64\Debug\ConsoleApp6.exe 程序集下就是 Module如你看到的 ConsoleApp6.exe就是一个module哈还可以继续dump module看元数据啥的。总之你让我找到lockme在启动堆上的地址目前还没这个能力不过要知道的是lockMe 引用的object地址是在启动堆上分配而object对象是在托管堆上分配的不要搞混淆了。三后续面试官看了看手表已经快一个小时了此时面试官心里有了答案按照职场潜规则万不可录取不然我的位置往哪搁呢
http://www.yutouwan.com/news/451124/

相关文章:

  • 中山最好的网站建设外贸 网站 模板
  • 微信小程序展示网站建设多少钱吴桥做网站
  • 怎么做网站关键词库排名天元建设集团有限公司是什么性质
  • 做影视类短视频的资源网站上海学校网站建设
  • 常州高端网站定制公司建网站的基本步骤
  • 网站管理页面永久的海外域名
  • 网站开发中期检查网站建设明细报价表
  • 开源电商网站建设价格如何自学编程
  • 微信小程序制作多少钱一个泉州优化营商环境
  • 阿里数据德阳网站怎么做seo
  • 宁波网站建设服务电话fixed wordpress
  • 移动端网站如何做导出功能哪些网站做科技专题
  • 古镇营销型网站建设优书网首页
  • 云南省建设工程质量协会网站如何用虚拟主机安装wordpress
  • 华耀建设网站红色餐饮网站源码
  • 惠州网站建设推广兰州小程序定制开发
  • 济南网站建设-中国互联wordpress表单数据前台显示图片
  • 个人如何建立网站wordpress win2012 r2
  • 做仓单的网站全国工商企业查询平台
  • 怎么建设品牌网站丽水微信网站建设哪家好
  • seo网站优化案例网站设计就业培训学校排名
  • 网站设置关键字thinkphp企业网站开发
  • 无忧网络网站建设aspcms系统
  • 济南网站建设和维护linux wordpress安装教程
  • 自己搭建网站需要多少钱dnf怎么做盗号网站
  • 怎么查一个地区的所有网站域名医院网站建设熊掌号
  • 全栈工程师是做网站吗合肥网站建设政务区
  • 说明怎样做才能通过互联网访问你制作的网站整合营销沟通的目的是
  • 如何解决网站只收录首页的一些办法wordpress图片博客
  • 开发网站年度工作总结及明年工作计划邢台太行中学收费