小米面经
总结:一面问了比较久项目,一个算法题,几道基础知识题;二面都是基础知识题。如果能对基础知识题都给出比较深入的讲解,会给面试官留下比较好的印象。
计算机网络:
1、iso七层协议都干了什么
速记:物数网传会表应
物理层:用物理设备例如网线光纤等传输透明的比特流,工作在物理层的设备有中继器(放大信号等)和集线器(将网线集在一起,多端口的中继器)
数据链路层:将比特封装成帧,在以太网上传输,可实现差错控制,工作在此层的设备有网桥(连接不同网络的桥梁)和交换机(根据mac地址交换信息到不同的端口)
网络层:实现主机之间的通信,传输ip数据包,工作在此层的设备有路由器(根据IP寻址路由转发数据包)
传输层:实现端到端的通信传输
会话层:建立不同机器之间的会话连接管理
表示层:对数据进行加解密、编码解码、压缩解压缩等,让数据在不同的机器以不同的方式表示
应用层:各种应用程序,网关在应用层,可连接不同协议的子网
2、大于MTU大小的报文分片后怎么组装
MTU是最大传输单元,由物理层的物理特性决定了以太网上数据帧的MTU为1500B,大多数路由器的MTU都为1500B。长度超过MTU大小的IP报文需分片,每个分片中都会带上报头,记录片偏移,组装时需把头去掉,按片偏移顺序组装。但IP报文组装出错,TCP能保证可靠性,有超时重传机制,出错的报文段会重传。而UDP则不保证可靠传输,若组装出错则该包会被丢弃,所以建议UDP包大小最好不要超过MTU。若要IP包不超过MTU大小,则:
TCP报文数据部分大小: 1500-20(IP报头)-20(TCP报头) = 1460 B
UDP报文数据部分大小:1500-20(IP报头)-8(UDP报头)= 1472 B
而鉴于因特网上标准MTU值为576B,所以在internet上进行UDP编程时,最好将UDP的数据长度控制在576-20-8=548字节以内。
理论上,IP数据报的最大长度是64K,这是由IP首部16bit总长度字段所限制的,所以我们在用Socket编程时,只要求UDP包大小小于64K,TCP没有限制。
3、tcp在java中用哪个类实现
java.net.Socket
4、http在java中用哪个类实现
//使用java.net.HttpURLConnection
URL url = new URL("http://www.baidu.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();//访问网址
connection.setConnectTimeout(1000);//设置超时时间
//设置请求方式
connection.setRequestMethod("GET");
//连接
connection.connect();
//得到响应码
int responseCode = connection.getResponseCode();
if(responseCode == HttpURLConnection.HTTP_OK){
System.out.println("连接成功");
}
//或者org.apache.http.client
// 创建HttpClient对象
HttpClient client = HttpClients.createDefault();
// 创建GET请求(在构造器中传入URL字符串即可)
HttpGet get = new HttpGet("http://www.baidu.com");
// 调用HttpClient对象的execute方法获得响应
HttpResponse response = client.execute(get);
// 调用HttpResponse对象的getEntity方法得到响应实体
HttpEntity httpEntity = response.getEntity();
// 使用EntityUtils工具类得到响应的字符串表示
String result = EntityUtils.toString(httpEntity,"utf-8");
System.out.println(result);
5、http协议的原理、https的原理,http1和http1.1、http2的区别。
http协议(超文本传输协议)是应用层协议,可在不同的应用间传输数据,使用TCP协议建立连接,若是http1则建立一次tcp连接只能发起一次http请求,http1.1和http2默认为长连接,即建立一次tcp连接可发起多次请求,即httpRequest的请求头中的connection:keep-alive,若想改成短连接则connection:close。http2常用于https协议中,可同时发送和接受多个http请求,使用multiplexing方式。
https是在http上增加了ssl协议,可实现安全的加密传输,https使用的是混合加密方式,用对称加密来处理要传输的数据,但交换对称加密的密钥时密钥可能会泄漏,因此用非对称加密方式加密传输对称密钥,增加了安全性,但非对称加密的过程比较慢,所以不能直接使用非对称加密来传输数据。
6、讲讲你了解的tcp和udp
tcp是面向字节流的可靠的,有报文排序、超时重传、流量控制、拥塞控制机制,报文长度不限,但发送速度慢。
流量控制使用滑动窗口协议实现,包括1比特滑动窗口协议、后退n帧协议、选择重传协议。
拥塞控制包括这几个阶段:慢启动,拥塞避免,快恢复,快重传。
7、一个url从输入浏览器到展现页面发生了什么
(1)DNS域名解析得到服务器IP
(2)发送http或https请求,通过tcp建立连接,ssl连接
(3)后端服务器接收http request,dispatcherSeverlet调用handlerMapping,根据这个请求的url去查找处理这个请求的controller,controller调用对应的service逻辑,返回一个modelAndView,视图解析器解析这个modelAndView并返回一个view,通过引擎模板进行视图渲染,然后得到的视图对象通过http response返回前端。或者只返回model数据,由前端来生成视图。
(4) 浏览器接收到http response后在前端展现页面。
java基础:
1、Collection的实现类介绍下?
2、介绍下HashMap、ConcurrentHashMap,HashMap扩容时为啥不安全?concurrentHashMap1.7里面用什么方法加锁?1.8呢?
HashMap的结构:数组加链表
数组初始大小:16,之后扩容也都是二倍扩,保证数组长度为2^n,这样取模运算时就可以使用这个公式:X % 2n = X & (2n - 1)了。
计算索引的方式: 1.7多次hash扰动,1.8将hash的高16位与低16位异或得到的哈希再通过hash&(n-1)计算索引。
put:
①.判断键值对数组table[i]是否为空或为null,否则执行resize()进行扩容;
②.根据键值key计算hash值得到插入的数组索引i,如果table[i]==null,直接新建节点添加,直接插入,并判断键值对个数是否超过阈值,如果超过则扩容。
③.如果table[i]不为空,判断table[i]的首个元素是否和key一样,如果相同直接覆盖value,这里的相同指的是hashCode以及equals;
④.如果不相同则判断table[i] 是否为treeNode,即table[i] 是否是红黑树,如果是红黑树,则直接在树中插入键值对;
⑤.如果不是红黑树,则遍历table[i],判断链表长度是否大于8,大于8的话把链表转换为红黑树,在红黑树中执行插入操作,否则进行链表的插入操作;遍历过程中若发现key已经存在直接覆盖value即可;
⑥.插入成功后,判断实际存在的键值对数量size是否超多了阈值threshold,如果超过,进行扩容。
get:
1)根据 key 计算 hash 值。
2)找到相应的数组下标:hash & (length - 1)。
3)遍历该数组位置处的链表,直到找到相等(