困难的.net问题

4

我想分享一些让我困惑的问题。请看一下。:-)

.NET进程在四核i7处理器上运行时有多少个GC线程?

我说4x2=8?

哪个GC代使用更多的内存,为什么?

我说Gen2,但不知道为什么?我猜可能是因为每本书或网站上都显示它的大小更大。 :-P

逆变是协变的必然结果吗?请解释。

这是关于泛型的,但我不知道如何解释。

EnlistDistributedTransaction方法不支持哪个数据库?

我说Oracle和IBM DB?

C#中codeBase元素的重要性及其用途?

我说程序集,但不知道确切的重要性。

好吧,我设法通过了面试,但这些问题确实让我很难。请帮我看看这些问题是否可以给我一些建议?

谢谢 Ajitpal


1
“Contravariance is the corollary of covariance?”一定是不正确的;corollary并没有接近这个意思。也许应该用“counterpart”,或者更准确地说,“dual”? - Domenic
1
没有一个问题是关于C#的。大多数都是关于.NET,而协变/逆变性问题是关于计算机科学的普遍问题。 - CodesInChaos
10
这些问题中有一些听起来更像是资深开发人员试图通过问一些超级棘手和离题的问题来炫耀他们所知道的知识。 - slugster
1
我认为这些不是好的面试问题。如果你可以在SO上作为答案的一部分得到答案,那么它们就不是好问题。如果你必须查看代码、编写代码、解释如何解决问题,那么这些都是好问题,但是任何可以通过阅读一段文本来获取的信息都不能告诉面试官有关受访者的好处。 - Lasse V. Karlsen
1
此外,对于常规开发人员来说,了解有多少个GC线程通常是否有用?我的意思是,对于服务器和工作站GC之间的差异有一般的概述知识当然有帮助,但像这样的确切细节呢?我不知道我的机器上有多少个,这会让我成为该公司不适合的开发人员吗? - Lasse V. Karlsen
显示剩余6条评论
3个回答

3

协变性/逆变性

对于协变性/逆变性,他们可能会想到数组的例子(或者一般来说是R/W协变对象)。

class A
{
}

class B : A
{
}

static void Func(A[] a) {
    a[0] = new A();
}

B[] b = new B[5];
Func(b);

这是“合法的”写法,但在赋值时(在Func中)会抛出一个ArrayTypeMismatchException的异常。这里协变性引起了问题。从Func的角度来看,这是“奇怪的”。我认为逆变性是ReadWrite CoVariance的“遗漏”推论(它应该存在,但显然不可能实现)。
对于垃圾回收器。

http://architecturebyashwani.blogspot.com/2010/02/foreground-gc-and-background-gc.html

似乎工作站GC总是在分配内存的线程中发生,因此没有任何“额外”的GC线程。我会补充说明这取决于版本,因此它可能会从.NET的一个版本到另一个版本(Mono处理方式不同)发生变化。使用服务器GC时,您需要专门的GC线程,每个处理器一个。例如,I7 Quad Core可能具有HT(超线程),因此有8个“核心”,因此有8个线程。
对于代的大小...我会说“通常”Gen2更大,因为大对象始终是Gen2(http://msdn.microsoft.com/en-us/magazine/cc534993.aspx)(从技术上讲,它们不是Gen2...它们存在于一个单独的空间中,在检查Gen2时进行检查,但我们将忽略这一点...问题不是很清楚,并且实现是定义和不透明的,因此我们不知道Gens在内存中如何“LinkedListed”),并且长寿命对象将进入Gen2(因此,在程序的“启动”阶段之后,所有单例和其他长寿命对象都在Gen2中)。
但是...一般来说这并不正确。
假设你创建了一个只进行单次分配的程序(var obj = new object())。那个分配将会从Gen0开始。当对象被分配时,有一个对象存在,那个对象就在Gen0中,所以严格意义上来说,Gen0是最大的。
DTC
IBM DB2支持DTC,Oracle也支持:

这是半重言的,但我认为EnlistDistributedTransaction不受以下数据库支持:

  • 不支持事务的数据库(某些MySQL,取决于基础数据库类型)
  • 不支持事务监视器/事务协调器的数据库,但据我所读,使用支持事务的基础数据库的新版MySQL似乎能够支持DTC(例如阅读http://dev.mysql.com/doc/refman/5.0/en/xa.html

<codeBase>元素

以这种方式编写更加清晰明了。

http://msdn.microsoft.com/en-us/library/efs781xb.aspx

你可以强制应用程序使用特定版本的已引用程序集运行。如果程序集的不同版本之间存在“破坏性变更”,则此方法很有用。


0
  1. 实现细节。可能在不同版本的.net中有所不同。并且可能在服务器/客户端GC之间有所不同。并且可能根据GC处于哪个阶段而发生变化。我假设在gc的某些阶段中,将使用与(虚拟)CPU /核心数量相同的线程,因此2x超线程四核心可能会使用多达8个线程。但是如果某些阶段仅为单线程,则我不会感到惊讶。
    特别是客户端GC在很大程度上与您的其他代码并行运行。因此,使用所有核心可能是一个坏主意,因为它会减慢程序速度。另一方面,服务器GC针对最大速度进行了优化,并停止整个程序。因此,对于服务器GC,尽可能多地进行多线程处理听起来像是一个好主意。

  2. 最有可能是Gen2,因为所有长期存在的对象都会在那里累积。但这取决于您的内存分配模式。其他代在(软)内存限制之后,该代的收集就会发生。
    然后还有大对象堆,它是与正常代堆分开的堆。如果您在那里分配大型对象,则有很大机会它会变得比正常代堆更大。我认为它仅在Gen2收集期间进行收集,因此可以将其视为Gen2的一部分。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接