一.struct和class的区别?
class 和 struct 最本质的区别 : class 是引用类型,它在堆中分配空间,栈中保存的只是引用;而 struct 是值类型,它在栈中分配空间。 struct默认的数据访问控制是public的,class默认的访问控制是private的
什么是class?
class(类)是面向对象编程的基本概念,是一种自定义数据结构类型,通常包含字段、属性、方法、构造函数、索引器、操作符等。在.NET中,所有的类都最终继承自 System.Object 类,因此是一种引用类型,也就是说,new 一个类的实例时,在栈(stack)上存放该实例在托管堆(Managed Heap)中的地址,而实例的值保存在托管堆(Managed Heap)中。
托管堆(Managed Heap) :托管堆分配在被操作系统保留的一段内存区域中,这段内存区域是由 CLR 来管理的,这段内存称之为托管堆。
什么是struct?
struct(结构)是一种值类型,用于将一组相关的变量组织为一个单一的变量实体 。所有的结构直接派生自 System.ValueType,间接派生自System.Object,但结构是隐式密封的,不能作为基类再派生出其他的结构,也不能从类派生,但可以从接口派生。struct 实例在创建时分配在线程的栈(stack)上,它本身存储了值。所以在使用 struct 时,我们可以将其当作 int、char 这样的基本类型对待。
二、i++在两个线程分别执行100次,最大值和最小值分别多少
i++只需要执行一条指令,并不能保证多个线程i++,操作同一个i,可以得到正确的结果。因为还有寄存器的因素,多个cpu对应多个寄存器。每次要先把i从内存复制到寄存器,然后++,然后再把i复制到内存中,这需要至少3步。从这个意义上讲,说i++是原子的并不对。
如此,假设两个线程的执行步骤如下:
1、 线程A执行第一次i++,取出内存中的i,值为0,存放到寄存器后执行加1,此时CPU1的寄存器中值为1,内存中为0;
注:对于多线程,线程共用一个内存,如果线程A在寄存器执行操作后而没有写入内存,则会切
换到另一个线程。
2、线程B执行第一次i++,取出内存中的i,值为0,存放到寄存器后执行加1,此时CPU2的寄存器中值为1,内存中为0;
3、线程A继续执行完成第99次i++,并把值放回内存,此时CPU1中寄存器的值为99,内存中为99;
注:线程A在此的每一步执行,都写回内存,直到完成第99次
4、线程B继续执行第一次i++,将其值放回内存,此时CPU1中的寄存器值为1,内存中为1;
注:由于线程B之前未写回内存,因此停留在第一次,而当其写回时,覆盖了原来的99,内存
中的值变为1
5、线程A执行第100次i++,将内存中的值(现在是1)取回CPU1的寄存器!!!,并执行加1,此时CPU1的寄存器中的值为2,内存中为1;
6、线程B执行完所有操作,并将其放回内存,此时CPU2的寄存器值为100,内存中为100;
注:B执行完100次i++,则CPU2寄存器值为100,写入内存,100覆盖了原来的1
7、线程A执行100次操作的最后一部分,将CPU1中的寄存器值放回内存(值为2,见第5步),内存中值为2;
8、结束!
注:最大值200的情况:线程A和B每次执行完i++均写入内存,交替进行
所以该题目便可以得出最终结果,最小值为2,最大值为200。
三、一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。
我们还是从头到尾依次异或数组中的每一个数字,那么最终得到的结果就是两个只出现一次的数字的异或结果。因为其他数字都出现了两次,在异或中全部抵消掉了。由于这两个数字肯定不一样,那么这个异或结果肯定不为0,也就是说在这个结果数字的二进制表示中至少就有一位为1。我们在结果数字中找到第一个为1的位的位置,记为第N位。现在我们以第N位是不是1为标准把原数组中的数字分成两个子数组,第一个子数组中每个数字的第N位都为1,而第二个子数组的每个数字的第N位都为0。
现在我们已经把原数组分成了两个子数组,每个子数组都包含一个只出现一次的数字,而其他数字都出现了两次。
四、C++类构造函数初始化列表执行顺序:对成员变量的初始化,是严格按照声明次序,而不是在初始化列表中的顺序进行初始化