首页 > 虎牙社招后台开发岗涉及的技术题目及其答案
头像
挽风屿你
编辑于 2021-05-22 14:23
+ 关注

虎牙社招后台开发岗涉及的技术题目及其答案

1.三次握手中,最后一次回复丢失,会发生什么?

答:客户端第三次丢失是感应不到的,所以,会当作正常情况发送报文,Server端将以RST

包响应要求,此时,客户端知道,第三次握手失败。而服务器经过一段时间后,没有得到第

三次握手的响应,则重新发送第二次握手的包。默认为5次重发。间隔时间为3,6,12秒,

之后就放弃。

2.消息队列的确保机制:

答:

-发送端的可靠性

发送端完成操作后一定能将消息成功发送到消息队列中。

实现方法:在本地数据库建一张消息表,将消息数据与业务数据保存在同一数据库实例里,

这样就可以利用本地数据库的事务机制。事务提交成功后,将消息表中的消息转移到消息队

列中,若转移消息成功则删除消息表中的数据,否则继续重传。

-接收端的可靠性

接收端能够从消息队列成功消费一次消息。

两种实现方法:

保证接收端处理消息的业务逻辑具有幂等性:只要具有幂等性,那么消费多少次消息,最后

处理的结果都是一样的。

保证消息具有唯一编号,并使用一张日志表来记录已经消费的消息编号。

3. redis高并发的原因:

答:

-它是单线程,没有进程竞争,锁等设置,所以少了切换上下文的时间,相对快了很多。

-同时,数据存储在内存中,他可以快速处理数据。

-同时,它又是epoll的多路复用模式,异步的读取信息,自己要进行的逻辑处理也相对很

少。并且可以涉及单机多redis,充分利用其他cpu核心。

4. threadlocal的作用:

答:确保线程中有独享的变量副本,可以为自己服务。这类副本本身是不用多个线程维护状

态的。所以可以放入线程本地。

5.微服务注册中心,如何主动删除服务?

参考:https://blog.csdn.net/xiaobao5214/article/details/81263445?utm_source=blogxgwz1

答:

- 一个是客户端自己关闭后,eureka检查心跳,发现服务已经下线就关闭。

-一个是发送delete 请求:/eureka/apps/app-name到注册中心。

-

还有就是客户端如果是springboot,那么调用方法

DiscoveryManager.getInstance().shutdownComponent();即可。

6. http状态码,及其对应的304状态码的含义:

答:客户端在请求一个文件的时候,发现自己缓存的文件有Last Modified(截止时间),

那么在请求中会包含If Modified Since,这个时间就是缓存文件的Last Modified。因此,

如果请求中包含If Modified Since,就说明已经有缓存在客户端。服务端只要判断这个时间

和当前请求的文件的修改时间就可以确定是返回304还是200。返回304,则代表浏览器

可以继续使用缓存数据。如此,可以减少传输的数据量,同时,服务器也不需要进一步执行

相关数据的查询。

7. 两种数据库引擎的差异答:6大差别:

- Innodb 支持行级锁,和外键,myisam不支持行级锁和外键。

- innodb删除表的数据是一行一行的删除的,而myisam是直接删除一个表。

- innodb表中,没有缓存这个表的数量(即count(*));而myisam缓存了。

- innodb支持事务,而myisam不支持。

- innodb的存储文件是一个大文件,而myisam是三个文件,分别存储数据,索引,表的定

义。在迁移数据库的时候更加方便。

- 5.6 之前,InnoDB 不支持全文索引,MyISAM支持全文类型索引

8. b+树的优点:

答:

-数据均存储在叶子节点中,非叶子节点只有索引值。这样的设置,非叶子节点小,一次性

读入内存的节点多,io新能消耗低。

- B+树的查询效率更加稳定,路径长度一致。

- B+树的数据都存储在叶子结点中,各个叶子节点有兄弟指针,所以,扫库的时候很方便,

只需要扫一遍叶子结点即可。

9.聚簇索引的特点:

https://blog.csdn.net/qq_29373285/article/details/85254407

https://www.cnblogs.com/wangkaihua/p/10220462.html

答:索引的位置和其对应的物理内存顺序是一致的,即,索引排在前的,其数据存储的物理

地址也在前面。同时,聚簇索引的叶子节点就是数据,而非聚簇的叶子节点是主键id,还要

根据这个id去对应的聚簇索引中查询相关的数据。

9.复合索引的最左原则

答:最左匹配四个点:

- 建立一个复合索引(a,b,c),相当于建立了多个索引(a),(a,b),(a,b,c);

-索引排序是根据从左向右匹配的。

-查询的时候,优化器会优化sql 语句为对应索引的顺序,即:(a,c,b)也是可以用索引的。

-单独查询b,会采用index类型索引,即:不符合最左,直接查询所有的节点,找到对应

的数据指针,回表,这样很慢。

补充:复合索引的三个好处:可以减小索引树的个数,节省空间开销,建立一个树,相当于

建立三棵树。可以提高效率,索引越多,筛选出的剩余数据越少,回表的时候越快。可以实

现覆盖索引。即:查询的数据刚好是我们的树的索引项,比如就要找(a,b,c),那么就可以

不用回表,返回索引的数据即可。

10. springmvc的过程:https://www.cnblogs.com/fengquan-blog/p/11161084.html

答:

-请求给dispetchServlet 拦截,dispetchServlet注册handlerMapping。

-转发(调用自己的成员变量)给handlerMapping对象,它根据配置文件,初始化自己的值。

其中有个自己维护的一张map《url,bean》,根据拦截到的url的路径,可以找到对应的

controller对象,封装为HandlerExecutionChain(里面可能还有一些拦截器,面向切面那种)。

返回给dispetchServlet。

- dispetchServlet转发HandlerExecutionChain给适配的handlerAdapter(也是dispetchServlet

自己注册维护的,默认有三种适配器)。

- handlerAdapter根据接收到的controller(也是handler)的类名,利用反射,执行其handle

方法。(如果有拦截器,会先执行pre拦截器,而后是handler的方法,之后是post拦截器。这些拦截器好像都是动态代理前织入的)返回modelandview给dispetchServilet。

- dispetchServilet转发modelandview给viewResolver;

- viewResolver将modelAndView找出,这里其实也是一个map 映射过程。modelAndView

只是一个包含model 数据和页面名字字符串的对象。viewResolver根据这个字符串去到配置

的路径,如resource之类的地方,找到对应的jsp页面。然后返回具体的view对象给

dispetchServilet。

- dispetchServilet调用对象View的方法renter()。该方法将model注入到jsp中(其实是

装入了response的请求头里),然后返回。

- dispetchServilet将视图返回给浏览器。

11.分布式锁的实现原理:

答:三个:

-利用mysql

-利用redis的setnx实现

-利用redis集群算法RedLock

12.为什么用线程池不用new?

答:1、每次new Thread,新建对象性能差2、缺乏统一管理,可能导致线程创建过多,死

机等。3、缺乏更多功能,如:定时执行,定期执行,线程中断等。

13.为什么线程池不允许使用Executors去创建?

答:推荐使用threadPoolExecutor,因为executors其实就是对threadPoolExecutor的一个封

装。而且封装的不好,它允许创建的最大线程是maxint,很容易导致oom,内存不足错误。

所以,创建线程池,还是要我们自己手动通过threadPoolExercutor设置参数。

- newFixedThreadPool和newSingleThreadExecutor:是等待队列无限长

- newCachedThreadPool和newScheduledThreadPool:是最大线程数无限长

14. get和post 的区别,get的最长数据段是?

答:

- get主要是为了获取数据,而post是为了提交数据。两者虽然都有给服务器传输数据的功

能,但是意义是不一样的。

- get拼接在url 后,post的数据放入body的param内

- GET的目的是是读取,所以,服务器对应的接口应该有幂等性。即:多次请求的数据,不

会因为我的get改变。同时,因为幂等,所以就可以对GET请求的数据做缓存。

- get在url上传递参数,默认是ascii,不支持中文,要经过其他配置,而post内的编码可以

是unicode-8,支持中文。

- URL的最大长度是2083 个字符,path的部分最长是2048个字符。不过其实是ie8规定的,

http协议没有这一点。

15. redis的5大数据结构和其底层实现,还有应用场景

答:

16. url的解析过程。

答:四个步骤;

-如果本机刚刚联网,则会去通过DHCP协议,发送广播,目标地址是67,源地址端口是

68。获得即插即用的本机的ip地址和距离本机最近的DNS服务器的ip,以及网关路由的ip。

-而后是解析浏览器的url。由于我们只知道网关路由器的ip,所以要通过ARP协议解析网

关ip,获得mac 地址。-得到后,继续进行url的解析。通过发送url给网关路由,再由路由转发到对应的DNS服

务器(DNS服务器的端口号是53),DNS服务器再通过域名解析,找到对应url的ip地

址。

-而后,浏览器可以根据DNS返回的ip,进行tcp/ip 协议,三次握手过程建立连接。(80

端口)

-最后是双方通信,服务器返回web页面信息,浏览器渲染并且显示。

17.浏览器会对html做什么?

答:渲染。

18. java的启动过程。(类的加载)https://www.cnblogs.com/qiumingcheng/p/5398610.html

答; 1. 编译,2.类的加载(5 个步骤),3.执行程序输出结果。

19. mybatis的启动过程:https://www.cnblogs.com/ZhuChangwu/p/11741125.html

答:

-通过sqlsessionFactory类注册xml配置文件(数据库的url之类的);

- sqlsessionFactory调用方法,获得sqlsession类。这个类封装了和数据库的连接,还有一系

列的事务管理功能;

- 而后,session内,有方法可以通过scan扫描到配置文件,生成mapperProxy对象;该对

象将读取对象的xxxMapper.xml文件和对应的xxx接口。采用动态代理方法,生成一个接口

实现类。

-执行sql语句时,通过反射的方式,调用实现类的方法,其中有两个参数,对应的方法名

和sql语句。这由mapperMethed对象进行封装。

- mapperMethed传入sqlsession内封装的CRUD方法,内有对应的执行器类Executor;

-执行器类将调用方法query(),取出mapperMethed内的sql语句,生成prepareStatement。

-最后,像执行jdbc一样,进行数据库查询。

总结:mybatis,其实就是封装了jdbc。只不过,采用了动态代理,将接口和方法实现拆分

开来。

20. springboot的启动过程。

答:

- new了一个SpringApplication对象,使用SPI技术加载加载ApplicationContextInitializer、

ApplicationListener接口实例

-调用SpringApplication.run()方法

-调用createApplicationContext()方法创建上下文对象,创建上下文对象同时会注册spring

的核心组件类(ConfigurationClassPostProcessor 、AutowiredAnnotationBeanPostProcessor

等)。

-调用refreshContext()方法启动Spring容器和内置的Servlet容器

21. springboot如何启动mybatis:https://www.cnblogs.com/nxzblogs/p/10484281.html

答:

-和上面启动spring一样,在refreshContext()方法调用后,会去将加载进来的各种配置

进行处理,装入我们的springboot容器中,包括了spring,和mybatis。mybaitis的具体过程,

其实就是19的过程,只不过最后把sqlsessionFactory放入了容器中。

21. jva的gc标记算法,以及为什么不用标记计数算法?

答; gc标记算法有两个:一个是标记计数算法,有一个对象引用,就标记一次。但是,在两

个对象出现循环引用的情况下,此时引用计数器永远不为0,导致无法对它们进行回收。

第二个是可达性分析算法:即: 判断栈和方法区中是否有该对象的引用,没有,则回收。(标记计数法中,存在的问题是,堆对象和堆对象之间互相计数+1了,但是,栈中使用引用以

及被释放,比如方法已经结束了,但是,没有进行-1操作,所以存在无法回收)

22.转发和重定向的区别:

答:转发就是服务器中,一个servlet对这个请求进行了处理,但是,没有返回,而是给了

服务器另一个sevrlet再加工,而后返回。这个过程,请求头和响应头用的都是同一个。里

面的协议,编码,数据都不改变。即:两个servlet间是实现了通信。

重定向就是客户端发送信息,到达了服务器,而后服务器接处理了请求后,返回消息给浏览

器,并且告诉他,还要进行后续的操作,返回状态码为301,浏览器立即进一步发送请求。

这个过程是两次请求,而非servlet之间的通信。

表现是:浏览器上的url的改变,转发并不会改变。

23.数据库中的乐观锁和悲观锁

答:我只是说了一下定义,面试官表示,不是要原理,而是实现。

定义就是:悲观锁是认为冲突会发生,所以加了锁,乐观锁是认为,冲突一般不会发生,会

在完成业务逻辑后,在提交之前进行验证。

悲观锁我们数据库可以依靠自带的XS锁实现。

乐观锁,我们采用CAS和vesion(或者时间戳)来实现。这就需要代码上进行一定的处理了。

比如,我们可以多加一个字段vesion,读取数据的时候,将vesion读取出来,保存前,进行

比较version值,没有改变,则version+1后,再存入我们真正操作的数据。如果version改

变了,那就代表,这个数据已经过期,则要重新来一遍了。

更多模拟面试

全部评论

(0) 回帖
加载中...
话题 回帖

相关热帖

近期热帖

历年真题 真题热练榜 24小时
技术(软件)/信息技术类
查看全部

近期精华帖

热门推荐