https://www.cnblogs.com/danbing/p/5023231.html 堆内存
https://www.cnblogs.com/panxuejun/p/5889418.html 内存模型
https://blog.csdn.net/lxf512666/article/details/52819906 数组
https://blog.csdn.net/qq_21430549/article/details/52225801 散列与散列码
https://blog.csdn.net/abcd1430/article/details/52745155 hashmap冲突的解决方法以及原理分析
一面
- i++是原子的吗?为什么不是原子的?会出现什么情况?
不是。i++操作分为三步,
1.从栈中取出i
2.i自增1
3.将i存到栈
这三步必须
原子操作(atomic operation)是不需要synchronized",所谓原子操作是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束,中间不会有任何 context switch(切换到另一个线程); java中一般事务管理里面用到原子操作。
-
数组的特点?底层如何定位到数组中的元素?数组的内存空间是连续的吗?
数组是相同类型数据的有序集合;
是连续的
-
32位操作系统会为每个进程分配多大的内存空间?为什么能为每个进程分配那么多虚拟内存空间?地址空间是连续的吗?
2^32 = 4G
地址空间是连续的,实际存储空间是不连续的
-
快速排序的时间复杂度是多少?最好情况和最坏情况出现在什么地方?为什么要从后往前排?
O (nlogn)
最好情况:每次枢纽元素在中间 O(nlogn)
最坏情况:每次划分只得到一个比上一次少一个记录的序列 (n^2/2)
如果基数选的是前面的,那么就要从后往前排,通过一次模拟{2,1,4,9},就会发现啦,这样我们无法确保左边的数小于基准值,右边的数大于基准值。 -
O(n)的排序算法
桶排序,比如对于这这样一个数组a [2,8,5,3,2],我们新建一个数组,int[] b;
遍历数组a,
a[0]=2,则b[2]+=1;
a[1]=8,则b[8]+=1;
a[2]=5,则b[5]+=1;
a[3]=3,则b[3]+=1;
a[4]=2,则b[2]+=1;
则最终,b数组内容如下:
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|
0 | 0 | 2 | 1 | 0 | 1 | 0 | 0 | 1 | 0 |
-
各种排序算法的复杂度
-
冒泡排序:每次比较相邻的两个元素,如果顺序不对就交换过来。
-
HashMap的底层实现?链地址法解决冲突?为什么需要转化成红黑树?
HashMap是基于哈希表的Map接口非同步实现,它的主干是一个Entry数组,每个Entry包含一个key value键值对。允许存放null值和null键。
当我们往HashMap里put元素的时候,首先会对key调用hashcode()方法算出hashcode,之后会对hashcode调用hash方法算出h,然后就会对h调用IndexFor函数来确定存储下标。如果没有发生哈希冲突的话,那么它就存了。如果发生了,在jdk1.8之前是插入头部的,在jdk1.8中是插入尾部的
HashMap到底是插入链表头部还是尾部
附: HashMap两个影响性能的参数
HashMap有两个参数会影响其性能,初始容量和加载因子:容量是HashMap在创建时“桶”的数量,而初始容量是哈希表在创建时分配的空间大小。加载因子是哈希表在其容量自动增加时能达到多满的衡量尺度(比如默认为0.75,即桶中数据达到3/4就不能再放数据了)。如果加载因子过大,迭代性能会下降,虽然空间开销减少。如果初始容量小于最大条目数除以加载因子,则会发生 rehash 操作。rehash操作即重建内部数据结构,一般是增加桶数为原来的两倍,rehash过程中会重新计算每个元素在数组中的位置,而这是一个非常消耗性能的操作,所以如果我们已经预知HashMap中元素的个数,那么预设元素的个数能够有效的提高HashMap的性能
————————————————
版权声明:本文为CSDN博主「xi_nuo」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/xi_nuo/article/details/94589827在jdk1.8之后,就把链表改成了红黑树,这样查询效率从O(n) 提高到O(logn)。
- 你编写程序的时候如何进行调试?如何快速定位到一个异常?
结合例子讲讲?前几天那个redis.先确定调用的什么方法,然后设置断点,做debug。找到之后
- TCP和UDP有什么区别?
TCP是面向连接、可靠、效率相比低一点、点对点、系统资源要求较多的
UDP是无连接、尽最大努力、效率较高、支持一对一、一对多、多对一、多对多的、系统资源要求较少的
-
TCP如何实现可靠的数据传输?
可靠的数据传输是保证数据无差错、无丢失、按序和无重复的交付。
-
数据编号和确认
TCP协议是面向字节的,会把应用层交下来的长报文看成一个个字节组成的数据流,并使每个字节对应于一个序号。连接建立的时候,双方都会确认好初始的序号。TCP使用的是累积确认,接收方会对所有按序接收到的数据返回确认号。
-
滑动窗口机制
让发送方的发送速率不要太快,让接收方来得及接受。发送方的发送窗口不能超过接收方给出的接收窗口的数值。
-
超时重传
当TCP发送一段报文时,他同时也会在它的重传队列中存放这个报文段的副本。如果在计时器设置的超时重传时间内收到了确认报文,那么这个副本就会删掉,否则就会重新发送。
-
快速重传
快速重传就是当发送方中途有一个报文丢失了,接收方会对发送方连续发送按序接收到的最后一个字节数据进行重复确认,一旦发送方收到三个连续重复的确认报文,就会重新发送丢失的那个报文。
-
选择确认
允许接收方通知发送方所有正确接受了但是失序的字节块。
-
拥塞控制机制(维持一个拥塞窗口cwnd
每一个发送方都可以根据感知到的网络拥塞程度来限制发送其发送流量的速率。
慢启动(<;cwnd呈指数增长
拥塞避免(>;cwnd呈线性增长
拥塞解决(解决方法是拥塞阈值乘性减即ssthreshold=cwnd/2,cwnd=1,或者ssthreshold=cwnd/2,cwnd=ssthreshold
快速恢复:超时重传——>慢启动 ;快速重传——>拥塞避免阶段
-
-
为什么有了TCP还需要UDP,能够保证传输的可靠性不是更好吗?
但是我们也要速度啊
-
TCP和UDP适用的场景?
TCP:文件传输,重要状态更新
UDP:音频、视频传输、实时通信
-
说一下使用UDP实现可靠数据传输的大体设计思路?
UDP仅仅提供了校验和机制来保障一个报文是否完整,若校验失败,则直接丢弃报文,不做任何处理。
所以我们可以在应用层做一个模仿TCP传输的机制,比如添加seq/ack机制,添加发送和接收缓冲区,添加超时重传机制;目前有一些开源程序如RUDP,RTP,UDT
-
TCP的time_wait状态出现在什么时候?有什么作用?
出现在最后一次挥手的时候。也就是发送端发送最后一个ACK报文完的时候。这个状态会持续2MSL,作用是:1.确保最后一个确认报文有送到服务器端 2.确保此次连接的所有报文都传输完毕。
-
大量TIME_WAIT造成的影响:
在高并发短连接的TCP服务器上,服务器一处理完请求变主动关闭连接,会使大量socke处于TIME_WAIT状态。如果客户端并发量持续很高,此时部分客户端就会显示连接不上。
如何解决?
当出现TCP: time wait bucket table overflow,尽量调大下面参数:
tcp_max_tw_buckets = 256000
调整次参数的同时,要调整TIME_WAIT_2到TIME_WAIT的超时时间,默认是60s,优化到30s:
net.ipv4.tcp_fin_timeout = 30编辑内核文件/etc/sysctl.conf,加入以下内容:
net.ipv4.tcp_syncookies = 1 表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;
net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;
net.ipv4.tcp_tw_recycle = 1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。
net.ipv4.tcp_fin_timeout 修改系默认的 TIMEOUT 时间
然后执行 /sbin/sysctl -p 让参数生效.
/etc/sysctl.conf是一个允许改变正在运行中的Linux系统的接口,它包含一些TCP/IP堆栈和虚拟内存系统的高级选项,修改内核参数永久生效。
简单来说,就是打开系统的TIMEWAIT重用和快速回收。
-
TCP具有超时重传策略?如果一直超时怎么办?如何解决?
设置RTO ? -
线程之间如何进行通信?
1. 共享变量
2. 等待唤醒机制 wait()/notify()
3. Lock/Condition机制 显示的使用Lock对像来充当同步监视器,使用Condition对象来暂停指定线程,唤醒指定线程
4. 管道
+ 创建管道输出流PipedOutputStream pos和管道输入流PipedInputStream pis
+ 将pos和pis匹配,pos.connect(pis);
+ 将pos赋给信息输入线程,pis赋给信息获取线程,就可以实现线程间的通讯了 -
进程之间如何进行通信?
- 管道: 允许具有亲缘关系进程间的通信,允许一个进程和另一个与它有共同祖先的进程之间进行通信。
- 命名管道:具有了名字,允许无亲缘关系进程间通信(mkfifo命令创建)
- 消息队列:存放消息的容器,具有存储权限的进程可以向队列添加消息,被赋予读权限的进程则可以读走队列的消息。克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺陷。消息队列
- 共享内存:多个进程可以访问同一块内存空间,需要使用信号量用来同步对共享存储的访问。
- 内存映射:
- 信号量:一个计数器,用于为多个进程提供对共享数据对象的访问。
- 套接字socket: 用于不同机器之间的进程间通信
-
匿名管道和命名管道的区别是什么?
命名管道可以让不具有亲缘关系的进程互相通信。 -
在网络通信当中,如何确认对方是否在线呢?
1. ping
2. ping不通,使用arp -a,查看是否有该ip地址 -
IO多路复用如何实现的?
服务器端采用单线程通过select/epoll等系统调用获取fd列表,遍历有事件的fd进行accept/recv/send,使其能支持更多的并发连接请求 -
epoll相对于select有什么优点?epoll的垂直和水平触发方式?
epoll相比select的优点有:- 首先它能处理的fd数量没有大小限制,而select有大小限制,只能保存1024位。
- 省去了内核态和用户态之间的拷贝
- epoll底层是红黑树,并且epoll_wait(难以描述
-
跳表的优点是什么?为什么不用红黑树?
跳表在原有的有序链表上面增加了多级索引,通过在每个节点中维持多个指向其他的几点指针,来实现快速查找。- skiplist的复杂度和红黑树一样,而且实现起来更简单。
- 在做范围查找的时候,平衡树比skiplist操作要复杂。skiplist进行范围查找非常简单,只需要在找到小值之后,对第1层链表进行若干步的遍历就可以实现。
- 在并发环境下skiplist有另外一个优势,红黑树在插入和删除的时候可能需要做一些rebalance的操作,这样的操作可能会涉及到整个树 的其他部分,而skiplist的操作显然更加局部性一些,锁需要盯住的节点更少,因此在这样的情况下性能好一些。
总的来说,实现简单,不易出bug,容易维护
跳跃表在 Redis 中使用不是特别广泛,只用在了两个地方。一是实现有序集合键,二是集群节点中用作内部数据结构。
-
平常用MySQL用的哪个存储引擎?Innodb有什么优缺点?
Innodb:Supports transactions, row-level locking, and foreign keys -
如何查看一条SQL指令的执行时间?
show profile show profile的使用 -
Linux基本指令有哪些?如何查看当前CPU的使用情况?(不懂)
-
二叉搜索树:二叉树,每个结点只存储一个关键字,等于则命中,小于走左结点,大于走右结点;
B(B-)树:多路搜索树,每个结点存储M/2到M个关键字,非叶子结点存储指向关键字范围的子结点;
所有关键字在整颗树中出现,且只出现一次,非叶子结点可以命中;
B+树:在B-树基础上,为叶子结点增加链表指针,所有关键字都在叶子结点中出现,非叶子结点作为叶子结点的索引;B+树总是到叶子结点才命中;
B树、B-树、B+树、B*树之间的关系
二面
- JVM运行时的内存布局是怎么样的?
- 什么排序的时间复杂度可能为O(n)?桶排序和计数排序懂吗?
平常一般都如何进行程序调试的?还会打断点?
链表和数组的区别?底层寻址是如何完成的?
TCP和UDP相关,很多问题
用过Socket编程吗?进行Socket编程的具体步骤是怎么样的?
“TCP/IP只是一个协议栈,就像操作系统的运行机制一样,必须要具体实现,同时还要提供对外的操作接口。
这个就像操作系统会提供标准的编程接口,比如win32编程接口一样。
TCP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket编程接口。”
同一个计算机上的应用能使用Socket进行通信吗?
IO多路复用到底在实际应用当中解决了什么问题?给了一个场景
解决过粘包问题吗?怎么拆包解包的?还有其它更多的解决方案吗?
HTTP 301状态码表示什么意思?还有什么其它的状态码?
写过Web编程吗?怎么分派请求的?
进程线程相关,通信如何进行?在代码中实现过吗?怎么用的?
多进程和多线程?平常用哪个更多?用过多进程吗?
UDP最大包长多少?首部的字段和长度?为什么是1500字节呢?
三面(主管面)
Innodb和ms的区别?具体一点
Innodb有什么优点?具体一点
什么是时候用缓存?你有什么解决方案?
你知道索引和主键有什么区别吗?
如果mysql数据库中的数据过多会产生什么问题?你会怎么办?
redis和mysql有什么区别?redis数据只存在内存上吗?
JVM垃圾收集策略是怎么样的?为什么有垃圾收集还会有内存泄漏问题?如何判断一个JVM进程是否发生了内存泄漏?
如何查看远程进程连接本地主机的一个端口号?写Linux命令
介绍一下http协议,写过web应用吗?了解过sql注入吗?会有什么问题?如何防止?
Java里面,既然有了基本类型,为什么还需要包装类型呢?
你说一下递归的优缺点吧,如何优化?如何进行剪枝搜索?
给了一道多进程和多线程的场景题。这个场景下会出现什么问题?为什么会出现这样的问题?你会如何解决呢?
给了一道场景题,我说用动态规划,写了个状态转移方程。
面完主管面一度自闭,以为挂了,没想到3分钟变成HR面试状态,许愿offer
哦对了,如果大家要问项目问题的话,我建议去看声哥写的文章,声哥的项目对我帮助挺大的,感谢声哥!