精简重要的IT知识点
1.数据类型占据字节大小问题?
答:数据类型指的是数据值的范围和在这一组值上的操作,数据类型有byte,char,int,long,float,double,bool等类型,数据类型占据字节的大小,在不同的编程语言,编译器和操作系统来决定,在C语言中,int类型根据编译器的不同,有2字节,也有4字节,而Java语言中,int类型占据固定的4字节,不会因为JVM的版本是32位和64位而发生变化。
2.参数传递的方式?
答:参数传递有以下几种方式,⑴按值传递⑵按结果传递⑶按值-结果传递⑷按引用传递⑸按名称传递。
按值传递:即将实参的值传递给形参,对形参的修改不会影响实参,形参会在被分配在栈上;
按结果传递:即实参不会向形参传递数值,形参相当于新的局部变量,当函数结束时,程序会把形式参数的值写入实际参数中;
按值-结果传递:是按值传递和按结果传递的结合,形参相当于新的局部变量,实参用来对形参做初始化,函数结束时,程序会把形式参数的值写入实际参数中;
按引用传递:即将实参的地址传递给形参,对形参的修改将直接影响实参;
按名称传递:将变量当成符号,将该符号名字传递给某个函数。
3.存储类别?
答:存储类别决定变量存储在内存的哪一部分,决定该空间的有效期,即,存储类别决定的是可见范围,有以下几种⑴auto⑶extern⑶register⑷static四种。
auto:是C语言默认的存储类别,对于函数中的该变量,称为局部变量,即当函数调用的时候创建该变量,当函数结束时销毁变量,即函数外部是访问不到该局部变量的;
extern:声明在函数之外,又称全局变量,该变量在程序执行期间一直存在,当全局变量和局部变量同名,则局部变量优先;
register:对于频繁访问的变量,声明这个的变量,存储在寄存器中;
static:可以声明在外部,内部,其只在编译的时候初始化一次,静态变量的值会一直保留到程序结束。
4.预处理器?
答:预处理器会对代码进行预处理,预处理过的代码称为预处理代码,预处理器的操作一般为:⑴把头文件代码加载到程序中⑵将宏展开,进行替换⑶条件编译。
5.printf函数?
答:printf函数用来输出打印变量的值,在C语言中,printf函数是有返回值的,其返回打印出来的字符个数。
6.初始化和赋值的区别?
答:初始化是在变量被定义的同时为其指定值;赋值是变量的值有所变化,即使用一个新的值对来源的值进行替换。
7.将两个数进行交换,不适用临时变量?
答:⑴ a=a+b;b=a-b;a=a-b ⑵a=a+b-(b=a)⑶a=a^b;b=a^b;c=b^a;等等
8.Java中的HashMap原理?
答:HashMap是一个由元素组成的数组,数组中的元素又是链表,对于数组的下标是通过hash函数来计算的,当对HashMap进行操作时,会根据数据计算出哈希码来对应数组的bucket位置,用来保存对象。注意bucket保存键和值。当不同的对象,具有相同的哈希码时,进行put方法时,两个对象会位于同一个bucket中,但是后者会插入到链表中前一个对象的后面,因为他们的key不相同,就会在链表中进行区分。
9.HashMap和Hashtable的区别?
答:⑴hashMap不同步,允许有null值,其键和值都可以是null,但Hashtable同步,但不允许有null值 ;⑵HashMap不保证数据是以固定的顺序出现的,因为它的存储位置是根据哈希算法确定的;
10.序列化和反序列化?
答:序列化是将对象状态保存成一系列字节,随后根据这些字节,可以把对象重新构建出来,在Java中,只需使类实现java.io.Serializable接口。反序列化:即变量不参与序列化,不能被序列化,只需标注为transient即可。
11.解释器和编译器区别?
答:⑴编译器将高级语言转变为计算机可以识别的机器语言,解释器将高级语言转换为中间语言;⑵编译器将整个代码一次性编译完,解释器一行一行的编译⑶编译器在执行完编译之后才会列出错误,解释器只要碰到错误,就会停止编译⑷编译器可以将程序编译成独立的可执行文件,而解释器,则需要每次在运行的时候需要解释器。
12.快速失败和安全失败区别?
答:快速失败:当在迭代一个集合的时候,如果有另一个线程在修改正在访问的那个集合,则抛出ConcurrentModification异常,java.util包下都是快速失败。安全失败:在迭代的时候,会去对低层集合进行一个拷贝,所以在修改上层集合的时候不会影响,不会抛出ConcurrentModification异常,java.util.concurrent包下都是安全失败。
13.Java GC的发生时间,做什么?
答:JVM的Java运行时数据有6种,分别是程序计数器,虚拟机栈,本地方法栈,堆,方法区,常量池。对于Java对象,一般被分配到堆中,堆又可以细分,堆根据对象的状态可以分为,新生代,老年代。新生代用来存储生命周期长,且新建的小对象,老年代用来存放生命周期长的大对象,新生代又分为一个Eden区和两个survivor区,对于新创建的对象,在新生代的Eden区,如果空间不足,就向其中的一个survivor区上存放对象,如果还是不能存储对象,则会发生一次在新生代的minor GC,会对区域进行一个垃圾清理,清理掉“死掉”(没有引用)的对象,并将存活的对象复制到另一个survivor区中,然后清空Eden区和刚开始的survivor区的对象,在某次GC中,仍然放不下对象,就会将一些对象放入到老年代区中,大对象和声明周期比较长的对象直接进行老年代,每次进行minor GC的时,对晋升到老年代的的对象进行分析,当马上要晋升到老年代的对象大于老年代剩余的空间大小的时候,会执行一个Full GC。
对象是否存活的判断有:可达性分析,引用计数法;
GC的算法由:标记清除,标记-复制,标记-整理。新生代是标记清理,老年代是清除和整理。
14.Java Volatile?
答:Volatile关键字用来修饰变量,对于多线程变量的同步问题,可以使用Volatile来解决问题,使用volatile关键字可以使变量的修改,对多个线程的可见性。
共享内存是在主存中,读取的时候 CPU 会将这块共享内存复制到缓存中(多核处理器每个 CPU 都有一个缓存),工作线程访问该共享内存的时候,先从缓存中获取,如果获取不到再从主存中获取。线程在工作内存中修改完共享变量后,会将其值同步回共享变量所在主存区域,此时需要访问主存,但是如果这块主存缓存过的话,并不会把值写回内存,而是写入缓存;对于其他 CPU 上的线程来说,如果需要访问 flag ,也会直接先从自己的缓存中获取该变量的值,即使该 flag 的值已经改变,其他线程读取到的也只能是自己缓存中已过期的值。如果加了 volatile 关键字,那么对该变量的读会直接从主存中读取,对该变量的写也直接写入主存,相当于使缓存无效。
参考书籍有《程序员面试手册》,以及个人的理解。如有问题,敬请指出,谢谢。