牛客习题总结38(7月13日)

    科技2024-08-09  67

    CP与UDP不同,它是基于连接的,也就是说:为了在服务端和客户端之间传送TCP数据,必须先建立一个虚拟电路,也就是TCP连接。 问题就出在TCP连接的三次握手中,假设一个用户向服务器发送了SYN报文后突然死机或掉线,那么服务器在发出SYN+ACK应答报文后是无法收到客户端的ACK报文的(第三次握手无法完成),这种情况下服务器端一般会重试(再次发送SYN+ACK给客户端)并等待一段时间后丢弃这个未完成的连接,这段时间的长度我们称为SYN Timeout,一般来说这个时间是分钟的数量级(大约为30秒-2分钟);一个用户出现异常导致服务器的一个线程等待1分钟并不是什么很大的问题,但如果有一个恶意的攻击者大量模拟这种情况,服务器端将为了维护一个非常大的半连接列表而消耗非常多的资源----数以万计的半连接,即使是简单的保存并遍历也会消耗非常多的CPU时间和内存,何况还要不断对这个列表中的IP进行SYN+ACK的重试。实际上如果服务器的TCP/IP栈不够强大,最后的结果往往是堆栈溢出崩溃—即使服务器端的系统足够强大,服务器端也将忙于处理攻击者伪造的TCP连接请求而无暇理睬客户的正常请求(毕竟客户端的正常请求比率非常之小),此时从正常客户的角度看来,服务器失去响应,这种情况我们称作:服务器端受到了SYN Flood攻击(SYN洪水攻击)。 rst是复位报文 几种TCP链接中出现rst的情况 1.端口未打开 2,请求超时 3,提前关闭 4,在一个已关闭的socket上出现数据

    前28位为网络号,故子网掩码为11111111.11111111. 11111111. 11110000(255.255.255.240)。 256-240=16,有16个子网,每一个子网段大小范围是16。 10.11.12.91/28中91可以表示为:01011011,前四位为网络号,后四位为主机号, 故包含10.11.12.91的子网范围是:0101000001011111(8095)。 去掉第一个和最后一个,和 10.11.12.91/28在一个网段的范围为: 10.11.12.81/28~ 10.11.12.94/28。 当通过网络发送该数据时,x86系列 CPU都是Little-Endian的,所以int 型变量值为 0x78563412, 网络发送数据时,采用Big-Endian,先发送高位再发送低位。相当于cpu先反过来排,网络再顺着发。 补: 小端法(Little-Endian)就是低位字节排放在内存的低地址端(即该值的起始地址),高位字节排放在内存的高地址端; 大端法(Big-Endian)就是高位字节排放在内存的低地址端(即该值的起始地址),低位字节排放在内存的高地址端; 解析:子网掩码写成二进制形式则为:1111 1111 1111 1111 1111 1111 1111 11110 0000 0000;可用地址为2^9=512;但是要减去全0和全1,并且要减去一个网关设备,所以512-3=509.

    1、因为ping的话 后面跟的是地址,所以要先将域名转换为ip地址,即用到了DNS 2、获取到ip地址后,在数据链路层是根据MAC地址传输的,所以要用到ARP解析服务,获取到MAC地址 3、ping功能是测试另一台主机是否可达,程序发送一份ICMP回显请求给目标主机,并等待返回ICMP回显应答,(ICMP主要是用于ip主机、路由器之间传递控制信息,控制信息是指网络通不通,主机是否可达) 4、TCP的话,不涉及数据传输,不会用到 C类地址默认掩码为255.255.255.0 6个公司二进制为110, 有3位 所以在第4段中前3位置1,11100000->224 所以D

    import java.util.Iterator; import java.util.LinkedList; import java.util.Scanner; public class FrogMaze { static int n = 0; static int m = 0; // 当前求解方案走完剩余的能量 static int maxResidueEnergy = 0; // 迷宫地图 static int[][] map; // 是否能出去 static boolean canSolve = false; // 路径 static String path = ""; // 保存当前走过的点 static LinkedList<String> linkedList = new LinkedList<>(); public static void main(String[] args) { // 输入操作 Scanner scanner = new Scanner(System.in); while (scanner.hasNext()) { n = scanner.nextInt(); m = scanner.nextInt(); int p = scanner.nextInt(); map = new int[n][m]; // 迷宫地图录入 for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { map[i][j] = scanner.nextInt(); } } runMap(0, 0, P); if (!flag) System.out.println("Can not escape!"); else System.out.println(path) } public static void enterMaze(int x, int y, int energy) { // 递归越界,能量耗完,当前点不能走 if (energy<0 || x<0 || y<0 || x>=n || y>=m || map[x][y]==0) { return; } else { // "-"作为分隔符,方便更新路线操作 linkedList.push("["+x+","+y+"]-"); // 将当前块记0,使之后的点不能再走 map[x][y] = 0; // 当前找到了出口 if (x==0 && y==m-1) { // 本次方案剩余的能量值比当前花费最少的方案剩余的能量还多,进行最优路径的更新 if (energy >= maxResidueEnergy) { maxResidueEnergy = energy; updatePath(); } map[x][y] = 1; canSolve = true; return; } // 向上 enterMaze(x-1, y, energy-3); // 向右 enterMaze(x, y+1, energy-1); // 向下 enterMaze(x+1, y, energy); // 向左 enterMaze(x, y-1, energy-1); map[x][y] = 1; linkedList.removeLast(); } } /** * */ public static void updatePath() { StringBuilder sb = new StringBuilder(); Iterator<String> iterator = linkedList.iterator(); while (iterator.hasNext()) { sb.append(iterator.next()); } path = null; // 以 - 作为分隔符切分 String[] paths = sb.toString().split("-"); sb.delete(0, sb.length()); for (int i = paths.length-1; i >= 0; i--) { sb.append(paths[i]).append(","); } // 删除最后一个"," if (sb.length() > 0) { sb.deleteCharAt(sb.length()-1); } path = sb.toString(); } }
    Processed: 0.014, SQL: 8