0%

https://www.bilibili.com/video/BV1ke4y1w7yn

什么是反射 ?

反射允许对字段(成员变量),成员方法和构造方法的信息进程编程访问。

获取类对象字节码文件的三种方式

  • Class.forName(“全类名”);

  • 类名.class;

  • 对象.getClass();

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package com.qust;

import com.qust.reflect.Student;

public class Main {
public static void main(String[] args) {

/**
* 获取 class 对象的三种方式
*/

Class clazz1 = null;
try {
clazz1 = Class.forName("com.qust.reflect.Student");
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}

Class clazz2 = Student.class;

Class clazz3 = (new Student()).getClass();

System.out.println(clazz1);

System.out.println(clazz2);

System.out.println(clazz3);

}
}

点击类名,点击 copy - cpoy as Reference,即可复制全类名(包名 + 类名)

利用反射获取成员变量信息

Class 中用于获取成员变量的方法

  • Field[] getFields() : 返回所有公共成员变量对象的数组

  • Field[] getDeclaredFields(): 返回所有成员变量对象的数组

  • Field getField() : 返回单个公共成员变量对象

  • Field getDeclaredField() : 返回单个成员变量对象

Field 类中用于创建对象的方法

  • void set(Object obj, Object value) : 赋值

  • Object get(Object obj) :获取值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package com.qust;

import com.qust.reflect_.Student;

import java.lang.reflect.Field;

public class Main {
public static void main(String[] args) {
// 获取字节码文件
Class clazz;
try {
clazz = Class.forName("com.qust.reflect_.Student");
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}

// 获取所有公共成员变量
Field[] fields = clazz.getFields();
System.out.println("All public variable:");
for(Field f : fields) {
System.out.println(f.getName());
}
System.out.println();

// 获取所有成员变量
fields = clazz.getDeclaredFields();
System.out.println("All variable:");
for(Field f : fields) {
System.out.println(f.getName());
}
System.out.println();

// 获取单个成员变量
Field gender = null;
try {
gender = clazz.getField("gender");
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
}
System.out.println(gender);
System.out.println();

Field name = null;
try {
name = clazz.getDeclaredField("name");
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
}
System.out.println(name);
System.out.println();

// 获取权限修饰符
System.out.println(name.getModifiers()); // 2 : 私有的
// 获取成员变量名
System.out.println(name.getName());
// 获取数据类型
System.out.println(name.getType());
// 获取对象的值
Student student = new Student(11, "wpc", "male");
name.setAccessible(true);
Object value = null;
try {
value = name.get(student);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
System.out.println(value);
// 修改对象值
try {
name.set(student,"wpc_");
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
System.out.println(student);
}
}

利用反射获取成员方法

Class 类中获取成员方法的方法

  • Method[] getMethods() : 返回所有公共成员方法的数组,包括继承的

  • Method[] getDeclaredMethods()

  • Methods[] getMethod(String name, Class<?> … Parameters)

  • Methods[] getDeclaredMethod(String name, Class<?> … Parameters)

Method 类中用于创建对象的方法

  • Object invoke(Object object, Object .. args) : 运行方法

参数一 :用 obj 对象调用该方法

参数二 :调用方法的传递的参数(没有就不写)

返回值 :方法的返回值(没有就不写)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package com.qust;

import com.qust.reflect__.Student;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Test {
public static void main(String[] args) {
Class clazz;
try {
clazz = Class.forName("com.qust.reflect__.Student");
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}

// 获取所有的方法对象(包括父类的所有公共方法)
// Method[] methods = clazz.getMethods();
// for(Method method : methods) {
// System.out.println(method.getName());
// }


// 获取所有方法(不包括父类)
Method[] methods = clazz.getDeclaredMethods();
for(Method method : methods) {
System.out.println(method.getName());
}

// 获取指定的单一方法
Method m = null;
try {
m = clazz.getMethod("eat", String.class);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
System.out.println(m);

// 获取方法的修饰符
int modifiers = m.getModifiers();
// 获取方法名字
String name = m.getName();
// 方法形参
m.getParameters();
m.getParameterCount();
m.getParameterTypes();

// 方法抛出异常
Class[] exps = m.getExceptionTypes();


/**
* 运行方法 invoke
* 参数一 : 方法的调用者
* 参数二 : 调用方法传递的参数
*/
try {
String res = (String) m.invoke(new Student(), "shit");
System.out.println(res);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}

// 获取方法返回值
Class<?> returnType = m.getReturnType();
System.out.println(returnType);
}
}

反射的作用

  • 获取一个类的所有的信息,获取到了之后,在执行其他的业务逻辑

  • 结合配置文件,动态的创建并调用方法

练习一 保存信息

对于任意一个对象,都可以把对象的所有字段名和值,保存到文件中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package com.qust.practice1;

import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Field;

public class MyReflectDemo {
public static void main(String[] args) throws IOException, IllegalAccessException {
Student s = new Student("wpc", 21, "male", "learn", 180.5);
Teacher t = new Teacher("teacher1", -100);
System.out.println(System.getProperty("user.dir"));
saveObjects(s);
}

// 将对象里面所有的成员变量名和值保存到本地文件中
public static void saveObjects(Object obj) throws IOException, IllegalAccessException {
// 1. 获取字节码文件对象
Class clazz = obj.getClass();

// 2. 创建 IO 流
BufferedWriter bw = new BufferedWriter(new FileWriter("C:\\Users\\95432\\Desktop\\Java-Reflect\\demo-reflect\\src\\main\\java\\com\\qust\\practice1\\data.txt"));
// BufferedWriter bw = new BufferedWriter(new FileWriter("data.txt"));

// 3. 获取所有的成员变量
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
String name = field.getName();
Object value = field.get(obj);
System.out.println(name + "=" + value);
bw.write(name + "=" + value);
bw.write("\n");
}
bw.close();
}
}

不知道为什么相对路径写入信息写不进去,也没提示找不到文件报错

练习二

跟配置文件结合,动态创建对象,并调用方法

  • Main.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.qust.practice2;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Properties;

public class Main {
public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
// 读取配置文件信息
Properties prop = new Properties();
prop.load(new FileInputStream("C:\\Users\\95432\\Desktop\\Java-Reflect\\demo-reflect\\src\\main\\resources\\test .properties"));
System.out.println(prop);

// 获取全类名和方法名
String className = (String) prop.get("classname");
String methodName = (String) prop.get("method");

System.out.println(className);
System.out.println(methodName);

// 利用反射创建对象,并运行方法
Class clazz = Class.forName(className);
// 获取构造方法
Constructor con = clazz.getDeclaredConstructor();
Object o = con.newInstance();
System.out.println(o);

// clazz.newInstance(); @deprecated

clazz.getDeclaredMethod(methodName).invoke(o);
}
}
  • test.properties
1
2
classname=com.qust.practice2.Student
method=learn

如果之后要运行别的类的方法,修改配置文件即可,例如修改为

className

classname=com.qust.practice2.Teacher
method=teach

动态代理

  • 为什么需要代理 ?

无侵入式的给对象增加额外的功能。

调用者 $\rightarrow$ 代理 $\rightarrow$ 对象

(对象功能太多的话,可以通过代理转移部分职责。)

  • 代理长什么样 ?

代理里面就是对象想要被代理的方法

(对象有什么方法想被代理,代理就一定要有对应的方法。)

  • Java通过什么保证代理的样子 ?

通过接口保证,后面的对象和代理需要实现同一个接口,接口中就是被代理的所有方法。

动态代理实例

Interface : Star

1
2
3
4
5
6
7
8
9
package com.qust;

public interface Star {
// 唱歌
public abstract String sing(String name);

// 跳舞
public abstract void dance();
}

Class : BigStar

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package com.qust;

public class BigStar implements Star{
private String name;

// 唱歌
@Override
public String sing(String name) {
System.out.println(this.name + "正在唱" + name);
return "谢谢";
}

// 跳舞
@Override
public void dance() {
System.out.println(this.name + "正在跳舞");
}

public BigStar() {
}

public BigStar(String name) {
this.name = name;
}

/**
* 获取
* @return name
*/
public String getName() {
return name;
}

/**
* 设置
* @param name
*/
public void setName(String name) {
this.name = name;
}

public String toString() {
return "BigStar{name = " + name + "}";
}
}

Class : Proxyutil

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package com.qust;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
* 类的作用 :
* 创建一个代理
*/


public class ProxyUtil {

/**
* 方法的作用 : 创建一个代理
* @param bigStar
* 返回值 :
* 给 BigStar 创建的代理
*/
public static Star createProxy(BigStar bigStar) {
/**
* java.lang.reflect.Proxy类 :提供了为对象产生代理对象的方法
* public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
* 参数一 : 用于指定哪个类加载器
* 参数二 : 指定接口,这些接口用于指定生成的代理长什么样,也就是有哪些方法
* 参数三 :指定生成的代理对象要干什么事情
*/
Star star = (Star) Proxy.newProxyInstance(
BigStar.class.getClassLoader(),
new Class[]{Star.class},
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if("sing".equals(method.getName())) {
System.out.println("准备话筒,收钱");
}
else if("dance".equals(method.getName())) {
System.out.println("准备场地,收钱");
}

return method.invoke(bigStar, args);

}
}
);

return star;
}

}

Class : Main

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.qust;

//TIP To <b>Run</b> code, press <shortcut actionId="Run"/> or
// click the <icon src="AllIcons.Actions.Execute"/> icon in the gutter.
public class Main {
public static void main(String[] args) {

// 获取代理对象
BigStar bigStar = new BigStar("鸡哥");
Star proxy = ProxyUtil.createProxy(bigStar);

// 调用对应方法
String result = proxy.sing("只因你太美");
System.out.println(result);

proxy.dance();
}
}

Usage

usage就是这个东西在哪里被使用了

Javabean

JavaBean 是一种符合特定规范的 Java 类,用于封装数据并通过 getter/setter 方法访问。

Ptg 可以一键生成 Javabean

class<?> []

class<?>[] 是 Java 中的一种数组类型,表示一个元素类型为 任意类型的 Class 对象数组

1
2
3
4
5
6
7
8
9
10
11
public class Example {
public static void main(String[] args) {
// 创建一个 Class<?> 数组
Class<?>[] classes = {String.class, Integer.class, Double.class};

// 输出每个元素的类名
for (Class<?> clazz : classes) {
System.out.println(clazz.getName());
}
}
}
1
2
3
java.lang.String
java.lang.Integer
java.lang.Double

打包成 jar 包会去除所有注释吗?

不会,打包成 JAR 包时注释不会被自动去除

具体原因是:

  1. 注释属于源码的一部分,它们不会被编译到 .class 文件中,因此在编译阶段就被丢弃了。JAR 包中存储的是编译后的字节码(.class 文件),而不是源码(.java 文件)。

  2. 如果 JAR 包中需要包含源码(比如 -sources JAR),源码中的注释会被保留,但这些注释只是存储在 .java 文件中,供开发者阅读使用,不影响运行时。

    总结

  • 普通 JAR 包(包含 .class 文件):没有注释,因为注释早在编译时被去掉了。

  • 源码 JAR 包(包含 .java 文件):注释会被保留。
    如果你的目标是生成一个干净的 JAR 包,避免泄露源码或敏感注释,可以通过排除 .java 文件的方式只打包字节码。

term

  • invoke v. 调用

  • utility /juːˈtɪləti/ n. 实用工具

  • AOP,Aspect-Oriented Programming,面向切面编程

  • proxy /ˈprɒksi/ n. 代理权,代理人

从0到1开发一个SpringBoot入门Demo

项目打包方法

  • 终端输入 mvn clean install 命令,等待控制台输出 BUILD SUCCESS,在 target 目录生成一个 .jar

  • 复制 .jar 包的路径,例如 /Users/evan/IdeaProjects/boot-demo/target/1.jar ,控制台输入 cd /Users/evan/IdeaProjects/boot-demo/target/ ,输入 ll 可以查看内容。

  • 使用 java -jar 1.jar 即可运行启动应用,直接访问项目 ;也可以修改端口,java -jar 1.jar --server.port=8081

什么是 IoC

1 IOC 是控制反转, Inversion of Control。
2 控制反转不是一种语法,不是类或方法,它是一种设计模式
3 当A类依赖于B类,如果不使用控制反转,A类要主动创建B类的对象,也就是new B类,这时候控制权在A类的手中,这就是主动控制; 使用控制反转,A类只要声明自己需要B类,而控制权交给Spring容器,Spring容器在A需要B类的时候为其注入B类即可,这时候控制权在Spring容器手中,即控制反转了。
4 好处是什么呢?控制反转后A类与B类的耦合性就降低了,程序更加灵活。
5 比如,一家公司为了卫生和清洁,需要有人打扫卫生,这家公司可以自己聘用一个保洁,就是将管理保洁的权利控制在自己手中,自己new一个保洁,那么这个保洁请假、调休、年终福利、婚丧嫁娶都要操心,太麻烦了,公司和这个保洁紧紧地绑在 一起,给公司带了了很大的负担。
公司决定采用控制反转模式,将保洁管理的权限交给物业来做,自己需要保洁的时候,由物业来分配一个保洁即可,公司和保洁直接就就没有什么关系了,松耦合了,这时候物业公司就是Spring容器,公司将保洁的控制权反转给了物业公司,当公司需要保洁的时候,物业公司将一个保洁注入到公司即可。
这就是控制反转模式。

IoC,Inversion of Control 作为一种设计模式,主要通过解耦组件之间的依赖关系,提升代码的可维护性、可扩展性和测试性。以下是 IoC 好处的一些实例及具体体现:

实例 1:可替换的数据库访问层

  • 场景:在开发一个多数据库支持的系统时,例如需要支持 MySQL 和 MongoDB。

  • 实现
    使用接口来抽象数据库操作逻辑,例如定义一个 DatabaseService 接口。然后实现 MySQLDatabaseServiceMongoDBDatabaseService 两个具体类。
    通过 IoC 容器将具体实现注入业务层代码中。

  • 体现的好处灵活性:切换数据库实现时,只需要更改注入配置,而不需要修改业务代码。可测试性:在单元测试时,可以注入一个 Mock 的 DatabaseService,无需真实数据库环境。

实例 2:解耦日志记录模块

  • 场景:应用需要支持不同的日志库(如 Log4j、SLF4J 或自定义日志系统)。

  • 实现
    定义一个 Logger 接口,并提供多个实现类,如 Log4jLoggerSLF4JLogger。通过 IoC 容器将具体实现注入需要记录日志的模块。

  • 体现的好处解耦:模块依赖于 Logger 接口,而非具体实现,日志实现的变更不会影响业务逻辑。可扩展性:可以轻松添加新的日志实现,无需修改现有代码。

实例 3:实现可扩展的通知服务

  • 场景:在系统中需要向用户发送多种类型的通知,例如短信、邮件、微信消息等。

  • 实现
    通过定义一个 NotificationService 接口,将 SMSNotificationServiceEmailNotificationServiceWeChatNotificationService 等实现类注入不同的上下文。

  • 体现的好处开闭原则:新增通知方式时,只需增加实现类和注入配置,不需更改原有代码。可测试性:测试时可以注入 Mock 实现,而不触发实际通知发送。

实例 4:Web 应用中的控制器与服务解耦

  • 场景:Web 控制器需要调用业务逻辑,但不同业务逻辑模块可能会发生变动。

  • 实现
    控制器通过依赖注入方式获取服务对象,而不是直接创建具体服务类实例。例如,使用 Spring 框架时,控制器通过 @Autowired 注解获取服务实例。

  • 体现的好处职责单一:控制器只负责调用服务,服务的实现逻辑可以独立修改。便于测试:控制器的单元测试中,可以注入模拟服务,而无需真实服务逻辑。

实例 5:动态替换算法实现

  • 场景:在一个搜索应用中,不同场景下需要使用不同的排序算法(如按相关性排序或按时间排序)。

  • 实现
    定义一个 SortAlgorithm 接口,通过 IoC 容器注入 RelevanceSortTimeSort 的实现到搜索模块。

  • 体现的好处易于扩展:添加新的排序算法时,不需要修改现有代码。降低耦合:搜索模块只依赖于抽象接口,而与具体排序实现无关。

总结

IoC 的核心好处通过以下方面体现:

  1. 代码解耦:模块之间通过接口交互,降低直接依赖。
  2. 易于扩展:新增功能时只需实现接口并配置注入,无需修改已有逻辑。
  3. 提高测试性:通过注入 Mock 实现,单元测试无需依赖外部系统。
  4. 统一管理依赖:依赖由 IoC 容器管理,简化了对象的创建和生命周期管理。
    这些好处在实际项目中大大提升了开发效率和代码质量,同时也让项目更容易维护和扩展。

打开项目结构

视图 > 解决方案资源管理器

设置启动项

新建 C++ 空项目,导入对应源文件、头文件、资源文件。

TODAY

今天看了一个某位大一做的简易电动自行车充电管理系统,感觉就是一坨,懒得看了。

Visual Studio 导入现有项,并不会复制一份文件,类似于复制过来一个文件路径。

WHAT IS NTD ?

通常 NTD 是指新台币,New Taiwan Dollar。

WHAT IS STUMIS ?

Student Management Information System 学生管理信息系统

过拟合

过拟合(Overfitting)是机器学习中的一种现象,指模型在训练数据上表现得非常好(即误差很小),但在测试数据或新数据上表现得很差。换句话说,模型过于“记住”了训练数据的细节和噪声,而没有学习到数据的总体规律或本质特征。

过拟合的表现

  1. 训练集误差很小:模型在训练集上的预测表现非常好。

  2. 测试集误差很大:模型在测试集上的表现却很差,无法很好地推广到新数据。

  3. 对噪声过于敏感:模型可能学习到了训练数据中的噪声和异常值,而不是数据的真实模式。

为什么会发生过拟合?

  1. 模型太复杂
  • 模型的自由度过高(如神经网络的层数或参数过多),能够拟合训练数据中的每个细节。
  1. 训练数据不足
  • 训练数据量过少,使得模型容易记住数据,而不是泛化规律。
  1. 训练时间过长
  • 模型训练时间过长,逐渐对训练数据“死记硬背”。
  1. 数据噪声
  • 数据中包含较多的噪声或无关特征,模型将这些噪声也视为模式。

如何防止过拟合?

  1. 增加数据量
  • 收集更多的训练数据,帮助模型更好地学习数据的总体分布。
  1. 简化模型
  • 减少模型的复杂度(如降低神经网络的层数、减少参数数量)。
  1. 正则化
  • 添加正则化项(如L1或L2正则化),限制模型参数的大小,防止过于复杂。
  1. 使用验证集
  • 在训练过程中通过验证集监控模型性能,防止训练时间过长。
  1. 提前停止(Early Stopping)
  • 在验证集误差开始增大时停止训练。
  1. 数据增强
  • 使用数据增强技术生成更多变种的训练数据(如图像旋转、裁剪等)。
  1. Dropout(神经网络中常用):
  • 随机丢弃一部分神经元,防止网络过于依赖特定节点。

过拟合的简单例子

假设你要用一个模型拟合一个散点图(如预测房价):

  • 欠拟合(Underfitting):模型是一个简单的直线,未能捕捉数据的非线性关系。
  • 正常拟合(Good Fit):模型是一条合理的曲线,能较好地预测数据趋势。
  • 过拟合(Overfitting):模型是一条非常复杂的曲线,完美拟合了每一个点,但在新数据上预测效果很差。
    通过平衡模型的复杂度和训练数据量,同时引入合适的正则化手段,可以有效地减轻过拟合问题。

ABC : American-born Chinese

“ABC” : American-born Chinese

美国出生的华裔


Welcome to 2025 🎉

Let’s embrace the future with colors and possibilities!

**HELLO, 2025** - Let's make this year unforgettable with passion and creativity!
**HELLO, 2025** - A year filled with new adventures and success.
**HELLO, 2025** - Keep pushing boundaries and pursuing your dreams!
**HELLO, 2025** - New challenges, new opportunities. Embrace them all!
**HELLO, 2025** - Let the creativity flow and bring your ideas to life!
**HELLO, 2025** - The future is bright, let's shine together!
HELLO, 2025
HELLO, 2025
HELLO, 2025
HELLO, 2025

TCP报文段的窗口字段的含义

TCP报文段的窗口字段表示的是接收方的接收窗口

(蒙错了,蒙的发送方的接收窗口)

主机到另一个主机经过两个switch,一个router,几次ARP?

不太好查

CSMA/CD为什么不适用于无线网络

  • 碰撞检测困难

    • 在无线网络中,设备之间的信号是通过空气传播的,信号会受到衰减和干扰。设备无法像有线网络中那样清晰地检测到碰撞,因为发送信号的设备可能无法接收到从其他设备发出的信号,尤其是在距离较远或信号被遮挡的情况下。这导致无法有效地判断是否发生了碰撞。
  • 隐蔽终端问题

    • 在无线网络中,不同设备的信号传播范围有限,因此某些设备可能无法直接接收到其他设备的信号,这就出现了隐蔽终端问题(Hidden Terminal Problem)。即某些设备无法察觉到其他设备正在发送数据,可能导致它们在信道上同时发送数据而发生碰撞。
  • 信道共享

    • 无线网络是共享信道的,每个设备都共享同一个频谱。在无线通信中,如果所有设备都使用 CSMA/CD 的方式,频繁的碰撞和重试会导致网络效率低下。因此,无线网络通常采用其他机制(如 CSMA/CA)来避免碰撞。

(自己就写了碰撞检测困难的问题,甚至没写CSMD/CA更适合,因为自己没具体学这个协议,怕写错了)

NAT(网络地址转换)不允许使用 “广播地址”“多播地址” 作为私有网络地址。

感觉自己写错了。

配置访问互联网地址

蒙错了估计

网络协议三要素

语法、语义和时序

PING使用的是 ICMP 报文的哪个类型 ?

回送请求或回答

TCP/IP是一个工业标准而非国际标准

数据链路层三个任务

(1)封装成帧

(2)透明传输

(3)差错检测

广播域和冲突域

1. 广播域 (Broadcast Domain)

  • 定义:广播域是指通过广播数据帧(如 ARP 请求)可以被传播到的所有网络设备的范围。
  • 特点
    • 所有同一广播域内的设备都会接收到广播帧。
    • 通过路由器可以隔离广播域,交换机不会隔离广播域。
  • 影响因素
    • 设备过多会导致广播流量增大,影响网络性能。
    • VLAN(虚拟局域网)可以创建多个独立的广播域。

2. 冲突域 (Collision Domain)

  • 定义:冲突域是指在使用共享传输介质的网络中,多个设备可能同时发送数据,导致数据冲突的范围。
  • 特点
    • 常见于传统的集线器(Hub)或使用共享以太网的网络中。
    • 交换机(Switch)可以隔离冲突域,每个端口是一个独立的冲突域。
    • 数据冲突会导致重传,降低网络效率。

题目一

以太网帧FCS字段的功能是(  A )    

A. 差错检测             B. 确保数据按照顺序到达   

C. 流量控制             D. 标识本地网络中的设备

FCS 字段,就是 Frame Check Sequence,用于差错检测,一般用 CRC 计算生成 FCS 字段。

Ethernet 帧格式 :

前导符 起始符 目MAC地址 源MAC地址 类型/长度 数据 PAD CRC

题目二

当进入网络的数据流量超过网络的载送能力时,将引起网络的吞吐率急剧下降,这时必须启用网络( 拥塞控制 )。

拥塞控制的作用对象是网络中的所有设备(如路由器、交换机等),它通过调节发送方的发送速率来避免网络中某个部分因过载而导致的性能下降。

流量控制的作用对象是接收方,确保接收方能够跟得上发送方的速度,不会因缓冲区满而丢弃数据。流量控制是为防止接收方缓冲区溢出所需要的。

题目三

以太网技术规范不包括(A )。

A. 网络层 B. 物理层 C. 数据链路层 D. 介质访问控制层

以太网的技术规范主要有以下三个层次 :

  • 物理层(Physical Layer):定义了网络的硬件设备和传输媒介的标准,例如电缆、光纤、网络接口等。
  • 数据链路层(Data Link Layer):负责在两个直接相连的设备之间传输数据帧,包括数据的封装、错误检测等。
  • 介质访问控制层(MAC Layer):是数据链路层的一部分,负责管理设备如何访问传输介质以及如何控制冲突等。

物理层接口的特性

  • 机械特性:接线器的形状和尺寸、引脚数目和排列、固定和锁定装置等。

  • 电气特性:电压范围。

  • 功能特性:指明某条线上的出现的某一电平的电压有何意义。

  • 过程特性:指明对于不同功能的各种可能事件的出现顺序。

题目四

当前因特网IP的版本是( )。
A. IPv6 B. IPv3 C. IPv4 D. IPv5

当前因特网的版本是 IPV4.

TCP三次握手、四次挥手

1、建立连接

(1)SYN = 1,seq = x

(2)SYN = 1, ACK = 1, seq = y, ack = x + 1

(3)ACK = 1,ack = y + 1, seq = x + 1

2、释放连接

(1)FIN = 1, seq = u

(2)ACK = 1, seq = v, ack = u + 1

(3)FIN = 1, ACK = 1, seq = w, ack = u + 1

(4)ACK = 1, seq = u + 1, ack = w + 1

计算机网络最基本的功能是数据通信,最主要的功能是资源共享

CSMA/CD

在使用CSMA/CD协议时,一个站不可能同时发送和接收。

数据链路层的三个基本功能

(1)封装成帧 :将分组封装成帧

(2)透明传输 :避免消息符号跟帧定界符号混淆

(3)差错检测 :防止出错的无效数据帧继续传播

RIP和OSPF路由信息交换方式的不同

(1)RIP是距离向量路由协议 ;OSPF是链路状态路由协议

(2)RIP仅向相邻路由器发送信息,发出的路由信息为该路由器的路由表 ;OSPF向本自己系统内所有路由器发送信息,发送的路由信息为该路由器的链路状态信息

(3)RIP定期和相邻路由器交换信息 ;OSPF只有链路状态信息发生变化时才洪泛信息

针对支持子网掩码的路由器,写出IP分组转发的算法

1、从收到的分组的首部提取目的IP地址 D。

2、先用各网络的子网掩码和D逐位相与,看是否匹配。如果匹配,直接交付分组 ;否则,间接交付,执行 3

3、若路由表中有目的地址为 D 的特定主机路由,则将分组传送给指明的下一条路由器 ;否则,执行 4

4、对路由表中的每一行的子网掩码和 D 逐位相“与”,若其结果与该行的目的网络地址匹配,则将分组传送给该行指明的下一跳路由器;否则,执行 5。

5、若路由表中有一个默认路由,则将分组传送给路由表中所指明的默认路由器;否则,执行 6。

6、 报告转发分组出错。