目录
选择题
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
编程题
1. 求和
选择题
1.
synflood 是 syn 泛洪攻击。有一个恶意主机,伪造大量的 IP 地址,然后给服务器发送 SYN 请求,但是不进行第三次握手的回复,这样就会消耗服务器大量资源,使服务器连接等待队列爆满,无法处理合理的客户端请求。
服务器会为每个客户端的连接请求都创建一个套接字用于与其通信,服务端回复 ACK + SYN 后,等待最后最后一次 ACK,如果一直等不到而超时了,则回复一个 RST 报文给客户端(表示如果还想通信就重新给我(服务器)发送请求,我要释放这个连接了)
UDP 不需要建立连接,根本就没有 SYN 请求,也就不存在 SYN 泛洪攻击。
2.
B 机器未监听任何端口说明 B 什么端口都没打开,无服务。
ACK 报文是对于对方的某个请求进行的接收确认报文。
FIN 是关闭连接时,向对方发送的断开连接请求报文。
RST 用于重置因为某种原因导致的错误连接,以及拒绝非法的数据和请求。
3.
A 类地址:0.0.0.0 ~ 127.255.255.255 主机号是后 24 位
B 类地址:128.0.0.0 ~ 191.255.255.255 主机号是后 16 位
C 类地址:192.0.0.0 ~ 223.255.255.255 主机号是后 8 位
A:256 超出限制了,最大是 255。
B:197.3.11.0 是 C 类 IP 地址,主机号是后八位,全是 0 是网络号,不能使用。
C:IP 地址得满足有 4 个字节
4.
10.11.12.01011011 ,/28 说明前 28 个比特位是网络号,则主机号是 4 位。
同一个子网的网络号相同(后 4 位为 0),那就是 10.11.12.80,一个子网可以分配 2^4 个主机,范围就是 10.11.12.80 ~ 10.11.12.95
除去全 0 跟全 1,可用的 ip 地址范围就是 10.11.12.81 ~ 10.11.12.94
5.
数据传输时,从低地址向高地址开始传输数据。
x86 平台意味着当前主机的字节序是一个小端字节序(低地址存储低位)。
而正确的网络传输字节序是大端字节序(与小端字节序相反)。
6.
根据子网掩码 255.255.254.0 可得知主机号是 32 - 23 = 9 位,则有 2 ^ 9 = 512 个地址,除去全 0 和全 1 就是 510 个地址,但是题目说网关占据了一个地址,所以最后一个子网能配分 509 个地址。
7.
255.224.0.0:11111111.11100000.00000000.00000000
255.255.240.0:11111111.11111111.11110000.00000000
255.255.255.248:11111111.11111111.11111111.11111000
255.255.255.250:11111111.11111111.11111111.11111010
如上,全部化为二进制之后,能发现最后一个子网掩码的 1 不连续,有中断的,所以最后一个不是子网掩码。
8.
ping 是用于网络状况探测的。
使用了 ping,说明一定使用了 ICMP 协议,ICMP 是网络层协议(隐含了一个东西就是不用端口)。
要 ping 牛客网,首先要域名解析(DNS 请求用的是 UDP 协议)来得到牛客网服务器的 IP 地址。
ARP 协议就是用来获取相邻设备的 MAC 地址。
9.
从浏览器打开链接的步骤:
域名解析 -> 搭建 TCP 客户端连接服务器 -> 组织 HTTP 请求,通过搭建的客户端发送请求给服务器
HTTP 协议是应用层协议(在传输层用的是 TCP 协议)。
SMTP 是邮件传输协议。
10.
如题,它说一个子公司在一个网段中,所以有 6 个子公司,那至少网络号得有 6 位,而一个子网(子公司)至少有 26 个主机号(计算机),2^5 = 32 > 26,所以只需要 5 位主机号即可,所以 32 - 5 = 27 ,所以有 27 位网络号,则最后子网掩码就是 255.255.255.1110 0000 ,也就是 255.255.255.224 。
C 类 IP 地址最多有一个字节来存放主机号。最多有 256 个主机
A:一个子网有 256 - 192 = 64,那最多只能划分 4 个子网,不够 6 个子网。
B:一个子网有 256 - 128 = 128,那最多只能划分 2 个子网,不够 6 个子网。
C:一个子网有 256 - 0 = 256,那最多只能划分 1 个子网,不够 6 个子网。
编程题
1. 求和
思路:可以用递归来做,用递归来帮查找和为 m 的集合。如果当前集合的和大于目标和(就不用继续往后累加数字了),则直接返回,如果等于的话,那就直接输出对应的集合,然后再返回,如果小于,就需要从当前位置开始遍历序列,然后往后累加,最后再进行回溯,把不可能的数字从数组中删除。
代码实现:
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) { // 注意 while 处理多个 case
int n = in.nextInt();
int m = in.nextInt();
List<Integer> sumList = new ArrayList<>();
print(n, m, 1, 0, sumList);
}
}
public static void print(int n, int targetSum, int pos, int curSum, List<Integer> sumList) {
// 如果当前和大于目标和,则说明继续往后累加的值也是大于目标和的,所以应该回退
if (curSum > targetSum) {
return;
}
// 如果当前和等于目标和,则输出即可。
if (curSum == targetSum) {
for (int i = 0; i < sumList.size() - 1; i++) {
System.out.print(sumList.get(i) + " ");
}
System.out.println(sumList.get(sumList.size() - 1));
return;
}
// 如果当前和小于目标和,就往后累加
for (int i = pos; i <= n; i++) {
sumList.add(i);
// 从下一个元素开始累加
print(n, targetSum, i + 1, curSum + i, sumList);
// 如果从递归中来到这里,则说明此时的当前和是要大于或等于目标和的
// 就需要把数组中的最后一个数删掉,然后去寻找下一个组合
sumList.remove(sumList.size() - 1);
}
}
}