查看原文
其他

什么是双亲委派模式?

编程导航和鱼友们 面试鸭 2024-03-29

大家好呀,今天是编程导航 30 天面试题挑战的第二十八天,一起来看看今天有哪些优质面试题吧。

后端

题目一

什么是双亲委派模式?有什么作用?

官方解析

双亲委派模式(Parent-Delegate Model)是 Java 类加载器(ClassLoader)在加载类时所采用的一种设计模式。这种模式的核心思想是:当一个类加载器收到类加载请求时,首先不会尝试自己加载这个类,而是将请求委派给其父类加载器。依次递归,直到最顶层的启动类加载器(Bootstrap ClassLoader);如果父类加载器无法加载该类,子类加载器才尝试自己去加载

双亲委派模式的作用主要有以下几点:

  1. 避免类的重复加载:通过委派给父类加载器加载类,可以确保同一个类不会被多个类加载器重复加载。这有助于节省内存资源,并确保类之间的互操作性。
  2. 保护 Java 核心类库:由于双亲委派模式的存在,用户自定义的类加载器无法直接加载 Java 核心类库(如java.lang.Object等)。这有助于确保 Java 核心类库的安全性,防止恶意代码篡改或破坏Java核心类。
  3. 维护类加载器的层次结构:双亲委派模式使得各级类加载器可以按照一定的层次结构来组织和管理。这有助于降低类加载器的复杂性,简化类加载过程。

双亲委派模式在 Java 类加载器中的应用是一种优秀的设计原则,它有助于确保类加载过程的稳定性、安全性和可维护性。

然而,在某些特殊场景下(如 OSGi、Java 热加载等),双亲委派模式可能无法满足需求,需要采用其他类加载策略。在这些场景下,开发者需要充分了解类加载机制,以避免产生意外的问题。

鱼友的精彩回答

Starry 的回答

双亲委派模式是一种类加载机制,它是基于一个简单的原则:除非有明确的需求,否则类加载器不会尝试去加载一个它找不到的类,而是把这个任务交给父类加载器来完成。

具体来说,当一个类加载器需要加载某个类时,它首先会委派给它的父类加载器去加载该类。如果父类加载器无法找到该类,则再将加载任务委派给它的父类加载器,直到最终委派到顶层的启动类加载器。如果顶层的启动类加载器仍然无法找到该类,则会抛出 ClassNotFoundException 异常。

这样做的好处是:防止内存中出现多份同样的字节码。

双亲委派模式的作用:

  • 保证 JVM 中每个类只会被加载一次,避免重复加载。当一个类被加载后,它会被缓存在 JVM 的内存中,以便之后的使用。
  • 如果不采用双亲委派模式,可能会导致同一个类被多次加载,从而浪费大量的内存资源。
  • 此外,双亲委派模式还可以保证类的安全性,因为如果一个类是由用户自定义的类加载器加载的,那么它并不能访问由系统类加载器或其它更高级别的类加载器加载的类。对于一些核心类,例如 java.lang.Object、java.lang.String 等,它们都是由启动类加载器加载的,因此也可以保证它们的正确性和安全性。

林风的回答


双亲委派机制是指当一个类加载器收到一个类加载请求时,该类加载器首先会把请求委派给父类加载器。每个类加载器都是如此,只有在父类加载器在自己的搜索范围内找不到指定类时,子类加载器才会尝试自己去加载。

双亲委派模型的好处 双亲委派模型保证了 Java 程序的稳定运行,可以避免类的重复加载,因为即使这两个类来源于同一个 Class 文件,被同一个虚拟机加载,只要加载它们的类加载器不同,那么这两个类就必定不相等。

同时保证了 Java 的核心 API 不被篡改。避免类的重复加载 保证Java核心API不被篡改

HeiHei 的回答

双亲委派:

类加载机制:双亲委派模型顾名思义就是每一个类加载器(classLoader)收到一个类加载请求,都不会先自己去加载,而是委托给自己的父类加载,如果父类加载器还存在它的父类加载器,则继续向上委托,直到达到最顶层的父类加载器,从最顶层的父类加载器开始进行类的加载,如果最顶层的类加载器找不到类的路径,又交给子类加载进行加载,依次进行递归,通俗地说,如下面的例子:

  • 假设用户刚刚写的 Tes t类想进行加载,这个时候首先会发送给应用程序类加载器 AppCloassLoader;
  • 然后 AppClassLoader 并不会直接去加载 Test 类,而是会委派于父类加载器完成此操作,也就是 ExtClassLoader;
  • ExtClassLoader 同样也不会直接去加载 Test 类,而是会继续委派于父类加载器完成,也就是 BootstrapClassLoader;
  • BootstrapClassLoader 这个时候已经到顶层了,没有父类加载器了,所以 BootstrapClassLoader 会在 jdk/lib 目录下去搜索是否存在,因为这里是用户自己写的 Test 类,是不会存在于 jdk 下的,所以这个时候会给子类加载器一个反馈。
  • ExtClassLoader 收到父类加载器发送的反馈,知道了父类加载器并没有找到对应的类,爸爸靠不住,就只能自己来加载了,结果显而易见,自己也不行,没办法,只能给更下面的子类加载器了。
  • AppClassLoader 收到父类加载器的反馈,顿时明白,原来爸爸虽然是爸爸,但是他终究不能管儿子的私事,所以这时候,AppClassLoader 就自己尝试去加载。

作用:

  1. 避免重复加载类:如果一个类已经被某个类加载器加载过了,那么其他类加载器就不需要再次加载该类,因为类的定义只需要加载一次就可以了。
  2. 确保类的唯一性:通过双亲委派模式,可以保证不同的类加载器加载同一个类时,得到的都是同一个 Class 对象,从而保证了类的唯一性。
  3. 安全性:通过双亲委派模式,可以保证核心 Java API 不会被非法替换,从而提高了 Java 应用的安全性。

题目二

什么是正向代理和反向代理,如何使用 Nginx 做反向代理?

官方解析

正向代理反向代理都是代理服务器的两种应用场景,它们在网络请求的处理过程中扮演不同的角色:

正向代理(Forward Proxy):正向代理位于客户端和目标服务器之间,客户端通过正向代理来访问目标服务器。正向代理代表客户端发起请求,隐藏客户端的真实身份。常见的应用场景包括使用魔法、访问内网资源、缓存和过滤等。

反向代理(Reverse Proxy):反向代理位于客户端和目标服务器之间,客户端直接访问反向代理服务器,反向代理将请求转发给目标服务器。反向代理代表目标服务器接收请求,隐藏目标服务器的真实身份。常见的应用场景包括负载均衡、安全防护、缓存和SSL终端等。

使用 Nginx 作为反向代理的方法如下:

安装Nginx:根据操作系统和需求选择合适的Nginx版本进行安装。安装完成后,启动Nginx。

配置反向代理:编辑 Nginx 的配置文件(通常位于/etc/nginx/nginx.conf或/etc/nginx/sites-available/default),在 http 或 server 块中添加反向代理配置。

示例配置:

http {
    ...
    server {
        listen 80; # 监听的端口号
        server_name example.com; # 反向代理的域名

        location / {
            proxy_pass http://backend_server; # 将请求转发给目标服务器
            proxy_set_header Host $host# 设置请求头部信息
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }
    
}

在这个示例中,将客户端的请求转发给名为 backend_server 的目标服务器。同时设置了一些请求头部信息,以便目标服务器获取客户端的真实 IP 地址。

重启 Nginx:保存配置文件并重启 Nginx,使配置生效。通常可以使用 nginx -s reload 或 systemctl restart nginx 命令重启 Nginx。

完成以上步骤后,Nginx 就被配置为反向代理服务器,可以将客户端的请求转发给目标服务器。

鱼友的精彩回答

林寻的回答

什么是正向代理和反向代理

  1. 正向代理
  2. 反向代理
  3. 两者的区别
1.正向代理

正向代理隐藏真实客户端

正向代理,就是一个位于客户端和原始服务器之前的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并且指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端,客户端才能使用正向代理。

比如我们要去访问某个网站,我们直接访问不通,那么我们就可以找一个代理服务器为我们服务,我们通过代理服务器请求到这个网站。对于这个网站而言他只知道有一个服务器访问了自己,并不知道你访问了他。

再举一个简单的例子告诉你什么是正向代理:

假设 A 和 B 是同学,但平时并不是很熟,A 向 B 借钱,被 B 拒绝了。

此时 A 联系了 C,C 是 A 的好朋友,C 和 B 也很熟。

C 向 B 借了钱并且给了 A。

此时 A 拿到了 B 的钱,但B并不知道他的钱借给了 A。

这时B同学扮演了一个非常关键的角色,就是代理,也可以说是正向代理

即就是隐藏了真实的客户端

正向代理的过程,隐藏了真实的客户端。客户端请求的服务都被代理服务器代替来请求

2.反向代理

反向代理隐藏真实服务端

反向代理服务器位于用户与目标服务器之间,但是对于用户而言,反向代理服务器就相当于目标服务器,即用户直接访问反向代理服务器就可以获得目标服务器的资源。同时,用户不需要知道目标服务器的地址,也无须在用户端作任何设定。反向代理服务器通常可用来作为 Web 加速,即使用反向代理作为 Web 服务器的前置机来降低网络和服务器的负载,提高访问效率。

反向代理方式是指以代理服务器来接收 internet 网上的连接请求,然后将请求转发给内部网络上的服务器,并从服务器上得到的结果返回给 internet 上请求连接的客户端,此时代理服务器对外就表现为一个节点服务器。

简单举例什么是反向代理:

我们平时访问百度时,直接访问网址。

它背后可能有成千上万的服务器为我们服务,但具体是哪一台为我们服务,我们并不知道,也没必要知道。

我们只需要知道反向代理服务器是谁就可以(只要达到目的就可以了)。

网址就是我们的反向代理服务器,它会把我们的请求发送到真实的服务器那里去。

即隐藏真实的服务端

Nginx 就是性能非常好的反向代理服务器,用来做负载均衡。

3. 两者的区别

两者的区别在于代理的对象不一样:正向代理代理的对象是客户端,反向代理代理的对象是服务端

正向代理中,proxy 和 client 同属一个 LAN,对 server 透明;反向代理中,proxy 和 server 同属一个 LAN,对 client 透明。实际上 proxy 在两种代理中做的事都是代为收发请求和响应,不过从结构上来看正好左右互换了下,所以把后出现的那种代理方式叫成了反向代理。

猫十二懿的回答

正向代理是指代理服务器代表客户端向目标服务器发送请求,代理服务器与目标服务器通信,并将响应返回给客户端。在这种情况下,目标服务器不知道请求的来源是代理服务器还是真正的客户端,因此正向代理可以用于隐藏客户端的真实 IP 地址和身份信息。客户端必须要进行一些特别的设置才能使用正向代理。就像要访问 google 用 vpn 代理翻墙去访问(用户知道要访问真正的服务器)

反向代理是指==代理服务器代表原始服务器==向客户端发送响应,代理服务器接收客户端请求并将其转发到原始服务器,然后将原始服务器的响应返回给客户端。在这种情况下,客户端不知道响应的来源是原始服务器还是代理服务器,因此反向代理可以用于负载均衡、缓存静态资源、增加安全性等方面。

Nginx 是一个功能强大的开源 Web 服务器,也是一个反向代理服务器。使用 Nginx 做反向代理可以将客户端请求转发到后端多台真实服务器上,从而实现负载均衡、缓存静态资源、防止攻击等功能。下面是使用 Nginx 做反向代理的示例代码:

http {
    upstream backend { # upstream 模块指定了后端服务器的列表,可以设置不同的权重,以实现负载均衡;
        # 设置后端服务器列表
        server backend1.com weight=5;
        server backend2.com;
        server unix:/tmp/backend3;
    }

    server {
        listen 80 ; # 监听端口
        server_name shier.com;

        location / { # location 模块指定了反向代理的规则,以及缓存静态资源和防止攻击等功能
            # 设置反向代理规则
            proxy_pass http://backend/; # 将请求转发给原始服务器
            proxy_set_header Host $host#设置请求头部信息
            proxy_set_header X-Real-IP $remote_addr;

            # 缓存静态资源
            proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m inactive=60m;
            proxy_cache_key "$scheme$request_method$host$request_uri";
            proxy_cache_valid any 20m;
            proxy_cache_bypass $http_pragma;
            proxy_cache_revalidate on;

            # 防止攻击
            limit_conn_zone $binary_remote_addr zone=addr:10m;
            limit_conn addr 5;
            limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
            limit_req zone=one burst=50 nodelay;
        }
    }
}

HeiHei 的回答

正向代理:

正向代理是一个位于客户端和目标服务器之间的代理服务器(中间服务器)。为了从目标服务器取得内容,客户端向代理服务器发送一个请求,并且指定目标服务器,之后代理向目标服务器转发请求,将获得的内容返回给客户端。正向代理的情况下,客户端必须要进行一些特殊的设置才能使用。

  • 正向代理需要主动设置代理服务器 ip 或者域名进行访问,由设置的服务器 ip 或者域名去访问内容并返回
  • 正向代理是代理客户端,为客户端收发请求,使真实客户端对服务器不可见。

使用场景:比如我们国内访问谷歌,直接访问访问不到,我们可以通过一个正向代理服务器,请求发到代理服,代理服务器能够访问谷歌,这样由代理去谷歌取到返回数据,再返回给我们,这样我们就能访问谷歌了

反向代理:

反向代理是指以代理服务器来接收客户端的请求,然后将请求转发给内部网络上的服务器,将从服务器上得到的结果返回给客户端,此时代理服务器对外表现为一个反向代理服务器。对于客户端来说,反向代理就相当于目标服务器,只需要将反向代理当作目标服务器一样发送请求就可以了,并且客户端不需要进行任何设置。

  • 正向代理需要配置代理服务器,而反向代理不需要做任何设置。
  • 反向代理是代理服务器,为服务器收发请求,使真实服务器对客户端不可见。

使用 Nginx 实现反向代理:

示例:使用 Nginx 反向代理,根据访问的路径跳转到不同端口的服务中,Nginx 监听端口为 9001 访问 http://192.168.17.129/edu/直接跳转到 127.0.0.1:8080 访问 http://192.168.17.129/vod/直接跳转到 127.0.0.1:8081 第一步,需要准备两个 tomcat,一个 8080 端口,一个 8081 端口,并准备好测试的页面 第二步,修改 nginx 的配置文件,在 http 块中配置 server

server {
 listen       9001;
 server_name  192.168.17.129;

 location ~ /edu/ {
  proxy_pass  http://127.0.0.1:8080
 }

 location ~ /vod/ {
  proxy_pass  http://127.0.0.1:8081
 }
}

Gianhing 的回答

正向代理:客户端向代理服务器发送一个请求并指定目标,由代理服务器向目标服务器发起请求,并将响应结果返回给客户端。代理的对象是客户端

使用场景:

  • 突破访问限制:正向代理可以访问受限制的资源,例如被墙的网站和内网资源等
  • 提高访问速度:正向代理能够缓存数据,当客户端请求相同资源时,能直接从缓冲区获取并返回,提高访问速度
  • 隐藏客户端信息:正向代理能够隐藏客户端的真实 IP 和其他信息,保护客户端的隐私
  • 网络爬虫:通过设置代理服务器,爬取目标网站的数据

反向代理:客户端发起请求到代理服务器,代理服务器将请求转发到内部服务器,获取到服务器的响应并返回给客户端。代理的对象是服务器

使用场景:

  • 负载均衡:反向代理可以将客户端的请求分发到多台服务器上,实现负载均衡
  • 缓存加速:反向代理通过缓存服务器上的静态资源,例如页面、图片和文件等,加速网站的访问速度
  • 安全防护:反向代理可以在客户端和服务器之间进行安全过滤,如过滤恶意攻击、限制外部访问等,保护服务器的安全

使用 Nginx 做反向代理:

  1. 安装 Nginx 服务器
  2. 修改 nginx.conf 配置文件
http {
    server {
        listen 80;
        server_name  localhost; 
        location / {
            proxy_pass http://backend;  
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }
    # 实现负载均衡
    upstream backend {
        server 127.0.0.1:8081;
        server 127.0.0.1:8082;
    }
}
  • listen :指定监听端口
  • server_name:指定监听地址
  • location:指定请求的路径
  • proxy_pass :指定目标服务器
  • proxy_set_header :指定传递给目标服务器的请求头信息,比如 Host,X-Real-IP,X-Forwarded-For 等,用来获取客户端的真实 IP
  1. 重启 Nginx 服务

在上面的例子中,当客户端访问 http://localhost/(没加端口时默认是 80 端口),会采用轮询的机制将请求转发到 127.0.0.1:8081 和 127.0.0.1:8082 上,然后将结果返回给客户端

题目三

什么是 Git 的 fork 命令?它和 clone 命令有什么区别?

官方解析

实际上,Git 本身并没有一个名为 fork 的命令。Fork 是一种在代码托管平台(如GitHub、GitLab等)上进行协作开发的概念。

Fork 操作的本质是复制一个仓库到自己的账户下,这样你就能在自己的仓库中进行修改,而不影响原始仓库。当你对自己仓库中的代码进行了修改,并希望将这些修改合并到原始仓库时,可以发起一个Pull Request。仓库的所有者可以审核你的修改,并选择是否将其合并到原始仓库中。

git clone命令是一个Git命令,用于将远程仓库克隆到本地计算机上。当你克隆一个仓库时,Git会将远程仓库的所有提交历史、分支和标签下载到本地。这样你就可以在本地进行开发、修改和提交操作。

Fork和Clone的区别如下:

  1. 操作层面:Fork是在代码托管平台上进行的操作,它会在你的账户下创建一个新的仓库,与原始仓库相互独立。而Clone是在本地计算机上进行的操作,用于将远程仓库的内容复制到本地。
  2. 目的:Fork主要用于协作开发,它让你可以在自己的仓库中进行修改,然后通过Pull Request将修改提交给原始仓库。而Clone用于将远程仓库的内容下载到本地,以便你可以在本地进行开发和修改。
  3. 权限:Fork操作不需要原始仓库的写权限,只需要读权限。而Clone操作通常需要在本地提交修改后,将修改推送到远程仓库。这可能需要原始仓库的写权限(除非你在自己Fork的仓库中进行开发)。

总之,Fork和Clone是两个不同层面的操作,它们在协作开发和版本管理中扮演不同的角色。在实际应用中,你可能需要同时使用Fork和Clone来进行协作开发。例如,在GitHub上,你可以先Fork一个仓库到自己的账户下,然后使用git clone命令将Fork的仓库克隆到本地进行开发。

鱼友的精彩回答

having 的回答

fork

fork,英语翻译过来就是叉子,动词形式则是分叉,如下图,从左到右,一条直线变成多条直线

转到 git 仓库中,fork 则可以代表分叉、克隆 出一个(仓库的)新拷贝

包含了原来的仓库(即 upstream repository,上游仓库)所有内容,如分支、Tag、提交

如果想将你的修改合并到原项目中时,可以通过的 Pull Request 把你的提交贡献回 原仓库

clone

clone,译为克隆,它的作用是将文件从远程代码仓下载到本地,从而形成一个本地代码仓

执行clone命令后,会在当前目录下创建一个名为xxx的目录,并在这个目录下初始化一个 .git 文件夹,然后从中读取最新版本的文件的拷贝

默认配置下远程 Git 仓库中的每一个文件的每一个版本都将被拉取下来

当你在github发现感兴趣开源项目的时候,可以通过点击github仓库中右上角fork标识的按钮,点击这个操作后会将这个仓库的文件、提交历史、issues和其余东西的仓库复制到自己的github仓库中,而你本地仓库是不会存在任何更改

然后你就可以通过git clone对你这个复制的远程仓库进行克隆

后续更改任何东西都可以在本地完成,如git add、git commit一系列的操作,然后通过push命令推到自己的远程仓库

如果希望对方接受你的修改,可以通过发送pull requests给对方,如果对方接受。则会将你的修改内容更新到仓库中

  • fork 只能对代码仓进行操作,且 fork 不属于 git 的命令,通常用于代码仓托管平台的一种“操作”
  • clone 是 git 的一种命令,它的作用是将文件从远程代码仓下载到本地,从而形成一个本地代码仓
  • branch 特征与 fork 很类似,fork 得到的是一个新的、自己的代码仓,而 branch 得到的是一个代码仓的一个新分支

HeiHei 的回答

Fork是GitHub操作,用于在远程仓库中创建一个副本,以便其他人可以基于该副本进行修改和贡献。通常,我们使用fork命令在GitHub或其他Git托管服务上创建一个公共仓库的个人分支,以便我们可以在其中进行自己的修改和实验,而不影响公共仓库的稳定性和安全性。

与fork命令相比,clone命令则是将远程仓库中的代码复制到本地机器上,以便我们可以在本地对代码进行修改和测试,而不需要连接到远程仓库。clone命令将整个仓库的历史记录、分支和标签都复制到本地,使得我们可以在本地完全重现远程仓库的状态。

因此,fork和clone命令之间的最大区别在于它们的操作目标。fork命令用于在远程仓库中创建个人分支,以便多人协作开发,而clone命令则用于将远程仓库复制到本地,以便在本地进行修改和测试。

前端

题目一

Node.js 有哪些全局对象?它们分别有什么作用?

官方解析

Node.js 中有一些全局对象,它们可以在任何模块中直接访问,无需进行导入。以下是一些常见的全局对象及其作用:

  1. global:它是 Node.js 的全局命名空间,类似于浏览器环境中的 window 对象。在 global 对象上定义的属性和方法可以在任何地方访问。然而,在实际开发中,应避免在 global 对象上添加属性,以防止全局命名空间污染。
  2. process:它是一个全局对象,提供了关于当前 Node.js 进程的信息和对其进行控制的方法。process 对象包含诸如环境变量、命令行参数、内存使用情况、当前工作目录等属性和方法。
  3. console:它是一个全局对象,提供了用于输出信息和调试的方法,如 console.log()、console.error()、console.warn() 等。
  4. setTimeout 和 clearTimeout:这两个方法用于设置和清除定时器。setTimeout 方法用于在指定的毫秒数后执行一个回调函数,clearTimeout 方法用于取消一个先前通过 setTimeout 设置的定时器。
  5. setInterval 和 clearInterval:这两个方法用于设置和清除周期性定时器。setInterval 方法用于每隔指定的毫秒数执行一个回调函数,clearInterval 方法用于取消一个先前通过 setInterval 设置的定时器。
  6. setImmediate 和 clearImmediate:这两个方法用于在当前事件循环结束时执行一个回调函数。setImmediate 方法会将回调函数添加到事件循环的队列末尾,以便在当前事件循环的所有 I/O 事件和定时器事件处理完毕后执行。clearImmediate 方法用于取消一个先前通过 setImmediate 设置的回调函数。
  7. Buffer:它是一个全局的构造函数,用于处理二进制数据,如文件 I/O、网络 I/O 等。Buffer 提供了一系列方法来创建和操作字节缓冲区。
  8. require 和 module:require 是一个全局函数,用于导入其他模块。module 是一个全局对象,表示当前模块。每个 Node.js 文件都是一个模块,模块可以导出函数、对象或值,以便其他模块使用。

注意,虽然这些对象在全局范围内可用,但它们并非严格意义上的全局变量。在 Node.js 模块中,它们是模块作用域内的变量,这意味着在一个模块中定义的变量不会自动成为全局变量。

题目二

简述 TCP/IP 网络模型,分为几层?每层的职责和作用是什么?

官方解析

TCP/IP 网络模型(也称为互联网协议套件)是一种用于描述网络通信的概念模型。它分为四层,每层都有特定的职责和作用,它们分别是:

  1. 应用层(Application Layer):应用层负责处理与应用程序的通信和数据传输。它包括各种应用层协议,例如 HTTP、HTTPS、FTP、SMTP、IMAP、POP3、DNS 等。这些协议定义了客户端和服务器之间如何互相发送和接收数据。应用层的主要职责是为应用程序提供用户接口、数据传输以及数据封装和解封装。
  2. 传输层(Transport Layer):传输层主要负责在网络中进行端到端的可靠数据传输。它提供了两种主要的传输协议:TCP(传输控制协议)和 UDP(用户数据报协议)。TCP 提供了可靠、面向连接的数据传输,它可以确保数据在传输过程中不会丢失、重复或乱序。UDP 提供了不可靠、无连接的数据传输,它不能保证数据的传输质量,但传输速度更快,适用于实时通信等场景。
  3. 网络层(Internet Layer):网络层负责在不同网络之间进行数据包的路由和传输。它使用 IP(互联网协议)进行寻址和路由,将数据包从源主机传输到目的主机。网络层的主要职责包括:IP 地址分配、路由选择、分片和重组以及错误检测和处理。除了 IP 协议,网络层还包括其他协议,如 ICMP(互联网控制消息协议)和 IGMP(互联网组管理协议)。
  4. 链路层(Link Layer):链路层(又称网络接口层或数据链路层)负责在同一网络中进行数据帧的发送和接收。链路层的协议因网络硬件而异,如 Ethernet、Wi-Fi、PPP 等。链路层的主要职责包括:物理寻址、数据帧封装和解封装、差错检测、流量控制以及链路管理。

总的来说,TCP/IP 网络模型将网络通信划分为四个层次,每层都有自己的职责和功能。这种分层模型有助于降低网络系统的复杂性,便于设计、实现和维护网络协议和设备。

鱼友的精彩回答

luckythus 的回答

简述 TCP/IP 网络模型,分为几层?每层的职责和作用是什么?
  1. 应用层:应用层为用户提供网络服务,应用层的任务是通过应用程序完成特定的网络功能。应用层负责处理与应用程序的通信和数据传输,它包括多种应用层协议,如 HTTP、FTP、DNS 等。这些协议定义了客户端和服务器之间如何互相发送和接收数据的交互规范。例如向服务器发送 HTTP 请求,或从 DNS 服务器获取 IP 地址等。为应用程序提供用户接口、数据传输以及数据封装和解析封装。
  2. 传输层:传输层主要负责提供端到端的数据传输服务,包括 TCP 和 UDP 协议。TCP 提供面向连接、可靠的数据传输服务,而 UDP 则提供无连接、不可靠的数据传输服务。传输层的主要任务是保证数据的可靠性,实现数据的分段和重组,并且确保数据按照正确的顺序到达目的地。
  3. 网络层:网络层负责在不同网络之间进行数据包的路由和传输。它使用 IP(互联网协议)进行寻址和路由,将数据包从源主机传输到目的主机。其中包括IP地址的分配、路由选择、分组传输和拥塞控制等功能。
  4. 数据链路层:数据链路层主要负责在物理层上传输数据。它将网络层传输的数据进行分帧,并添加了物理地址(MAC 地址)以及校验和等信息,使其可以在物理层上传输。

它们之间的具体过程是这样:

发送方:

  • 应用层:应用层向下传输报文,报文中包含应用层自己的报头和应用层的数据。
  • 传输层:传输层接收到应用层的报文,将应用层报文封装成一个或多个数据段,同时添加传输层的报头信息,例如 TCP 的源端口和目标端口号等。
  • 网络层:网络层接收到传输层的数据段,将数据段打包成 IP 数据包,同时添加网络层的报头信息,例如源 IP 地址和目标 IP 地址等。
  • 数据链路层:数据链路层接收到 IP 数据包,将其封装成数据帧,同时添加数据链路层的报头信息,例如源 MAC 地址和目标 MAC 地址等。
  • 物理层:物理层接收到数据帧,将其转换为 0 和 1 的电信号,通过物理介质传输到接收方,接收方的物理层将电信号转换为数据帧。

接收方:接收方也会按照相反的顺序层层解析报文。

  • 物理层:物理层传来的 0 和 1 的电信号,并将其转换为数据帧。
  • 数据链路层:会解析数据帧中的报头信息,剥离数据链路层的报头信息,并将剩余的数据包交给网络层。
  • 网络层:解析数据包中的报头信息,剥离网络层的报头信息,并将剩余的数据段交给传输层。
  • 传输层:解析数据段中的报头信息,剥离传输层的报头信息,并将剩余的数据段重组成完整的数据,并交给应用层。
  • 应用层:解析数据中的应用层报文,并进行处理和响应。

整个接收过程与发送过程类似,但是在每一层都需要进行不同的处理,以确保数据能够被正确地接收、还原和处理。

Kristen 的回答

TCP/IP模型

协议(protocol)是规定网络中双方通信方法的规则。TCP/IP是一个泛指,包括了TCP,UDP,IP,FTP,HTTP,ICMP,SMTP 等协议。

TCP/IP从上往下共分为四层模型,分别是:链路层:负责封装和解封装IP报文,发送和接受ARP/RARP报文等。

网络层:负责路由以及把分组报文发送给目标网络或主机。

传输层:负责对报文进行分组和重组,并以TCP或UDP协议格式封装报文。

应用层:负责向用户提供应用程序,比如HTTP、FTP、Telnet、DNS、SMTP等。

数据在发送端经过各层时都会通过附加协议头(经过数据链路层还会附加协议尾)进行封装,以标识对应层所用的通信协议。

题目三

git stash 命令有什么作用?什么时候适合用它?

官方解析

git stash 命令用于临时保存当前工作区的修改,以便你可以在干净的工作区上执行其他操作,如切换分支、拉取更新等。当你完成其他操作后,可以使用 git stash apply 或 git stash pop 将之前保存的修改重新应用到工作区。

git stash 在以下场景中非常有用:

  1. 当你正在进行一项尚未完成的任务,但需要切换到其他分支处理紧急问题或更新时。你可以使用 git stash 临时保存当前修改,然后切换分支并处理其他任务。完成后,切换回原来的分支,并使用 git stash apply 或 git stash pop 恢复之前的修改,继续完成未完成的任务。
  2. 当你需要拉取远程仓库的更新,但当前工作区有未提交的修改时。使用 git stash 保存当前修改,拉取远程更新,然后使用 git stash apply 或 git stash pop 恢复修改。

以下是一些常用的 git stash 子命令:

  • git stash save [message]:将当前工作区的修改保存到一个新的存储,并可以添加一个可选的描述信息。
  • git stash list:列出所有的存储。
  • git stash apply [stash_name]:将指定的存储应用到当前工作区,不删除存储。如果未指定存储名,则默认应用最近的存储。
  • git stash pop [stash_name]:将指定的存储应用到当前工作区,并从存储列表中删除。如果未指定存储名,则默认应用并删除最近的存储。
  • git stash drop [stash_name]:删除指定的存储。如果未指定存储名,则默认删除最近的存储。
  • git stash branch <branch_name> [stash_name]:基于指定存储创建一个新分支,并将存储应用到新分支。如果未指定存储名,则默认使用最近的存储。
  • git stash clear:删除所有的存储。

总之,git stash 是一个非常有用的命令,用于临时保存工作区的修改,以便在干净的工作区上执行其他操作。在处理紧急任务、更新代码或切换分支时,git stash 都可以帮助你轻松管理工作区的状态。

鱼友的精彩回答

九仞的回答

在切换分支时,假设我们已经对分支代码做了更改,但并不想提交 commit,此时切换到其他分支可能会把对当前分支的修改带到其他分支去,或者直接丢失更改,这也许不是我们想要的效果。git stash 命令对应的使用场景就是这种情况。他允许我们临时保存当前工作去的修改,然后以干净的工作区切换到另一分支进行其他修改,等修改完毕后切换回原分支时也能快去恢复之前的修改。

useGieGie 的回答

git stash 命令的作用是将当前工作目录中的修改暂时保存起来,以便在需要时可以重新应用这些修改。使用 git stash 命令可以避免在切换分支或者回滚代码时丢失未提交的修改。

适合使用 git stash 命令的情况包括:

  1. 当你需要切换到其他分支进行开发,但是当前分支中还有未提交的修改时,可以使用 git stash 命令将这些修改暂时保存起来,然后切换到其他分支进行开发。
  2. 当你需要回滚代码到之前的某个版本时,但是当前工作目录中还有未提交的修改时,可以使用 git stash 命令将这些修改暂时保存起来,然后回滚代码到指定的版本。
  3. 当你需要进行一些临时的修改,但是不想将这些修改提交到版本库中时,可以使用 git stash 命令将这些修改暂时保存起来,然后在需要时再重新应用这些修改。

适合使用 git stash 命令的场景包括:

  1. 当你正在进行某些修改,但需要切换到其他分支或者处理其他任务时,可以使用 git stash 命令将当前的修改暂存起来,以免对其他任务造成干扰。

  2. 当你在处理某个 bug 或者其他问题时,需要暂时回到上一个提交状态进行一些测试或者比较代码时,可以使用 git stash 命令将当前修改暂存起来,以便稍后恢复。需要注意的是,git stash 命令只能将未提交的修改暂存起来,如果已经提交了修改,则无法使用该命令。另外,使用 git stash 命令时需要注意保存的修改内容,以免丢失重要的修改。


星球活动

1.欢迎参与 30 天面试题挑战活动 ,搞定高频面试题,斩杀面试官!

2.欢迎已加入星球的同学 免费申请一年编程导航网站会员 !

3.欢迎学习 鱼皮最新原创项目教程,手把手教你做出项目、写出高分简历!

加入我们

欢迎加入鱼皮的编程导航知识星球,鱼皮会 1 对 1 回答您的问题、直播带你做出项目、为你定制学习计划和求职指导,还能获取海量编程学习资源,和上万名学编程的同学共享知识、交流进步。

💎 加入星球后,您可以:

1)添加鱼皮本人微信,向他 1 对 1 提问,帮您解决问题、告别迷茫!点击了解详情

2)获取海量编程知识和资源,包括:3000+ 鱼皮的编程答疑和求职指导、原创编程学习路线、几十万字的编程学习知识库、几十 T 编程学习资源、500+ 精华帖等!点击了解详情

3)找鱼皮咨询求职建议和优化简历,次数不限!点击了解详情

4)鱼皮直播从 0 到 1 带大家做出项目,已有 50+ 直播、完结 3 套项目、10+ 项目分享,帮您掌握独立开发项目的能力、丰富简历!点击了解详情

外面一套项目课就上千元了,而星球内所有项目都有指导答疑,轻松解决问题

星球提供的所有服务,都是为了帮您更好地学编程、找到理想的工作。诚挚地欢迎您的加入,这可能是最好的学习机会,也是最值得的一笔投资!

长按扫码领优惠券加入,也可以添加微信 yupi1085 咨询星球(备注“想加星球”):

往期推荐

编程导航,火了!

JS 会出现内存泄漏问题么?

什么是 AOP?

什么是注册中心?

Spring 支持哪几种事务管理类型?

什么是 Bean 的生命周期?





继续滑动看下一个
向上滑动看下一个

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存