目录
选择题
1.
访问服务器需要域名解析,就涉及到了与域名服务器之间的网络通信(DNS,UDP,IP),也就会设计到相邻设备之间的数据传输(ETH, ARP),所以会先获取相邻设备的 MAC 地址,使用的是 ARP 协议,获取到相邻设备的通信的信息之后,然后再进行域名解析,域名解析成功之后,会搭建 HTTP 客户端访问服务器(HTTP, TCP, IP, ETH)。
2.
用 IP 地址可以访问网站(有网),而使用域名就无法访问网站,说明域名解析失败,就无法获取到域名对应的服务器 IP 地址。
DNS 协议使用的是 53 号端口。
3.
A 类 IP 地址:0.0.0.0 ~ 127.255.255.255 网络号有 1 个字节,主机号有 3 个字节。
B 类 IP 地址:128.0.0.0 ~ 191.255.255.255 网络号有 2 个字节,主机号有 2 个字节。
C 类 IP 地址:192.0.0.0 ~ 223.255.255.255 网络号有 3 个字节,主机号有 1 个字节。
D 类 IP 地址:224.0.0.0 ~ 239.255.255.255
E 类 IP 地址:240.0.0.0 ~ 247.255.255.255
D 类 IP 地址和 E 类 IP 地址比较特殊,做题的时候一般不用考虑 D 类 和 E 类。
4.
TCP 如何实现可靠传输:
可靠传输的基础是确认应答是超时重传保证数据能够到达对端,通过序号和确认序号保证有序传输交付,通过校验和保证发送的数据和接收的数据内容一致。
流量控制:TCP 滑动窗口机制,是避免发送方发送数据过多而导致的丢包。
5.
6.
NAT 地址转换,用于组建私网,让私网中的主机使用私网地址,而向外通信是进行地址转换为对外地址,节省公网地址的使用,因为使用的是对外的地址进行通信,因此对于外部来说,私网内部是不可见的。
7.
/20 表示网络号是前 20 位,所以子网掩码是:11111111.11111111.11110000.0000,255.255.240.0
8.
HTTPS 使用的是 SSL 加密。
SSL:安全套接字协议,TSL 与 SSL 在传输层与应用层之间对网络连接进行加密。
IPsec:互联网安全协议,工作在网络层,适用于保护 TCP/UDP(SSL 无法加密 UDP)
PGP:优良保密协议,是一套用于消息加密,验证的应用程序。
SET:被称之为安全电子交易协议。
9.
A 类 IP 地址:0.0.0.0 ~ 127.255.255.255 网络号有 1 个字节,主机号有 3 个字节。
B 类 IP 地址:128.0.0.0 ~ 191.255.255.255 网络号有 2 个字节,主机号有 2 个字节。
C 类 IP 地址:192.0.0.0 ~ 223.255.255.255 网络号有 3 个字节,主机号有 1 个字节。
154.27.0.0 是 B 类 IP 地址,则说明主机号有 16 位。
一共有 2^16 = 65536 台主机,除去全 0(网络号) 和全 1(广播号) 还剩 65534 台主机。
10.
TCP 建立连接需要三次握手,关闭连接需要四次挥手。
服务端会调用 listen() 进入监听状态,才会开始处理客户端请求,客户端可以调用 bind() 来绑定地址。(但是一般不建议,因为可能会产生端口冲突)
短连接:一次请求,建立一次连接,请求完毕后,会断开连接。
长连接:建立连接之后,如果有请求,那么请求会一直使用这个连接。缺点就是会长时间的维护连接。
编程题
1. 简单错误记录
如图,题目要求按照出现次数的大小来输出 错误记录文件名 + 行号 + 出现次数。
如果文件名长度大于 16 个字符,就需要输出最后 16 个字符。
只有文件名整体 + 行号相同时,两条错误记录才是同一条错误记录。
根据上述信息,我们可以使用 LinkedHashMap 来存放错误记录以及对应的出现次数。
然后再重写比较器,调用 Collections.sort() 方法来排序一下 map 中的 Map.Entry<String,Integer> 节点,最后如果答案集合的元素大于 8,那就输出前 8 个元素,否则就输出集合中的所有元素。
如果文件名长度大于 16,那就截取最后 16 个字符输出,如果不是就直接输出即可。
代码实现:
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 使用 LinkedHashMap 是因为它是有序的
Map<String, Integer> map = new LinkedHashMap<>();
while (in.hasNext()) {
// 文件路径
String filePath = in.next();
// 行号
String num = in.next();
// 文件名
String file = filePath.substring(filePath.lastIndexOf("\\") + 1);
// 文件名 + 行号
file += " " + num;
// 预处理,将所有错误记录的出现次数放入 map 中
// 以 文件名 + 行号 为 key,出现次数为 value
// 累加
int value = map.getOrDefault(file, 0);
map.put(file, value + 1);
}
// 排序后的 ans 就是目标集合,如果集合个数大于 8,那就只输出前 8 个
List<Map.Entry<String, Integer>> ans = new LinkedList<>(map.entrySet());
// 自己实现一个比较器,按照出现次数来排序
Collections.sort(ans, new Comparator<Map.Entry<String, Integer>>() {
@Override
public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
return o2.getValue().compareTo(o1.getValue());
}
});
// 最后输出 ans 的前 8 个元素,如果不够 8 个,那就全部输出即可
for (int i = 0; i < Math.min(8, ans.size()); i++) {
Map.Entry<String, Integer> entry = ans.get(i);
String[] arr = entry.getKey().split(" ");
// arr[0] 是文件名,arr[1] 是行号
if (arr[0].length() > 16) {
// 如果文件名长度大于 16,就需要截取最后 16 位
arr[0] = arr[0].substring(arr[0].length() - 16);
}
System.out.println(arr[0] + " " + arr[1] + " " + entry.getValue());
}
}
}