一、Java基础
Java和C语言有什么区别?Java好在哪里?
内存管理:Java中不需要考虑内存的问题,如果想用一个对象,new一个就可以,当不再使用这个对象后,JVM会自动进行回收。而C需要使用malloc之类的方法申请内存,然后不想用了需要使用free去释放内存。
面向对象:Java是一门面向对象的编程语言,而C语言主要是面向过程的
解释与编译共存:Java是一门解释与编译并存的语言,而C语言是编译型语言。
Java程序从源代码到运行的过程是这样的:.java文件—>javac编译—>.class文件—>解释器和JIT即时编译器—>机器码—>OS
.class—>机器码这一步JVM加载器首先加载字节码文件,然后通过解释器逐行解释运行,但这种方式执行速度相对较慢。而且很多方法和代码块是被频繁调用的(热点代码),所以后面引进了JIT编译器,而JIT属于运行时编译,当JIT编译器完成第一次编译后,会将字节码对应的机器码保存下来,下次直接使用(也就是说热点代码基本上已经被编译成机器码保存了下来,而其他的代码可以通过解释器执行,这样就大大提高了程序运行效率)。JVM 会根据代码每次被执行的情况收集信息并相应地做出一些优化,因此执行的次数越多,它的速度就越快。
一次编译到处运行:Java是先从.java文件通过javac编译成字节码文件,然后这个字节码文件可以在任何操作系统的JVM上运行。当然其他语言编译成字节码文件后也可以在JVM上运行。因此Java的开发效率比较高。
开发效率高:C语言主要面向底层,像内存、CPU等;而Java不需要,虚拟机已经帮助解决很多底层方面的问题。
指针:Java 不提供指针来直接访问内存,程序内存更加安全
为什么Java要经过中间步骤转换为字节码,然后再用JVM执行Java字节码,而不能一步到位,直接从原始代码到执行结果?
每次重新执行同样的代码都必须重新经过从源代码到机器语言之间的编译过程,而Java可以在编译成字节码后,在多平台运行。
怎么理解Java的跨平台性,一次编译到处运行?
简单地说就是编译后的Java程序可直接在不同的平台上的虚拟机运行,而不用重新编译。
面向对象和面向过程的区别?
面向过程是直接将解决问题的步骤分析出来,然后用函数把步骤一步一步实现,再依次调用就可以了;而面向对象是将构成问题的事物,分解成若干个对象,建立对象的目的不是为了完成一个步骤,而是为了描述某个事物在解决问题过程中的行为。面向过程思想偏向于我们做一件事的流程,首先做什么,其次做什么,最后做什么。面向对象思想偏向于了解一个人,这个人的性格、特长是怎么样的,有没有遗传到什么能力,有没有家族病史。
面向过程的性能比面向对象高,因为类调用需要实例化,开销比较大,比较消耗资源。如单片机、嵌入式开发、Linux/Unix等一般采用面向过程开发,因为在它们看来性能是最重要的因素。而面向对象易维护、易扩展(封装、继承和多态,容易设计高内聚低耦合的系统结构)、开发效率高(接近日常生活和自然的思考方式)
如何理解面向对象三大特性:封装、继承、多态?
封装:将类成员属性(数据)和类的方法(对数据的操作)捆绑到一起,形成对外界的隐藏,同时提供外界可以操作的接口。封装的意义在于保护或者防止代码被我们无形破坏,保护成员属性,不让类以外的程序直接访问和修改,隐藏方法细节。
继承:继承是在已有的类中派生出新的类,新的类能够吸收原有类的属性和行为,并能够扩展新的能力。继承能够反映现实生活中的真实关系,减少了代码冗余,对父类的代码和属性进行重写。子类不可以选择性的继承父类的属性和方法,而是要全部继承。(父类中的静态方法可以被继承但是不能被重写)
多态:父类引用指向不同子类实例对象。Java实现多态需要三个必要条件:继承、重写、向上转型。继承:在多态中必须存在有继承关系的子类和父类。重写:子类对父类中的某些方法进行重新定义,那么在调用方法时就会执行子类中的方法。向上转型:需要将子类的引用赋给父类对象,只有这样该引用才既能调用父类的方法,又能调用子类的方法。
类继承会有什么问题吗,一般什么情况下才会去用继承?
a:子类只能继承父类所有非私有的成员(成员方法和成员变量)。但是可以通过暴力反射来获取。
b:子类不能继承父类的构造方法,但是可以通过super关键字去访问父类构造方法。
类继承打破了封装性,这迫使开发者要去了解超类的实现细节,导致了子类和超类的耦合,当父类改变时可能要相应地对子类做出改变。子类从父类继承的方法在编译时就确定下来了,所以无法在运行期间改变从父类继承的方法的行为。
继承是 is-a 的关系
为什么重写equals方法还要重写hashcode方法?
需要保证重写后的equals方法认定相同的对象的hashcode相等。
深克隆和浅克隆
浅拷贝:在拷贝对象时,只对基本数据类型进行了拷贝,对于引用数据类型只是进行了引用地址的传递,而没有创建一个新的对象,这就是浅拷贝;
深拷贝:相应地,对于引用数据类型进行拷贝时,创建了一个新的对象,并且复制了其内的成员变量,就叫做深拷贝。(深拷贝实现:1. 继续利用clone方法 2. 序列化这个对象)
反射相关
反射指在运行状态时,对于任意一个类,都可以获取到这个类的全部属性和方法。对于任意一个对象,都能够调用它的任意方法和属性,并且可以改变它的属性,这种动态获取信息以及动态调用对象的方法的功能称为Java语言的反射机制。
注解的实现原理
注解的作用:
1 生成文档。这是最常见的,也是Java 最早提供的注解。常用的有@param
@return
等; 2 跟踪代码依赖性,实现替代配置文件功能。比如Dagger 2
依赖注入,未来java 开发,将大量注解配置,具有很大用处; 3 在编译时进行格式检查。如@override
放在方法前,如果你这个方法并不是覆盖了超类方法,则编译时就能检查出。
注解的原理:
注解本质是一个继承了Annotation
的特殊接口,在调用getDeclaredAnnotations()
方法(通过反射方法获取)的时候,返回一个代理$Proxy
对象,这个代理对象是由jdk
动态代理创建,使用Proxy
的newProxyInstance
方法,传入接口和InvocationHandler
的一个实例(也就是 AnotationInvocationHandler
) ,最后返回一个实例。期间,在创建代理对象之前解析注解的时候,从该注解类的常量池中取出注解的信息,包括之前写到注解中的参数,然后将这些信息在创建 AnnotationInvocationHandler
时候,传入进去作为构造函数的参数。
1 | static class AnnotationInvocationHandler implements InvocationHandler{ |
1 | public static Object newProxyInstance(ClassLoader loader, |
newProxyInstance,方法有三个参数:
loader: 用哪个类加载器去加载代理对象
interfaces: 动态代理类需要实现的接口
h: 动态代理方法在执行时,会调用h里面的invoke方法去执行
Lambda表达式的优缺点?
优点:
简洁。
非常容易并行计算。
结合 hashmap 的 computeIfAbsent 方法,递归运算非常快。java有针对递归的专门优化。
缺点:
- 若不用并行计算,很多时候计算速度没有比传统的 for 循环快。(并行计算有时需要预热才显示出效率优势,并行计算目前对 Collection 类型支持的好,对其他类型支持的一般)
- 不容易调试。
- 若其他程序员没有学过 lambda 表达式,代码不容易让其他语言的程序员看懂。
- 在 lambda 语句中强制类型转换貌似不方便,一定要搞清楚到底是 map 还是 mapToDouble 还是 mapToInt
Stream流式编程的好处?终止方法和延迟方法的区别是?终止方法存在的意义是什么?
二、Java集合
HashMap底层实现
JDK1.7使用数组+链表;JDK1.8使用数组+链表+红黑树
链表会转化为红黑树的两个条件:
①链表的长度达到8;
②HashMap底层使用的table数组长度length达到64(当HashMap底层使用的table数组长度达到64时,链表的长度达到8这种情况不满足泊松分布,即出现的概率非常非常小,一般是存在恶意攻击,就是一直存入同样的值,因此此时将链表转换为红黑树);
注:如果不满足后者,将会触发扩容方法
链表长度大于8转化为红黑树,小于6红黑树转化为链表;为什么不直接设置成大于8转化成红黑树,小于8转化成链表;(中间有个差值7进行过渡是为了避免链表和树频繁转换,如果一个HashMap不停的插入、删除元素,链表个数在8左右徘徊,就会频繁的发生树转链表、链表转树,效率会很低)
HashMap为什么要引进红黑树?为什么不用其他的平衡二叉树之类的?红黑树的优势在哪里?
- 红黑树的五大特征:
a. 节点要么全为红色,要么为黑色
b. 根节点为黑色
c. 叶子节点为黑色
d. 从根节点到叶子节点不存在两个相邻的红色节点
e. 从任意节点到其每个叶子节点的所有路径包含相同数目的黑色节点 - 根据红黑树的特征可知
a. 红黑树不追求“完全平衡”,它只要求部分地达到平衡要求,降低了对旋转的要求,从而提高了性能。红黑树的算法时间复杂度与平衡查找树相同,但统计性能比平衡二叉树更高
b.
(AVL树的旋转比红黑树的旋转更加难以平衡和调试,需要更高的旋转次数)
HashMap扩容机制,即resize方法?(JDK 1.7 会重新计算每个元素的哈希值,JDK1.8是通过高位运算(e.hash & oldCap)来确定元素是否需要移动,如果运算结果值为0,那么元素扩容后位置不变,结果值为1表示元素在扩容时位置发生了变化,新的下标位置等于原下标位置 + 原数组长度)
HashMap添加元素的步骤(put方法)、计算集合元素个数(size方法)
HashMap为什么是线程不安全的?(同时新增元素、同时扩容导致数据丢失,jdk1.7头部倒序插入出现死循环导致CPU占用100%)
HashMap默认的加载因子是0.75,为什么不设置成1或者0.5(从容量和性能考虑)
HashMap发生哈希冲突,新节点是插入到链表头部还是链表的尾部,头部倒序插入死循环是怎么产生的?(jdk1.7采用头部倒序插入,会导致死循环;jdk1.8使用尾部正序插入)
Hashtable怎么控制key value 不能为null?(当调用put方法时,首先会判断value是否为null,为null的话直接抛出空指针异常;对于key,由于Hashtable计算hash值是int hash = key.hashCode();直接取对象的hashcode,key为null就会报空指针异常;而HashMap计算hash值是return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16),key为null则hash值为0)
ConcurrentHashMap底层采用的结构(分jdk1.7和jdk1.8),jdk1.7和jdk1.8分别采用什么方式实现线程安全?(jdk1.7采用分段锁,也就是为每一个segment加上ReentrantLock锁;jdk1.8使用的是CAS机制加上synchronized锁)
ConcurrentMap中的size方法是如何实现的?多线程操作下,如果一个线程在查size方法,一个线程在执行put方法,底层是如何控制每次计算出来的值是正确的?(https://blog.csdn.net/chenyiminnanjing/article/details/82716180)
HashSet的底层实现?(基于HashMap来实现的,new 一个 HashSet对象底层实际就是new了一个HashMap,并且使用默认的初始容量16和默认的加载因子0.75;当我们往HashSet里面添加一个元素其实就是往HashMap里面put了一个元素,并且是以key存在的,HashMap的value值都是一样的,是一个静态常量PRESENT,源码为:private static final Object PRESENT = new Object(); )
BlockingQueue(阻塞队列)如何实现生产者消费者模型?
线程安全的List有哪些?(Vector、CopyOnWriteArrayList、还可以使用Collections类的synchronizedList方法将线程不安全的List转为线程安全的)
为什么ArrayList查询速度快?(ArrayList底层是基于数组实现,可以根据元素下标进行查询,查询方式为(数组首地址+元素长度*下标,基于这个位置读取相应的字节数就可以了),如果数组存的是对象,怎么根据下标定位元素所在位置?(对象数组每个元素存放的是对象的引用,而引用类型如果开启指针压缩占用4字节,不开启则占用8字节,所以对象数组同样适用上面的公式)
ArrayList的扩容?(ArrayList底层是基于数组实现,所以创建ArrayList会给数组指定一个初始容量,默认值为10,因为必须指明数组的长度才能给数组分配空间;由于数组的特性,ArrayList扩容是创建一个更大的数组,然后将原来的元素拷贝到更大的数组中,扩容的核心方法是Arrays.copyOf方法)
ArrayList和LinkedList的区别,添加一个元素的时间复杂度各是多少,既然ArrayList添加元素效率没有LinkedList高,为什么我们平时用的比较多的还是ArrayList?
一般什么情况下会用ArrayList,什么情况用LinkedList?(如果只是普通的存取元素多用ArrayList,LinkedList一般用作栈、队列)
将一个Map集合变成栈,如何实现?(我的思路是用TreeMap去实现,key存的是要入栈的元素,value存的是可以记录他们入栈的一个先后顺序的,例如时间戳,然后重写Comparator比较器,根据value进行排序,遍历Map时,先进的后面出)
Map集合有迭代器吗?遍历输出Map中所有元素有哪些方法?
三、多线程和Java锁
线程池的三大方法、七大参数、四种拒绝策略(可以顺带谈一下阿里巴巴开发手册对于线程池使用的规范)
创建线程的多种方式
最大线程数如何定义?(从CPU密集型和IO密集型考虑)
线程池的五种状态(Running、Shutdown、Stop、Tidying、Terminated)
线程池的任务执行流程、excute方法和 submit方法的区别?
Synchronized锁和Lock锁的区别
Java线程虚假唤醒(线程本应该处于wait状态却被唤醒了,解决方案是wait方法应该用while循环包裹,不用if)
JMM的三种特性(原子性、可见性、有序性)、主内存和线程工作内存的八种交互动作
volatile如何保证可见性(MESI缓存一致性协议)
volatile如何保证有序性(内存屏障——lock前缀指令)
synchronized和volatile的区别(volatile是一种非锁机制,这种机制可以避免锁机制引起的线程上下文切换和调度问题。因此,volatile的执行成本比synchronized更低;volatile只能保证可见性有序性;synchronized可以保证原子性可见性有序性)
JUC包中的原子类如何保证原子性?(CAS机制和自旋锁)
CAS机制,会引发什么问题,如何解决ABA问题?(CAS会导致ABA问题,解决ABA问题是使用版本号机制)
悲观锁和乐观锁的区别,应用?(java中的Synchronized关键字和lock锁使用的都是悲观锁;CAS机制是乐观锁的一种实现方式)
公平锁和非公平锁(公平锁按照先来先服务,不会出现饥饿;非公平锁会导致饥饿,但是效率更高,默认的锁都是非公平的)
自旋锁和互斥锁,自旋锁的优缺点?(优点:减少上下文切换和用户态内核态的切换带来的开销;缺点:循环等待消耗CPU)
可重入锁和不可重入锁(不可重入锁容易导致死锁发生,大多数锁都是可重入的,例如Synchronized锁和ReentrantLock)
JDK1.6 Synchronized锁升级(偏向锁—轻量级锁—重量级锁)
Synchronized锁的底层实现,锁的是什么,其它线程如何判断该锁已经被占用了?
死锁产生的四个必要条件以及死锁的处理策略
四、Mysql
Myisam和InnoDB存储引擎的区别?(Myisam不支持外键也不支持事务,支持的是表锁,当执行select操作时,自动给涉及的表加表锁,当执行增删改操作,自动给涉及的表加写锁;InnoDB支持外键也支持事务,支持的是行锁,当执行select操作时,不加任何锁,当执行增删改操作,自动给涉及的行加写锁)
间隙锁是什么?行锁升级为表锁的情况?
InnoDB的行锁有哪些?锁住的是行还是索引?(Record Lock、Gap Lock、Next-Key Lock;锁住的是索引,而不是行)
为什么可重复读隔离级别也可以解决幻读?(通过Next-Key Lock可以消除幻读)
并发事务处理带来的四种问题和事务的隔离级别(丢失更新、脏读、不可重复读、幻读;读未提交、读已提交、可重复读、串行化)
如何理解Mysql默认的事务隔离级别可重复读?
事务的ACID属性是如何实现的?(原子性通过回滚日志undo log实现;持久性通过重做日志redo log实现;隔离性通过锁和MVCC实现;而一致性则是通过原子性、隔离性、持久性来实现,只有满足这三个特性,才能实现事务的一致性)
聚簇索引、非聚簇索引、回表查询、覆盖索引;
索引失效的情况?(违反最左前缀法则、范围查询右边的列索引失效、字符串不加单引号、对索引列进行运算、头部模糊匹配、使用不等于!=或者<>)
explain分析执行计划、SQL语句的优化
mysql三大范式(1NF即原子性,2NF即消除部分依赖,3NF即消除传递依赖)
mysql索引的底层实现,为什么用B+树不用B树?(B+树IO次数更少、更适合范围查询、查询效率更加稳定)
哈希表查找速度不是更快吗,为什么不直接使用哈希表来做索引的底层数据结构?(哈希表不支持范围查找)
五、Redis
Redis五种基本数据类型的使用场景
缓存穿透、缓存击穿、缓存雪崩
Redis的过期策略和内存淘汰机制
Redis的zset底层数据结构,为什么用跳跃表而不用红黑树
六、框架相关
Spring AOP的实现原理?(基于动态代理模式,如果目标类实现了接口,那么使用基于接口的动态代理,否则使用基于子类/cglib的动态代理)
Spring AOP 的具体加载步骤?
AOP和OOP的区别,分别适用什么场景?
Spring Bean的作用域,Spring Bean的生命周期(Bean的实例化—初始化Bean—使用Bean—Bean的销毁)
Spring容器创建对象的两种时机,各有什么优缺点?(一是Spring容器启动时创建Bean,二是调用getBean方法时创建)
SpringMVC的执行流程(可以顺带讲一下适配器模式)
Mybatis的一级缓存和二级缓存?
Mybatis中#和$的区别?
Mybatis如何实现批量插入?
Mybatis的xml文件中,sql语句可以使用直接使用大于号小于号吗?应该用什么符号代替?
七、设计模式
代理模式(应用:一是创建多线程的方式之使用Runnable接口应用了静态代理;二是Spring AOP应用了动态代理)
参考文章:https://blog.csdn.net/can_chen/article/details/107827629
适配器模式(应用:一是创建多线程的方式之使用Callable接口;二是SpringMVC中的HandleAdapter)
参考文章:https://blog.csdn.net/can_chen/article/details/106968769
工厂模式(应用:一是Spring IOC;二是Mybatis中的SqlSessionFactory就用到了简单工厂模式)
参考文章:https://blog.csdn.net/can_chen/article/details/105924115
单例模式(一般会需要手撕单例模式的代码,主要谈DCL模式关于指令重排的问题,以及反射可以破坏除枚举以外的几种方式;单例模式的应用有:一是Spring Bean的作用域默认就是使用单例模式;二是Mybatis中的ErrorContext类也使用了单例模式,这个类用于记录线程执行环境的错误信息)
参考文章:https://blog.csdn.net/can_chen/article/details/105049999
装饰器模式(应用:JAVA的IO流就用到了装饰器模式)
参考文章:https://blog.csdn.net/can_chen/article/details/105786680
装饰器模式和代理模式的区别?
参考文章:https://www.cnblogs.com/yanggb/p/10952843.html
策略模式(应用:Arrays类的sort方法就用到了策略模式,Comparator接口就是一个策略接口,将排序方法定义成一个策略,用户可以自定义排序策略,可以是升序也可以是降序)
参考文章:https://blog.csdn.net/can_chen/article/details/106745298
观察者模式与发布订阅模式的区别?(JDK源码已经为我们提供好了一套观察者模式,Observer就是观察者接口,Observable类是被观察者,是一个具体类,提供了一个存放所有观察者角色的集合,并且也提供了添加观察者、移除观察者、通知观察者等方法)
参考文章: https://blog.csdn.net/hf872914334/article/details/88899326
八、网络
TCP三次握手和四次挥手的过程,每次发送的包的内容,客户端和服务端的状态?
TCP三次握手可以携带数据吗?TCP协议运行时阶段?
为什么是三次握手,可以四次握手或者两次握手吗?
为什么握手是三次,而挥手要四次?
TCP四次挥手为什么需要TIME-WAIT阶段等待2MSL,是哪一方有TIME-WAIT阶段?(主动释放释放连接的那端)
TCP的长连接和短连接(http://blog.sina.com.cn/s/blog_6d39b5be0101k6v4.html)
半连接队列和全连接队列,什么是syn flood攻击,如何应对syn flood攻击?(https://www.jianshu.com/p/ff26312e67a9)
在浏览器中输入一个网址回车后发生了什么?(https://www.cnblogs.com/tisikcci/p/5866753.html)
域名解析过程的递归查询和迭代查询(https://blog.csdn.net/weixin_42061048/article/details/80170991)
浏览器输入一个网址之后,按照TP/IP参考模型,从应用层到网络层各使用了哪些协议?
(应用层:HTTP、DNS;传输层:TCP、UDP;网络层:IP、ICMP、ARP)
ICMP协议的两个应用——Ping和Traceroute(https://www.jianshu.com/p/32bc2749a831)
IP地址和MAC地址有什么区别?
http和https的区别 (https://www.php.cn/faq/418162.html)
网站为什么要使用cookie和session;cookie和session有什么区别?
get请求和post请求的区别?
TCP和UDP的区别以及各自的应用场景?
epoll和select的区别?
客户端和服务端通信大致分为四个步骤:①打开一个TCP连接 ②发送一个http报文 ③读取服务端返回的报文 ④关闭连接或者为后续请求重用连接
请求报文由以下元素组成:
- 一个 HTTP 的method,经常是由一个动词像
GET
,POST
或者一个名词像OPTIONS
,HEAD
来定义客户端的动作行为。通常客户端的操作都是获取资源(GET 方法)或者发送HTML form表单(POST 方法),虽然在一些情况下也会有其他操作。 - 要获取的资源的路径,通常是上下文中就很明显的元素资源的 URL,它没有protocol(
http://
),domain(developer.mozilla.org
),或是 TCP 的port (en-US)(HTTP 一般在 80 端口)。 - HTTP 协议版本号。
- 为服务端表达其他信息的可选头部headers。请求头
- 对于一些像 POST 这样的方法,报文的 body 就包含了发送的资源,这与响应报文的 body 类似。请求体
响应报文包含了下面的元素:
- HTTP 协议版本号。
- 一个状态码(status code),来告知对应请求执行成功或失败,以及失败的原因。
- 一个状态信息,这个信息是非权威的状态码描述信息,可以由服务端自行设定。
- HTTP headers,与请求头部类似。
- 可选项,比起请求报文,响应报文中更常见地包含获取的资源 body。
http流水线
九、JVM
- JVM是运行Java字节码的虚拟机。JVM有针对不同操作系统的不同实现,目的是采用相同的字节码,都会给出相同的结果。字节码和不同系统的JVM是实现“一次编译,到处运行”的关键。
- JVM内存模型(程序计数器、虚拟机栈、本地方法栈、堆、方法区)
JDK1.8做了哪些变化?(JDK1.7已经将原本位于永久代的字符串常量池移到堆中了,但是永久代的概念还存在,JDK1.8才彻底废除永久代,进而用元空间代替)
永久代和元空间,JDK1.8为什么要使用元空间代替永久代?
元空间溢出?(元空间不属于Java虚拟机,使用的是本地内存,存放的是类及方法的一些信息,动态加载类或者频繁加载类信息,但是没有及时卸载,会导致元空间溢出)
对象创建的两种方式(指针碰撞、空闲列表)、对象访问定位的两种方式(使用句柄、直接指针)
栈上分配与逃逸分析(JVM层面进行java性能优化的技巧)
判断对象是否存活的两种方式,引用计数法的缺点?(引用计数法、可达性分析法)
关于Object类的finalize()方法(jvm自动执行,无需手动调用,只能执行一次).
java的四种引用(强引用、软引用、弱引用、虚引用)
三种垃圾回收算法,各自的优缺点(标记-清除法、标记-复制法、标记-整理法)
Minor GC 和 Full GC 的区别,触发条件,以及空间分配担保策略?
内存溢出和内存泄露(内存泄露的堆积会导致内存溢出)
JVM参数调优(-Xms、-Xmx、-Xss、-XX:NewRatio、-XX:SurvivorRatio、-XX:+PrintGCDetails、-HeapDumpOnOutOfMemory)
发生OOM如何解决(首先尝试通过JVM参数调优扩大堆内存空间;再者dump出堆内存存储快照,使用JProfile工具进行分析)
垃圾收集器(CMS问的居多,另外,如果谈及发生gc会给用户带来什么不好的体验,可以谈谈Stop the World)
类加载机制的过程,准备阶段做了哪些工作?(准备阶段会给类的静态变量分配内存(方法区)并赋初值,如果类的静态变量被final修饰,那么初始化的值就不是零值,而是声明的值)
类的双亲委派模型定义,双亲委派模型的好处?如何破坏类的双亲委派模型?
十、操作系统
linux的僵尸进程和孤儿进程的区别,如何清理僵尸进程?(kill僵尸进程的父进程)
如何查看僵尸进程信息?如何统计僵尸进程数量?(ps - ef | grep defunct;ps -ef | grep defunct | wc - l)
并发和并行的区别?
进程和线程的区别?
进程通信的方式有哪些?(管道、消息队列、共享内存、信号量、套接字Socket)