快手老铁面经+ 很多tcp的总结,面试一天之后就发了意向,太爽了!
刚拿到了铁手意向书了,效率真快,一周全完事,hr面后一天就给意向了。
面试问了好多TCP 的问题都不会,之后复盘详细看了相关资料,写了不少tcp的问题,比较基础的握手挥手就没记下来
一面 1小时10分钟
自我介绍
熟悉的语言
Java
Java 范型怎么实现,为什么要擦除,和C++模版区别是什么
泛型 = “参数化类型”。就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。
编译器会在编译期间擦除泛型语法并相应的做出一些类型转换动作,以 Object 或者extends xxx 的xxx 来替代 擦除是为了兼容老程序,需为原本不支持泛型的 API 平行添加一套泛型 API(主要是容器类型)。
C++ 编译器从函数模板通过具体类型产生不同的函数;编译器会对函数模板进行两次编译:在声明的地方对模板代码本身进行编译,在调用的地方对参数替换后的代码进行编译。 是真正的范型**
刚开始学C++ ,为了面华为这个部门。。
JAVA 怎么实现多态
方法的动态绑定, 通过方法表,方法表有继承自父类 的方法及各自新定义的方法。因此,方法表的偏移量总是固定的。所有继承父类的子类的方法表中,其父类所定义的方法的偏移量也总是一个定值。这样 JVM 在调用实例方法只需要通过Invokevirtual 指令调用方法表中的第几个方法 。如果是实现多个接口,就要遍历搜索方法表,所以接口方法慢于类方法的调用的。
C++ 怎么实现多态 ? 和java 区别是什么?
和Java差不多,虚函数 加 vitrual 关键字,编译器会为每个包含虚函数的类创建一个虚表 ,在这个数组中存放每个虚函数的地址,每个对象有一个指针,指向所属类的虚表,在程序运行时,根据对象的类型去初始化这个指针指向了所属类的虚表。
但是Java 的方法表中包含 Java 类所定义的所有实例方法,C++ 虚表只包含vitrual的方法 。Java 类方法都相当于C++的虚方法,任意 Java 对象都只有一个方法表,而 C++ 在多重继承下可能指向多个方法表
我是Java选手,C++不熟啊
Java ConcurrentHashmap的put 操作,详细说说流程
检查传入的参数, ConcurrentHashmap 不允许null值或key
计算key 的( hash 值 & capacity -1 ), 用来后面定位元素
位置上没有元素存储 -- 没有发生hash冲突 , CAS 换入, 有元素的话,锁住这个元素,开始在这个链表上插入 ,链表的话插入到尾巴,红黑树的话加入红黑树再平衡
链表的话数量 > x 转红黑树
如果状态是正在扩容的话要帮助扩容
数量> capacity * load factor 扩容两倍
CAS 机制,好处,缺点以及怎么解决
对比,一致就替换,不一致就替换失败, 不加锁,超快,不用切换/休眠,ABA问题,如果一开始位置V得到的旧值是A,当进行赋值操作时再次读取发现仍然是A,并不能说明变量没有被其它线程改变过,有可能是其它线程将变量改为了B,后来又改回了A。解决: 追加版本号,每次变量更新就把版本号加1,则A-B-A就变成1A-2B-3A。或者加时间戳。
写一个单例模式(先写懒汉,再写DCL,为什么加volatile)
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Singleton {
private static Singleton instance;
private Singleton (){
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Singleton {
private volatile static Singleton instance;
private Singleton (){
}
public static Singleton getInstance() {
if (instance== null) {
synchronized (Singleton.class) {
if (instance== null) {
instance= new Singleton();
}
}
}
return singleton;
}
}
**instance= new Singleton(); 有3部:
给singleton对象分配内存空间
调用Singleton类的构造函数等,初始化singleton对象
将singleton对象指向分配的内存空间,这步一旦执行了,那singleton对象就不等于null了
JVM会为了优化,会做指令重排序的操作,正常情况下,singleton = new Singleton(); 的步骤是按照1->2->3这种步骤进行的,但是一旦JVM做了指令重排序,那么顺序很可能编程1->3->2,如果是这种顺序,可以发现,在3步骤执行完singleton对象就不等于null,但是它其实还没做步骤二的初始化工作,但是另一个线程进来时发现,singleton不等于null了,就这样把半成品的实例返回去,调用是会报错的。
synchronized 和 reentrantlock 有啥区别?哪一个效率高?
等待可中断 使用synchronized。如果Thread1不释放,Thread2将一直等待,不能被中断。synchronized也可以说是Java提供的原子性内置锁机制。一个线程引用锁的时候,别的线程阻塞等待。使用ReentrantLock。如果Thread1不释放,Thread2等待了很长时间以后,可以中断等待,转而去做别的事情。
公平锁 synchronized的锁是非公平锁,ReentrantLock默认情况下也是非公平锁,但可以通过带布尔值的构造函数要求使用公平锁。
锁绑定多个条件,ReentrantLock可以同时绑定多个Condition对象,只需多次调用newCondition方法即可, synchronized中,锁对象的wait()和notify()或notifyAll()方法可以实现一个隐含的条件。但如果多于一个的条件关联的时候,就不得不额外添加一个锁。
子网掩码是什么
子网掩码是一种用来指明一个IP地址所标示的主机处于哪个子网中的标志,子网掩码只有一个作用,就是将某个IP地址划分成网络地址和主机地址两部分。
ip首部有什么字段
首都长度 ,总长度,
分片相关的
标识符:唯一标识主机发送的每一份数据报。*
标志:分为3个字段,依次为保留位、不分片位和更多片位。
生存时间:TTL
协议:TCP/UDP/ICMP
首部校验和:校验接收到的IP数据报是否有差错。
源 IP地址
目的 IP地址
选项
糊涂窗口是什么,怎么解决
https://blog.csdn.net/hzhsan/article/details/46429749
当发送端应用进程产生数据很慢、或接收端应用进程处理接收缓冲区数据很慢, 就会使应用进程间传送的报文段很小,特别是有效载荷很小。极端情况下,有效载荷可能只有1个字节;而传输开销有40字节(20字节的IP头+20字节的TCP头) 这种现象就叫糊涂窗口综合症。
Nagle算法与 CORK算法
Nagle算法和CORK算法非常类似,但是它们的着眼点不一样,Nagle算法主要避免网络因为太多的小包(协议头的比例非常之大)而拥塞,而CORK算法则是为了提高网络的利用率,使得总体上协议头占用的比例尽可能的小。如此看来这二者在避免发送小包上是一致的,在用户控制的层面上,Nagle算法完全不受用户socket的控制,你只能简单的设置TCP_NODELAY而禁用它,CORK算法同样也是通过设置或者清除TCP_CORK使能或者禁用之,然而Nagle算法关心的是网络拥塞问题,只要所有的ACK回来则发包,而CORK算法却可以关心内容,在前后数据包发送间隔很短的前提下(很重要,否则内核会帮你将分散的包发出),即使你是分散发送多个小数据包,你也可以通过使能CORK算法将这些内容拼接在一个包内,如果此时用Nagle算法的话,则可能做不到这一点。**
简单介绍tcp的特点,怎么可靠
可靠,基于连接,各种控制
TCP协议保证数据传输可靠性的方式主要有:
校验和
序列号
确认应答
超时重传
连接管理
流量控制
拥塞控制
DNS 具体流程? 递归和 迭代
1)递归查询
递归查询是一种DNS 服务器的查询模式,在该模式下DNS 服务器接收到客户机请求,必须使用一个准确的查询结果回复客户机。如果DNS 服务器本地没有存储查询DNS 信息,那么该服务器会询问其他服务器,并将返回的查询结果提交给客户机。
2)迭代查询
DNS 服务器另外一种查询方式为迭代查询,DNS 服务器会向客户机提供其他能够解析查询请求的DNS 服务器地址,当客户机发送查询请求时,DNS 服务器并不直接回复查询结果,而是告诉客户机另一台DNS 服务器地址,客户机再向这台DNS 服务器提交请求,依次循环直到返回查询的结果为止。
页面置换算法
最佳置换算法(OPT)
先进先出置换算法(FIFO)
最近最久未使用(LRU)**算法
Clock置换算法(LRU算法的近似实现)
最少使用(LFU)置换算法
进程调度算法有什么,讲讲CFS
先来先服务调度算法
短作业(进程)优先调度算法
时间片轮转法
CFS:vruntime值较小就说明它以前占用cpu的时间较短,受到了“不公平”对待,因此下一个运行进程就是它。这样既能公平选择进程,又能保证高优先级进程获得较多的运行时间。这就是CFS的主要思想了。
实现加权随机算法,int rand(double [] a ), 比如输入a=[2,6,2] ,调用多次 rand(a) ,返回的结果为 1或 2 或 3 , 出现的概率分别为20%,60%,20%
问了好多次才明白题目的意思,最简单的方法是初始化一个数组 b = [ 1,1,2,2,2,2,2,2,3,3 ], 直接取b [ rand(b.length)] : 时间复杂度O(1) ,但空间复杂度很爆炸,比如输入a=[1/3,1000,0.00002] 这就没法整。
没有什么好的思路,用二分把空间复杂度变为O(N),时间复杂的(log N)
面试官说回去看看别名法 -- 简直大开眼界,太神奇
面试官夸了下挺好,基础可以,过了,给打个好评分,等会马上二面。