Java 面试自用

一、HashMap:
1、谈一下HashMap的特性:
a、HashMap存储键值对实现快速存取,允许为null。key值不可重复,若key值重复则覆盖。
b、非同步,线程不安全。
c、底层是hash表,不保证有序。

2、谈一下HashMap的底层原理是什么?
基于hashing的原理,jdk8采用数组+链表+红黑树的数据结构。通过put和get存储和获取对象。当我们给put()传递key和value时,先对key做一个hashCode()的计算来得到他在bucket数组中的位置来存储Entry对象。当获取对象时,通过get()获取到bucket的位置,再通过对象equals()方法找到正确的键值对,然后再返回值对象。

3、put是如何实现的?
a、计算关于key的hashcode();
b、如果散列表为空时,调用resize()初始化散列表。
c、如果元素没有发生碰撞,直接添加元素到散列表中。
d、如果发生碰撞(hashcode值相同),进行三种判断
若key地址相同或者equals后内容相同,则替换旧值
如果是红黑树结构,就调用树的插入方法
链表结构:循环遍历知道链表中的某个节点为空,尾插法进行插入,插入之后判断链表个数是否达道红黑树的阈值8;也可以遍历到与插入元素的hash值和内容相同,进行覆盖。
e、如果容量大于阀值,则resize进行扩容。

4、hashmap的扩容:
扩容需要重新分配一个新数组,新数组是老数组的2倍长,然后遍历整个老结构,把所有的元素挨个重新分配到新结构中去。

二、树结构
平衡二叉树
在二叉树中,如果插入的节点接近有序,那么二叉树就会退化为链表大大降低了查找效率,为了使二叉树无论什么情况下最大限度的接近满二叉树,从而保证它的查找效率,因此引入平衡二叉树。
1、规则:
非叶子节点只能允许最多两个子节点的存在。
每一个非叶子节点数据分布规则为左边的子节点小于当前节点的值,右边的节点值大于当前节点的值。
2、特点:
(1)非叶子节点最多拥有两个子节点;
(2)非叶子节点值大于左边子节点、小于右边子节点;
(3)树的左右两边的层级数相差不会大于1;(通过旋转)
(4)没有值相等重复的节点;

红黑树:(Treemap)
红黑树是一种含有红黑结点并能自平衡的二叉查找树。
1、性质:
(1)每个节点要么是黑色,要么是红色。
(2)根节点是黑色。
(3)每个叶子节点(NIL)是黑色。
(4)每个红色节点的两个子节点一定都是黑色。
(5)任意一节点到每个叶子节点的路径都包含相同数量的黑节点。
插入一个节点,先查找,再插入,插入后变红色。

B树
1、概念:
B树和平衡二叉树稍有不同的是B树属于多叉树又名平衡多路查找树(查找路径不只两个),数据库索引技术里大量使用B树和B+树的数据结构。
2、规则:
(1)所有节点关键字是按递增次序排列,并遵循左小右大原则;
(2)子节点数:非叶节点的子节点数>1,且<=M ,且M>=2,空树除外(注:M阶代表一个树节点最多有多少个查找路径,M=M路,当M=2则是2叉树,M=3则是3叉);
(3)关键字数:枝节点的关键字数量大于等于ceil(m/2)-1个且小于等于M-1个(注:ceil()是个朝正无穷方向取整的函数 如ceil(1.1)结果为2);
(4)所有叶子节点均在同一层、叶子节点除了包含了关键字和关键字记录的指针外也有指向其子节点的指针只不过其指针地址都为null;

3、查询、插入(>M-就要进行合并)、删除(小于ceil(M/2)就要进行合并)
4、特点:把树的节点关键字增多后树的层级比原来的二叉树少了,减少数据查找的次数和复杂度;

B+树
1、规则:
(1)B+树非叶子节点不保存关键字记录的指针,只进行数据索引,这样使得B+树每个非叶子节点所能保存的关键字大大增加;
(2)B+树叶子节点保存了父节点的所有关键字记录的指针,所有数据地址必须要到叶子节点才能获取到。所以每次数据查询的次数都一样;(稳定)
(3)B+树叶子节点的关键字从小到大有序排列,左边结尾数据都会保存右边节点开始数据的指针。
(4)非叶子节点的子节点数=关键字数

三、线程和进程
1、区别:
(1)进程是资源分配的最小单位,线程是程序执行的最小单位。
(2)进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数据段,这种操作非常昂贵。线程是共享进程中的数据的,使用相同的地址空间,因此CPU切换一个线程的花费比进程要小很多,同时创建一个线程的开销也比进程小很多。
(3)线程之间的通信方式更方便,同一进程下的线程共享全局遍历,静态遍变量等数据,二进程之间的通信需要以通信的方式(IPC)进行。
(4)多进程的程序更健壮,在多线程程序中只要一个线程死掉了,整个进程也死掉了,而一个进程死掉并不会对另外一个进程造成影响,应为进程有自己独立的地址空间。

四、栈、堆、方法区
栈的特点:
1、栈描述的是方法执行的内存模型。每个方法被调用都会创建一个栈帧(存储局部变量、操作数、方法出口等)。
2、JVM为每个线程创建一个栈,用于存放该线程执行方法的信息(实际参数、局部变量)。
3、栈属于线程私有,不能实现线程间的共享。
4、栈的存储特性是:先进后出,后进先出。
5、栈是由系统自动分配,速度快,栈是一个连续的内存空间。
堆的特点:
1、堆用于存储创建好的对象和数组。
2、JVM只有一个堆,被所有线程共享。
3、堆是一个不连续的内存空间,分配灵活,速度慢。
方法区(静态区)特点:
1、JVM只有一个方法区,被所有线程共享。
2、方法区实际也是堆,只是用于存储类、常量相关的信息。(类相关信息)
3、用来存放程序中永远不变或唯一的内容。(类信息、静态变量、字符串常量等)

五、java垃圾回收机制
1、发现无用对象
a、引用计数法
堆中每个对象都有一个引用计数,被引用一次,计数+1,被 引用变量值变为null,则计数减1,直到计数为0,则表示变成无用对象。优点是算法简单,缺点是“循环引用的无用对象”无法被识别。
b、引用可达法(根搜素算法)
把引用关系看作一张图,从一个节点GC ROOT开始,寻找对应的引用节点,找到这个节点以后,接续寻找这个节点的引用节点,当所有的引用节点寻找完毕之后,剩余的结点被视为无用节点。
2、回收无用对象占用的内存空间
3、分代垃圾回收机制
年轻代、年老代、持久代

六、java线程池
1、什么是线程池:
多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力。
假设一个服务器完成一项任务所需时间为:T1 创建线程时间,T2 在线程中执行任务的时间,T3 销毁线程时间。
如果:T1 + T3 远大于 T2,则可以采用线程池,以提高服务器性能。

七、死锁及解决方法
死锁:若干进程共享同一资源,推荐顺序不当,从而构成无限循环等待的局面,叫做死锁。死锁回浪费大量的系统资源,甚至导致整个系统崩溃,后果严重。
死锁的避免:
a、安全序列:进程按照某一种次序分配资源,并能依次的完成运行。
b、银行家算法:银行家算法是从当前状态出发,逐个按安全序列检查各客户谁能完成其工作,然后假定其完成工作且归还全部贷款,再进而检查下一个能完成工作的客户,…。如果所有客户都能完成工作,则找到一个安全序列,银行家才是安全的。
缺点:要求客户数保持固定不变,响应速度慢,增加了系统开销。

八、进程通信的七种方式:
管道、匿名管道(pipe):半双工、数据只能向一个方向流动,需要双方通信时,需要建立起两个管道,只能用于父子进程或则兄弟进程之间。
有名管道(fifo):有名管道,只要可以访问该路径,就能够彼此通过有名管道相互通信,先进先出
,没有文件定位操作。
信号(signal):信号可以在任何时候发给某一进程,而无需知道该进程的状态。如果该进程当前并未处于执行状态,则该信号就有内核保存起来,直到该进程回复执行并传递给它为止。
消息队列:消息队列是存放在内核中的消息链表,每个消息队列由消息队列标识符表示。不同的是消息队列存放在内核中,只有在内核重启(即,操作系统重启)或者显示地删除一个消息队列时,该消息队列才会被真正的删除。
共享内存:使得多个进程可以可以直接读写同一块内存空间,是最快的可用IPC形式。
信号量:信号量是一个计数器,用于多进程对共享数据的访问,信号量的意图在于进程间同步。
(同步和互斥:
互斥:是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。
同步:是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。

套接字:套接字是一种通信机制,凭借这种机制,完成客户/服务器形式的通信。

九、HTTP与HTTPS
HTTP(HyperText Transfer Protocol:超文本传输协议)应用层协议。 简单来说就是一种发布和接收 HTML 页面的方法,被用于在 Web 浏览器和网站服务器之间传递信息。
HTTPS(Hypertext Transfer Protocol Secure:超文本传输安全协议)是一种透过计算机网络进行安全通信的传输协议。HTTPS 经由 HTTP 进行通信,但利用 SSL/TLS 来加密数据包。

HTTPS工作流程:
1、TCP/IP三次握手。
2、客户端验证服务器数字证书。
3、协商对称加密算法的密钥、hash 算法的密钥。
4、SSL安全加密隧道协商完成。
5、网络以加密的方法传输,用协商的对称加密算法和密钥加密,保证数据加密性;用协商的Hash算法进行数据完整性保护,保证数据不被篡改。

HTTP与HTTPS区别:
1、HTTP明文传输,数据都是未加密的,安全性较差。HTTPS数据传输过程是加密的,安全性较好。
2、使用HTTPS协议需要到CA(数字证书认证机构)申请证书,需要一定的费用。
3、HTTP页面响应速度比HTTPS快。
4、连接方式不同,端口不同: http:80端口 https:443端口。
4、HTTPS更耗费服务器资源。

十、用户态和内核态
定义:
为了保护操作系统及其数据结构,处理机的运行状态分为两种模式。
操作系统运行与核心态(内核态),具有较高的特权,能执行一切命令,访问所有寄存器和存储区。
用户程序运行于用户态,具有较低的特权,只能执行规定的命令,访问指定的寄存器和存储区。

指令的划分:
特权指令:只能由操作系统使用,用户程序不能使用的指令(启动I/O、内存清零、修改程序状态字、设置时钟、允许/禁止终端、停机等)
非特权指令:用户程序可以使用的指令(控制转移、算数运算、取数指令、访管指令(使用户程序从用户态陷入内核态))

CPU状态之间的转换:
用户态->内核态:唯一途径是通过中断、异常、陷入机制(访管指令)
内核态->用户态:设置程序的状态字PSW

访管指令:是可以在用户态下执行的指令,当源程序有需要操作系统服务要求时,编译程序就会在有源程序转换成目标程序的目标过程中,安排一条“访管指令”并设置一些参数。当目标程序执行时,CPU读取到访管指令就产生了一个中断事件,中断装置就会把中CPU转换为内核态,并让操作系统处理该中断事件。操作系统分析访管指 令中的参数,然后让相应的“系统调用”子程序为用户服务。系统调用功能完成后,操作系统把中央处理器的管态改为目态, 并返回到用户程序)

三种情况会使用户态到内核态的切换:
1、系统调用
2、异常
3、外围设备的中断

内核态与用户态的区别:
1、内核态与用户态是操作系统的两种运行级别。(3级特权)
2、当程序运行在0级特权时,就可以称之为运行在内核态。
3、运行在用户态下的程序不能直接访问操作系统内核数据结构和程序。
4、
处于用户态执行时,进程所能访问的内存空间和对象受到限制,其所占有的处理机是可被抢占的 ;
而处于核心态执行中的进程,则能访问所有的内存空间和对象,且所占有的处理机是不允许被抢占的。

你可能感兴趣的:(Java 面试自用)