• 第三次线上面试总结(2022.9.15 二面)


    2022年9月15号 第三次线上面试(二面)

    面试题总结

    1.CDN原理?

    CDN的全称是Content Delivery Network,即内容分发网络。CDN是构建在现有网络基础之上的智能虚拟网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。CDN的关键技术主要有内容存储和分发技术。

    CDN的技术原理:

    1、用户向浏览器提供要访问网站的域名,域名解析的请求被发往本地用户使用的DNS服务器,本地DNS服务器将解析请求转发至网站的DNS服务器。

    2、由于网站的DNS服务器对此域名的解析设置了CNAME,请求最终被指向到CDN网络中的GLB系统。

    3、GLB系统对域名进行智能解析,将响应速度最快的节点IP返回给用户。

    4、浏览器在得到实际的IP地址以后,向CDN节点发出访问请求。

    5、由于是第一次访问,CDN节点将回到源站获得用户请求的数据并发给用户,同时CDN节点根据缓存策略对该数据进行缓存。

    6、当有其他用户再次访问同样内容时,CDN节点直接将数据返回给客户,完成请求/服务过程。

    影响CDN加速效果的因素:

    1.CDN主要是靠把网站内容缓存到各个节点服务器,不同地区的访问者可以就近访问,起到加速的效果。所以,理论上来讲:你网站里被缓存的内容越多,效果就越好。

    2.当用户访问一些不能缓存的内容时,CDN节点会临时去你源站获取,此时,如果到你源站的链路不好的话,就会导致这个过程很慢。所以,你源站链路状况也是比较重要的。

    3.还是跟CDN的服务质量有关。包括它的智能调度、CDN节点链路状况等。

    2.为什么使用Docker?

    1.环境隔离
    通过cgroups和namesapce进行实现资源隔离,实现一台机器运行多个容器互不影响。

    2.更快速的交付部署
    使用docker,开发人员可以利用镜像快速构建一套标准的研发环境,开发完成后,测试和运维人员可以直接通过使用相同的环境来部署代码。Docker可以快速创建和删除容器,实现快速迭代,大量节约开发、测试、部署的时间。并且,各个步骤都有明确的配置和操作,整个过程全程公司内文档说明,使团队更容易理解应用创建和工作的过程。

    3.更高效的资源利用
    Docker容器的运行不需要额外的虚拟化管理程序的支持,它是内核级的虚拟化,可以实现更高的性能,同时对资源的额外需求很低。

    4.更易迁移扩展
    Docker容器几乎可以在任意的平台上运行,包括乌力吉、虚拟机、公有云、私有云、个人电脑、服务器等,这种兼容性让用户可以在不同平台之间轻松的迁移应用。

    5.更简单的更新管理
    使用Dockerfile,只需要小小的配置修改,就可以替代以往的大量的更新工作。并且所有修改都是以增量的方式进行分发和更新,从而实现自动化和高效的容器管理。

    3.Docker镜像和容器之间的关系?

    容器是镜像的实例,先描述镜像,再创建容器,所以容器可以有多个。镜像是一个只读的文件系统,在本地会共用,主要是通过签名来实现的,类似于存储里面的De-dup技术。

    每运行一个容器,会在镜像上加一个可写层,但这一层并不会改变镜像本身,这也就是为什么有时候你用同一个镜像启动多个容器,里面的内容是不会变的。如果你要将可写层持久化,就要通过 commit命令来把这个可写层写到磁盘上,即生成新的镜像。

    总的来说,镜像是文件, 容器是进程。容器是基于镜像创建的,即容器中的进程依赖于镜像中的文件,这里的文件包括进程运行所需要的可执行文件、依赖软件、库文件、配置文件等等。

    4.反向代理跟正向代理的区别是什么?

    一、正向代理:
    当用户想访问某一网址时,用户先访问代理服务器,然后由代理服务器向目标网址发送请求最终将数据返回代理服务器,最后代理服务器将数据返回给用户这一过程我们称之为正向代理。
    正向代理它代理了客户端,相当于代理服务器去访问目标网址。

    特点:
    1、隐藏用户真实地址信息。因为代理服务器相当于客户端,所以与目标网站直接交互的是代理服务器而非用户。

    2、突破IP访问限制。使公司内部搭建的局域网链接互联网。

    3、提高访问速度。代理服务器提供了一个很大的缓冲区将部分请求的响应保存到缓冲区中,当其他用户再访问相同的信息时, 则直接由缓冲区中取出信息,传给用户,以提高访问速度。

    二、反向代理:
    基本流程是与正向代理是相同的,都是通过用户发送请求 -->代理服务器–>目标服务器。但是二者的区别在于正向代理时用户知道自己访问的是代理服务器,而反向代理是无感知的,用户本质上是不知道自己访问的是代理服务器。
    反向代理它代理了目标服务器,让客户感觉自己实际上是在和目标服务器本身进行交互。

    特点:
    1、负载均衡。反向代理服务器相当于一个服务站,当接收到请求时根据负载情况将请求发送到不同的服务器上。

    2、提高内部服务器的安全。正向代理中代理服务器相当于用户,所以隐藏了真实用户的地址信息,而反向代理代理了实际的服务器,所以隐藏了真实服务器的信息,用户实际是在和代理服务器交互而不是目标服务器本身。反向代理服务器相当于应用级防火墙,所以检查十分严格。

    3、提高访问速度。反向代理服务器对于静态内容及短时间内有大量访问请求的动态内容提供缓存服务,提高访问速度。

    三、正向和反向代理的区别:

    1、正向代理实际代理的是客户端。反向代理代理的是目标服务器。

    2、正向代理是客户端架构,而反向代理是服务器架构。

    3、正向代理中,服务器不知道真正的用户是谁。反向代理中,用户不知道真正的服务器是谁。

    4、正向代理主要用来解决访问问题。反向代理主要用于解决负载均衡、安全防护,但二者都能提高访问速度。

    5.为什么不使用Select *?

    1.增加查询分析器解析成本。
    2.无用字段增加网络消耗,尤其是text类型的字段。
    3.无法使用索引覆盖,导致回表。

    6.使用Select *,会导致索引失效吗?

    select * 走不走索引,关键取决于 where 后面是否包括有效的索引字段,和 select * 没有关系,select * 最大的影响就是额外的 IO 开销。

    select * 走不走索引与结果集大小无关,而应该和结果集数量有关。

    查询的结果集,超过了总行数 25%,优化器就会认为没有必要走索引了,导致索引失效。

    7.哪些情况会导致索引失效?

    1.索引列参使用了函数
    2.错误的Like使用
    3.类型隐式转换
    4.使用OR操作
    5.不等于比较
    6.is not null
    7.not in和not exists
    8.联合索引不满足最左匹配原则
    9.使用了select *
    10.索引列参与运算
    11.两列做比较
    12.其他
    这里要说的其他:Mysql优化器的其他优化策略,比如优化器认为在某些情况下,全表扫描比走索引快,则它就会放弃索引。

    8.描述API接口幂等性?

    幂等性原本是数学上的概念,用在接口上就可以理解为:同一个接口,多次发出同一个请求,必须保证操作只执行一次。
    调用接口发生异常并且重复尝试时,总是会造成系统所无法承受的损失,所以必须阻止这种现象的发生。
    实际上,我们常用的 HTTP 协议的方法是具有幂等性语义要求的,比如:get 方法用于获取资源,不应有副作用,因此是幂等的。post 方法用于创建资源,每次请求都会产生新的资源,因此不具备幂等性。put 方法用于更新资源,是幂等的。delete 方法用于删除资源,也是幂等的。
    比如下面这些情况,如果没有实现接口幂等性会有很严重的后果:
    支付接口,重复支付会导致多次扣钱
    订单接口,同一个订单可能会多次创建。

    9.怎么确保幂等性?

    1.唯一索引
    使用唯一索引可以避免脏数据的添加,当插入重复数据时数据库会抛异常,保证了数据的唯一性。

    2.乐观锁
    这里的乐观锁指的是用乐观锁的原理去实现,为数据字段增加一个version字段,当数据需要更新时,先去数据库里获取此时的version版本号。更新数据时首先和版本号作对比,如果不相等说明已经有其他的请求去更新数据了,提示更新失败。

    3.悲观锁
    乐观锁可以实现的往往用悲观锁也能实现,在获取数据时进行加锁,当同时有多个重复请求时其他请求都无法进行操作。

    4.分布式锁
    幂等的本质是分布式锁的问题,分布式锁正常可以通过redis或zookeeper实现。在分布式环境下,锁定全局唯一资源,使请求串行化,实际表现为互斥锁,防止重复,解决幂等。

    5.Token机制
    客户端每次在调用接口的时候,需要在请求头中,传递令牌参数,每次令牌只能用一次。
    一旦使用之后,就会被删除,这样可以有效防止重复提交。Token机制的应用十分广泛。

    10.描述http和https的区别?

    1.HTTP 明文传输,数据都是未加密的,安全性较差,HTTPS(SSL+HTTP) 数据传输过程是加密的,安全性较好。

    2.使用 HTTPS 协议需要到 CA(Certificate Authority,数字证书认证机构) 申请证书,一般免费证书较少,因而需要一定费用。证书颁发机构如:Symantec、Comodo、GoDaddy 和 GlobalSign 等。

    3.HTTP 页面响应速度比 HTTPS 快,主要是因为 HTTP 使用 TCP 三次握手建立连接,客户端和服务器需要交换 3 个包,而 HTTPS除了 TCP 的三个包,还要加上 SSL 握手需要的 9 个包,所以一共是 12 个包。

    4.HTTP 和 HTTPS 使用的是完全不同的连接方式,用的端口也不一样,前者是 80,后者是 443。

    5.HTTPS 其实就是建构在 SSL/TLS 之上的 HTTP 协议,所以 HTTPS 比 HTTP 要更耗费服务器资源。

    11.https的加密过程?

    三种加密方式:
    对称加密
    非对称加密
    混合加密

    HTTPS采用的就是对称加密和非对称加密的混合加密方法。

    1.混合加密解决了信息的机密性,防止数据被窃听。
    2.摘要算法实现了数据的完成性,防止了数据被篡改。
    3.数字证书提供了身份验证,防止了被冒充风险。
    
    • 1
    • 2
    • 3

    12.http1.1默认开启了长连接,长连接指的是什么?

    在 HTTP/1.0 中,默认使用的是短连接。也就是说,浏览器和服务器每进行一次 HTTP 操作,就建立一次连接,但任务结束就中断连接。如果客户端浏览器访问的某个 HTML 或其他类型的 Web 页中包含有其他的 Web 资源,如JavaScript 文件、图像文件、CSS 文件等。当浏览器每遇到这样一个 Web 资源,就会建立一个 HTTP 会话。

    但从 HTTP/1.1 起,默认使用长连接,用以保持连接特性。使用长连接的 HTTP 协议,会在响应头有加入这行代码:

    Connection:keep-alive
    
    • 1

    在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输 HTTP 数据的 TCP 连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。Keep-Alive 不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如 Apache )中设定这个时间。实现长连接要客户端和服务端都支持长连接。

    HTTP 协议的长连接和短连接,实质上是 TCP 协议的长连接和短连接。

    13.Cookie和Session的区别?

    HTTP Cookie,也可以称作浏览器 Cookie,是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。通常,它用于告知服务端两个请求是否来自同一浏览器,如保持用户的登录状态。Cookie 使基于无状态的 HTTP 协议记录稳定的状态信息成为了可能。

    Cookie 主要用于以下三个方面:

    会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
    个性化设置(如用户自定义设置、主题等)
    浏览器行为跟踪(如跟踪分析用户行为等)
    
    • 1
    • 2
    • 3

    Session 代表着服务器和客户端一次会话的过程。Session 对象存储:特定用户会话所需的属性及配置信息。这样,当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当客户端关闭会话,或者 Session 超时失效时会话结束。

    Cookie 和 Session 的不同之处:
    1 作用范围不同,Cookie 保存在客户端(浏览器),Session 保存在服务器端。

    2 存取方式的不同,Cookie 只能保存 ASCII,Session 可以存任意数据类型,一般情况下我们可以在 Session 中保持一些常用变量信息,比如说 UserId 等。

    3 有效期不同,Cookie 可设置为长时间保持,比如我们经常使用的默认登录功能,Session 一般失效时间较短,客户端关闭或者 Session 超时都会失效。

    4 隐私策略不同,Cookie 存储在客户端,比较容易遭到不法获取,早期有人将用户的登录名和密码存储在 Cookie 中导致信息被窃取。Session 存储在服务端,安全性相对 Cookie 要好一些。

    5 存储大小不同, 单个 Cookie 保存的数据不能超过 4K,Session 可存储数据远高于 Cookie。

    14.JS怎么使用数组模拟队列?

    在JavaScript中实现队列和数组主要是通过数组,js数组中提供了以下几个方法可以让我们很方便实现队列和堆栈:

    shift:从数组中把第一个元素删除,并返回这个元素的值。
    unshift: 在数组的开头添加一个或更多元素,并返回新的长度
    push:在数组的中末尾添加元素,并返回新的长度
    pop:从数组中把最后一个元素删除,并返回这个元素的值。
    
    • 1
    • 2
    • 3
    • 4

    实现队列:

     1 <script type="text/javascript">
     2         //创建一个数组来模拟队列
     3         var a=new Array();
     4         console.log(a);
     5         //unshift: 在数组的开头添加一个或更多元素,并返回新的长度
     6         console.log("入队");
     7         a.unshift(1)
     8         console.log(a);//----->1
     9         a.unshift(2);
    10         console.log(a);//----->2,1
    11         a.unshift(3);
    12         console.log(a);//----->3,2,1
    13         a.unshift(4);
    14         console.log(a);//----->4,3,2,1
    15         console.log("出队,先进先出");
    16         console.log(a);
    17         //pop:从数组中把最后一个元素删除,并返回这个元素的值
    18         a.pop();//----->1
    19         console.log(a);
    20         a.pop();//----->2
    21         console.log(a);
    22         a.pop();//----->3
    23         console.log(a);
    24         a.pop();//----->4
    25         console.log(a);
    26 </script>
    
    • 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

    实现堆栈:

    1 <script type="text/javascript">
     2         //创建一个数组来模拟堆栈
     3         var a=new Array();
     4         console.log(a);
     5         //push: 在数组的末尾添加一个或更多元素,并返回新的长度
     6         console.log("入栈");
     7         a.push(1)
     8         console.log(a);//----->1
     9         a.push(2);
    10         console.log(a);//----->1,2
    11         a.push(3);
    12         console.log(a);//----->1,2,3
    13         a.push(4);
    14         console.log(a);//----->1,2,3,4
    15         console.log("出栈,后进先出");
    16         console.log(a);
    17         //pop:从数组中把最后一个元素删除,并返回这个元素的值
    18         a.pop();//----->4
    19         console.log(a);
    20         a.pop();//----->3
    21         console.log(a);
    22         a.pop();//----->2
    23         console.log(a);
    24         a.pop();//----->1
    25         console.log(a);
    26 </script>
    
    • 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

    15.数组跟链表的区别?

    数组的定义:
    数组(Array)是有序的元素序列。 若将有限个类型相同的变量的集合命名,那么这个名称为数组名。组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量。用于区分数组的各个元素的数字编号称为下标。数组是在程序设计中,为了处理方便, 把具有相同类型的若干元素按有序的形式组织起来的一种形式。 这些有序排列的同类数据元素的集合称为数组。
    数组是用于储存多个相同类型数据的集合。

    数组的特性:

    数组分配在内存上要求必须是连续的
    数组在在创建时要申请创建的内存大小,如果使用量很小,就会造成内存的浪费。
    插入或删除的效率低,由于要求内存上是连续的,所以添加或删除的元素后面的所有元素都要移动。
    数组的读取效率非常高,因为是连续的,所以能知道每个元素在内存上的位置。
    
    • 1
    • 2
    • 3
    • 4

    链表的定义:
    链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。 相比于线性表顺序结构,操作复杂。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而线性表和顺序表相应的时间复杂度分别是O(logn)和O(1)。

    链表的特性:

    链表分配在内存上可以使非连续,非顺序的 每个元素都记录着它下一个元素的地址,双向链表每个元素记录着他的上一个元素和下一个元素。
    
    插入或删除效率高,如:原先AC是一个链表结构,这时要在AC中间插入元素B,他(B)只要在元素(A)拿到下一个元素(C)的地址,
    让元素A记录自己B为下一个元素,B记录C为它的下一个元素即可完成链表。
    
    链表查询效率低,因为在地址上是不连续的,只能从标的第一个元素一个一个的往下找。
    
    不用提前申请链表的大小
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    16.Linux常用命令?

    reboot  //重启
    pwd   //显示当前工作目录
    mkdir handsome  //创建工作目录
    cd handsome  //更改工作目录
    cd ..  //返回上一级
    touch handsome  //创建文件
    mv myfile mydir  //移动目录或文件
    cp myfile myfir  //复制目录或文件
    rm -rf handsome  //删除目录或文件
    ls //列出所有文件和目录
    cat -n handsome //查看文件
    chmod [u/g/o/a][+/-/=][r/w/x] handsome  //更改文件权限
    head (-10) handsome  //指定显示文件前若干行(默认前10)
    tail (-10) handsome  //指定显示文件后若干行(默认后10)
    clear  //清楚屏幕信息
    echo xx  //显示文本  x=0  echo $x . echo -e \$x . echo $(pwd)
    date  //显示日期和时间(+%y 年  +%m 月  +%d日)
    cal  //显示当前日期  cal -y
    ps  //查看当前进程  -A(所有)  U  lilei (用户lilei)
    kill -9 6666  //终止某一进程  
    ps -ef | grep java  //查看进程  
    sudo adduser handsome sudo  //给普通用户赋予root权限
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    17.Linux下怎么修改文件权限?

        -rw------- (600)      只有拥有者有读写权限。
        -rw-r--r-- (644)      只有拥有者有读写权限;而属组用户和其他用户只有读权限。
        -rwx------ (700)     只有拥有者有读、写、执行权限。
        -rwxr-xr-x (755)    拥有者有读、写、执行权限;而属组用户和其他用户只有读、执行权限。
        -rwx--x--x (711)    拥有者有读、写、执行权限;而属组用户和其他用户只有执行权限。
        -rw-rw-rw- (666)   所有用户都有文件读、写权限。
        -rwxrwxrwx (777)  所有用户都有读、写、执行权限。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    修改单个文件名:

    chmod 777 文件名
    
    • 1

    修改某路径下的文件权限:

    chmod -R 777 路径(文件夹的路径)
    
    • 1

    18.Linux下怎么查看进程?

    1、ps命令——查看静态的进程统计信息(Processes Statistic)

    常见的选项:

    a:显示当前终端下的所有进程信息,包括其他用户的进程。
    
    u:使用以用户为主的格式输出进程信息。
    
    x:显示当前用户在所有终端下的进程。
    
    -e:显示系统内的所有进程信息。
    
    -l:使用长(long)格式显示进程信息。
    
    -f:使用完整的(full)格式显示进程信息。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    2、top命令——查看进程动态信息

    以全屏交互式的界面显示进程排名,及时跟踪包括CPU、内存等系统资源占用情况,默认情况下每三秒刷新一次,其作用基本类似于Windows系统中的任务管理器。

    3、pgrep命令——根据特定条件查询进程PID信息。

    4、pstree命令——查看进程树,以树形结构列出进程信息。

  • 相关阅读:
    JavaEE中的Lambda表达式与方法引用的使用
    C++ 多线程 Thread类
    NCO IP Core
    【10. 差分】
    在线教育项目【老师服务】
    C++ 数字
    浅谈如何更好的进行需求评审
    Flink 实践 | B站流式传输架构的前世今生
    静态资源映射
    【信号调理】ADC保护电路/ADC缓冲器
  • 原文地址:https://blog.csdn.net/weixin_59262008/article/details/126913748