0


weipai网络-面试回顾

本片章节:

  1. 介绍一下自己在实习期间的工作内容吧!
  2. 什么是四层代理、什么是七层代理?
  3. 介绍一下这个自己开发的上线项目吧!
  4. MySQL常用的字符集及字符序;
  5. 有没有遇到过慢SQL问题;
  6. 需要在性别或年龄上建立索引吗?
  7. 事务的隔离级别;
  8. tcp三四次握手;
  9. redis的数据类型;
  10. redisSorted_Set可以干什么;
  11. 五个数组如何找并集、交集;
  12. 跨域请求会不会到服务器那里;
  13. 二分查找;

1. 介绍一下自己在实习期间的工作内容吧!

  1. 在这实习了两个月左右。大致做了四个方面的内容,分别是 服务测试、代理配置、优化代码以及线上项目开发
  2. 服务测试:利用JMeter测试了小组开发的C++服务及利用PostMan测试了还未上线数据接口。输出了两份邮件、五份测试报告及五十多张结果截图;
  3. 代理配置:在进行线上项目开发时,组长给我了这样一个需求。为上线项目配置错误页面,因为当项目更新时要给用户一种良好的使用体验;
  4. 但是这个错误页面尽量不要放在项目中,单独做出来,复用一下。然后我就想到了Nginx来做这个需求;
  5. 后期由于用户需求的不断变更,组长又让我配置了负载均衡及传递用户IP的需求;
  6. 优化代码:团队开发了一个无人车巡逻的项目,组长在进行运维的时候给我提出了优化车辆巡逻模板的需求。因为初始的巡逻模板建立只能设置起点和终点,用户体验度不够;
  7. 然后我就从前端到后端整体完成了这个需求。难点在于设定中间点的次序问题及与算法的衔接部分;
  8. 项目开发:团队跟用户协商好了需求,说年后再进行项目开发。但后期时用户这边突然提出要看展示型项目。组长这边要求我在半个月之内做出一个演示项目。这其中涉及了 需求分析 数据库设定 设备协议设定 接口开发 设备联调 前端开发 打包部署 运维 这些工作内容;
  9. 核心功能是一个数据展示页面,虽然说项目总体难度不是很大,但是它是一个小而美的内容,让我学习到了小型项目的生命周期;

2. 什么是四层代理、什么是七层代理?

  1. 这个所谓的 四层、七层代理 是依据 网络模型 OSI 来划分的。OSI就是我们在计算机网络里面学的那个;
  2. 因为在OSI中,分为七层,从硬件到软件分别是:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层;
  3. 而四层的就是传输层,也就是说四层代理就是代理传输层,而七层代理就是代理应用层;
  4. 四层代理和七层代理的区别:
  5. 四层代理:
  6. 四层代理是在传输层的,此时的代理只起到了一种转发的作用,当它接收到用户的请求之后,它会把修改报文中的目的IP地址为真实服务器的IP地址;
  7. 因为在使用四层代理的时候,用户访问的目的IP地址其实是四层代理的IP,当四层代理接收到用户的请求之后,会把报文中目的地址改为真实服务器的IP地址;
  8. 这样的过程实际只建立了一个TCP连接。是用户和服务器间的TCP连接,这个TCP没有四层代理的踪迹;
  9. 有时候根据配置的不同,四层代理服务器接收到用户的请求之后,也会把源地址给改了,改为四层代理的IP地址,这是为了防止真实服务器接收到请求之后转发错误;
  10. 七层代理:
  11. 作用于七层代理的服务器我们也可以称之为反向代理服务器;
  12. 当我们使用七层代理进行配置时,它的工作流程是这样的:用户请求七层代理,七层代理代替用户去请求真实的服务器;
  13. 再细致一些就是,当用户请求七层代理的时候,七层代理会拿到请求体,然后依据这个请求体去访问真实的服务器,真实的服务器把数据返回给七层代理;
  14. 七层代理拿到这些返回数据之后会拼接为一个响应体,然后再返回给用户那里去展示;
  15. 这里可以和四层代理区分一下,四层只起转发作用,不会拼接数据包的内容,但是七层代理是把用户的请求直接拦在自己这里了,然后代替用户访问服务器,之后拼接数据包然后再返回到用户那里;
  16. 当在使用七层代理时,用户需要访问的真实服务器其实通常是一个服务器集群,但我们肯定会把这样的集群配置进行一些隐匿的;
  17. 此时通常就会使用到七层代理,当用户请求真实的服务器集群时,首先访问的是七层代理再由七层代理代替用户去访问真实的服务器,真实的服务器把响应的数据返回给七层代理,由七层代理再转发给用户那里去;
  18. 这样的一种工作过程会建立两个TCP连接分别是 用户 七层代理之间,七层代理 服务器集群之间;
  19. 同时,七层代理和四层代理进行服务代理时依据的条件是不同的;
  20. 四层代理:
  21. 因为它作用在传输层,所以进行服务代理时它根据 IP+PORT 的方式进行工作;
  22. 七层代理:
  23. 七层代理作用于应用层,它可以使用 HTTP协议 URL Cookie 请求体 中的内容,所以依据的方法比较多样;

3. 介绍一下这个自己开发的上线项目吧!

  1. 说一下核心模块:
  2. 核心模块分为两个部分,分别是设备端数据接收及数据处理并展示;
  3. 使用的技术的SpringBoot+Vue,数据库是MySQL
  4. 因为数据是由设备上传的,所以需要设定一份数据上报协议给设备开发人员。这是业务中比较特殊的部分;
  5. 之后就是拿设备上传的数据在页面中进行展示,数据分为数值型数据,还有GPS数据及图片数据;
  6. 图片直接放在了工程目录下,然后GPS使用到了百度地图的逆地址服务,因为这边使用的是WGS84这种经纬度格式;

4. MySQL常用的字符集及字符序

  1. 字符集:英文名字 character set ,它所代表的就是对于字符的编码形式。说到这里就必须要提到 GBK Unicode UTF-X ASCII
  2. 其中上面列举的每一个都是一个字符集,其中GBK就是国标的意思,可以把它理解为我们汉字的编码形式,也就是属于我们汉字的字符集(同时呢,它也是我们中国人自己做出来的 哈);
  3. Unicode也叫万国码,没错,它就是大一统的意思,使用它就可以包揽世界上几乎所有语言的字符编码形式;
  4. 但是呢,它类似于 OSI模型 ES6 一样,它们都是一种理论上的标准,实际上的产品落地通常会有落差,它的代表性产品就是UTF-X,所以说UTF-X具备万国码的特征,就是万金油,几乎所有的语言都可以使用它来作为自己的编码方式;
  5. 最后的就是ASCII了,它是美国做出来的字符集,所以说它只能编码那些 英文字母、特殊字符 ,因为英语文字中也只包含这些;
  6. 字符序:针对字符集而言,字符序没有那么多的开放性,它针对于字符的序列性,英文名字是 Collation
  7. 每一种字符集通常会有 1到多种的字符序,同时呢每两种字符集之间不会有共同的字符序。最后呢,每一种字符集都会有一个默认的字符序;
  8. 字符序描述的就是字符之间的排序规则,通常来说,字符序的命名会以 ci cs bin 来结尾;
  9. ci:不区分大小写;
  10. cs:区分大小写;
  11. bin:使用二进制进行排序,区分大小写;
  12. utf-8 来描述字符序,每一个字符序我们用一个SQL来理解:假设有一个表名为 user1 ,表中有俩字段,分别是 user_1_name user_1_age
  13. 假设它使用了如下几种字符序,会出现这样的结果:
  14. utf8_general_ciSELECT user_1_name , user_1_age FROM USER1 WHERE User_1_name ='LMJ';== SELECT user_1_name , user_1_age FROM USER1 WHERE User_1_name ='lmj';
  15. 这俩SQL的最大不同就是 WHERE User_1_name ='' 处,在 ci 中因为不区分大小写,所以 lmj == LMJ
  16. utf8_general_csSELECT user_1_name , user_1_age FROM USER1 WHERE User_1_name ='LMJ';!= SELECT user_1_name , user_1_age FROM USER1 WHERE User_1_name ='lmj';
  17. 而在 cs 中,LMJ != lmj ,所以最终的查询结果为空;
  18. utf8_binbin 因为是基于二进制进行排序,所以和 cs 结果一致;
  19. 但是哈,这三种方式各有优缺,比如 ci csbin 相比,ci 效率更快但是准确率低一些,而 csbin却恰恰相反。但最常用的是ci结尾;
  20. 解释一个小问题:
  21. 有些博客里面会说 ci csbin 的区别在于 假设字段名为 user_1_name 时,ci 可以使用 USER_1_NAME 或者 user_1_name ,但 csbin 只能使用 user_1_name
  22. 他们的意思是区分大小是在这里体现的,其实他们说的是错误的哈!!!
  23. MySQL 数据库在 windows 下是不区分大小写的,也就是说 select user_1_name from user == SELECT USER_1_NAME FROM USER
  24. 这是已知事实,但这个事实不是靠 cs ci bin 来决定的。而 cs ci bin 决定的是表里面的数据在进行写入和取出的时候是否会区分大小写(我建表实测过);

5. 有没有遇到过慢SQL问题

  1. 导致慢SQL的原因(通常就是索引失效):
  2. 1. 使用 like '%李%' ,这个时候即使 name 上有索引也不会生效,因为 % 在模糊匹配字符串的第一个字符时索引会失效;
  3. 2. 在使用联合索引时,没有使用联合索引的第一个字段作为条件。因为联合索引如果第一个字段没有作为条件就会失效;
  4. 解决方案:
  5. 1. 建立索引或者是优化SQL写法使索引生效;
  6. 2. 优化表结构,因为优质的表结构即可以节约空间也可以优化查询速度;
  7. 3. 减少表与表的连接次数,因为两表之间的连接都是笛卡尔积形式的暴增型对比次数增加;

6. 需要在性别或年龄上建立索引吗?

  1. 年龄上可以建立索引,但是性别上不能建立索引。因为重复率过高的字段建立索引查询效率反而会降低;
  2. 因为数据表通常分为两个文件,一个是数据文件一个索引文件,所以当我们访问索引的时候其实这是一次IO操作;
  3. 如果100万条记录中男女各有50万条,那显然在性别上建立索引是得不偿失的,因为50万次的IO操作会把这条SQL的速度降低到比没有建立索引时还慢;

7. 事务的隔离级别

  1. 事务:通常在我们的业务流程中DML都不是一条两条或三条,而是一捆。也就是说一个事务就是一捆DML
  2. 事务四特性:原子性、一致性、隔离性、持久性;
  3. 细究隔离性:
  4. 读未提交(read uncommited):事务A可以读取到事务B还未提交的数据;
  5. 造成的问题:脏读。读取到其他事务还未提交的数据;
  6. 实例:假设此时money(家庭共同财产)为10000元,程序猿小张(事务B)首先用8000元买了一台外星人,小红(小张的妻子,事务A)此时查询money时为2000
  7. 但是小张突然想把外星人换成败家之眼,所以就先退掉了这台外星人,然后回家了(事务提交了)。所以此时money10000元,但是小红此时认为money仍旧是2000元;
  8. 所以此时小张回到家莫名其妙的就迎来了自己的一顿搓衣板;
  9. 我们可以把这种错误理解为:脏读,解决方案是使用下一种事务隔离级别:读已提交;
  10. 读已提交(read commited);事务A只能读取到事务B已经提交的数据;
  11. 造成的问题:不可重复读。在一次事务过程中两次查询同一数据得到不同结果;
  12. 实例:昨晚跪完搓衣板之后,小张解释了一下便顺利调解了此事。第二天一早小张就去败家之眼旗舰店了,一进店门小张就被一台9000元的笔记本给吸引住了;
  13. (事务B开始)同时呢,小红不放心小张,小张出门后小红又查询了一下money,还是10000万元,小红就安心的去懒觉了;
  14. (事务A开始)一小时后,小张经过多方面的细致了解,以8500的价格顺利拿下了这台败家之眼。之后小张一看时间也快中午了,就直接回家了(事务A结束);
  15. 回到家后小红一看小张手提一台笔记本,然后她急忙又查询了一下money发现只有1500了,然后小红就默默打开了存放搓衣板的柜门(事务B结束);
  16. 在这种隔离级别之下,事务B只能读取到事务A已经提交的数据,就会产生不可重复读的问题,就是说它前一次读取的数据等一会儿读取时就会有所改变。也可以理解为在事务B进行的过程中(事务B还未结束),对于同一数据的两次查询却出现了不同的查询结果;
  17. 可重复读:它解决了不可重复读的问题。解决的方案就是在开启事务B的时候,对money建立一份数据快照(money在事务B开启的那一刻时的数据备份);
  18. 一旦事务B开启时对money建立一份数据快照,那在事务B的整个操作过程中,money都是一致的。因为任何其他事务都无法改变这份数据快照;
  19. 但它依旧会产生问题,那就是幻读;
  20. 实例:第二天一大早,小红就嚷嚷着要让小张赶紧把败家之眼给退了,无奈之下小张只能暂时放弃了自己的“好兄弟”(小张是个妻管严);
  21. 小张出门一个小时后,(money数据快照建立)(事务B开启)小红赶紧查询money。一看依旧是1500元,小红心想大概是堵车了吧,于是就继续等着。十分钟后,小张到家了,小红赶忙查询money,发现依旧是1500。于是乎小红又打开了柜门;
  22. 但这是为什么呢?
  23. 小张已经把电脑退掉,但小红查询的money依旧是1500
  24. 原因就是那份数据快照,有了数据快照,在一次事务的过程中,money的值确实唯一了,但是它还是不真实,有种虚幻的感觉;
  25. 所以此处依旧是存在问题的,这个问题被称为:幻读。解决方案使用串行化;
  26. 串行化:见名知意,它的含义就是在一个事务操作money的过程中,任何事务都不能操作money;这里的操作指的是 insert update delete
  27. 这样的话,只有一个事务在操作money,一定会把 脏读、不可重复读、幻读 都给干掉;
  28. 但它也有巨大且明显的问题,那就是效率。只允许一个事务进行操作,在很多业务流程中这样的设定几乎是不存在的;
  29. 总结:
  30. 读未提交:事务B可以读取到事务A操作过程中的中间数据(还未提交时对于money的操作)。产生的问题:脏读;
  31. 读已提交:事务B只能读取到事务A已经提交的数据。产生的问题:不可重复读(一次事务过程中对同一数据读取两次结果却不唯一);
  32. 可重复度:事务B在开启事务的那一刻对money建立一份数据快照。产生的问题:幻读。事务B操作过程中都是根据一份数据快照来进行操作;
  33. 串行化:事务B开启的时候,任何其他事务都不能对money再做insert update delete。产生的问题:效率低;

8. tcp三四次握手

  1. 建立连接三次握手(发起端只能是client):
  2. request报文
  3. client -------------> server 文字描述: client server 发送 request 报文;
  4. ACK+SYN报文
  5. server -------------> client 文字描述: server 接收到 request 报文之后,为此次连接分配资源然后向 client 回应 ACK+SYN 报文(其中SYN是用来做同步的);
  6. ACK报文
  7. client -------------> server 文字描述: client 接收到 server 发送的 ACK 报文之后向 server 回应 ACK 报文并为此次连接分配资源;
  8. 断开连接四次握手(发起端可以是client也可以是server,这里以client为例):
  9. FIN报文
  10. client -------------> server 文字描述: client 认为自己此次连接过程中的数据都发送完毕了,就会向 server 发送 FIN 报文;
  11. 用人的交流沟通这次对话是这样的过程:
  12. server,你好!我的数据发送完毕了,我打算关闭连接了。但是你不用着急关闭连接,等你的数据发送完成之后再关闭就可以了。我等着你的FIN报文。over
  13. 同时呢!这个时候,client会进入到 FIN_WAIT 状态,因为它在等待 server 向它发送 FIN
  14. ACK报文
  15. server -------------> client 文字描述: server 接收到了client发送过来的FIN,但它需要向client证明自己确实接收到了它发送的FIN,所以它发送ACKclient
  16. 用人的交流沟通这次对话是这样的过程:
  17. client,你好!你的FIN我收到了,我这边需要进行一些收尾数据的发送,你先稍等一下。但我先把ACK给你代表我接收到了你的FIN,你先稍等一下,我等会儿就把FIN发你。over
  18. FIN报文
  19. server -------------> client 文字描述: server 确认自己的数据发送完毕之后,会向 client 发送自己的 FIN 报文;
  20. 用人的交流沟通这次对话是这样的过程:
  21. client,你好!我这边把数据发送完毕了,准备好关闭连接了,现在把FIN发给你。voer
  22. ACK报文
  23. client -------------> server 文字描述: client 接收到 server FIN 之后知道自己可以关闭连接了。但是它要给 server 发送一个 ACK 来确保让 server 知道自己接收到了它的 FIN
  24. 用人的交流沟通这次对话是这样的过程:
  25. server,你好!我接收到了你的FIN,现在向你发送ACK。但是我怕网络问题你接收不到我的ACK,然后傻等我而不关闭此次连接;
  26. 所以我再经过一个 2MSL TIME_WAIT 时间,如果你接收不到我的ACK可以给我发消息,我再给你重新发送。但是如果我经过TIME_WAIT之后你仍旧没有再给我发送任何消息。就意味着你已经关闭了此次连接,那我也要关闭了。over
  27. 为什么连接要三次,而结束要四次呢?
  28. 因为连接的建立是同步的,其中server会向client发送SYN,而SYN就是用来同步的报文;
  29. 但是连接关闭的时候,是异步的。发起者往往率先准备好关闭连接,接收者都是被动的来进行连接关闭的;
  30. 2MSL:最大报文段生存时间;

9. redis的数据类型

  1. 它的数据类型分为:String Hash List Set Sorted_Set
  2. 其实这些数据类型都是指 value 的类型,因为Redis中存储数据都是以 key-value 这种形式进行存储的。而且它的key只能是String
  3. 同时呢!Redis是一款用C语言编写的开源的单线程数据库;

10. redis的Sorted_Set可以干什么?

  1. Sorted_Set是有序Set,它可以用来做实时排行榜;

11. 五个数组如何找并集、交集

  1. 并集:{1. 直接把这个五个数组放到Set里面,自动去重;
  2. 2. 两个两个的处理这些数组;
  3. 1)首先拿出来两个数组进行排序,利用API就可以。因为是快排;
  4. 2)依次比较排序后数组每一位上的数据(假设是a[n]和b[n]);
  5. if a[i]> b[j]-> j++;
  6. elseif a[i]< b[j]-> i++;
  7. else 否则就把a[i]或b[j]放到result数组中(因为排除了大于或者小于的情况,只剩下等于了)-> i++, j++;
  8. 注:循环的条件是( i != a.length && j != b.length );
  9. 3 经历上面的循环之后,a或者b数组肯定会有一个到达了尾部。我们假设是a,那b数组就可以从刚才j结束的位置将数据全部遍历出来并加入到result中;
  10. 因为a数组没了,且俩数组都是有序的,那此时b数组中的第一个元素的值肯定比a数组中最大的值还要大;
  11. 也就是说剩下的数据都是b特有的。所以这些都是并集的内容;
  12. }
  13. 交集:{1. 直接把这个五个数组放到Set里面,自动去重;
  14. 此时呢,做一个判断。如果一个元素在Set中不存在就直接添加,否则就放到新建的result数组中,因为已经存在的就是交集;
  15. 2. 两个两个的处理这些数组;
  16. 1)首先拿出来两个数组进行排序,利用API就可以。因为是快排;
  17. 2)依次比较排序后数组每一位上的数据(假设是a[n]和b[n]);
  18. if a[i]> b[j]-> j++;
  19. elseif a[i]< b[j]-> i++;
  20. else 否则就把a[i]或b[j]放到result数组中(因为排除了大于或者小于的情况,只剩下等于了)-> i++, j++;
  21. 注:循环的条件是( i != a.length && j != b.length )。因为一旦一个数组到达尾部,那另一个数组中不管剩多少数据都绝不会是交集了;
  22. }
  23. 算法方面非常薄弱,大佬勿喷,蟹蟹!

12. 跨域请求会不会到服务器那里?

  1. 可以到;
  2. 我们都知道,服务器可以处理跨域请求,只需要进行配置即可;
  3. 设想一下,如果服务器接收不到跨域请求,那服务器又如何处理跨域请求呢?
  4. 这里也贴一篇我的另一个文章,里面对跨域请求可以到后端进行了论证;

地址:跨域请求后端能接收到吗?

13. 二分查找

  1. 二分查找中间元素的下标值是向下取整的;
  2. 之所以这样写是因为遇到了这样的一个数组:1357911
  3. 此时二分的话会以5作为起始值;
标签: 网络 面试 java

本文转载自: https://blog.csdn.net/Mjh20180341121/article/details/122442116
版权归原作者 20180341121 所有, 如有侵权,请联系我们删除。

“weipai网络-面试回顾”的评论:

还没有评论