面试题05
1,TCP和UDP的区别
TCP(传输控制协议)和UDP(用户数据报协议)都是网络传输协议,但它们在很多方面有所不同。TCP是面向连接的协议,建立连接后,数据传输前会进行三次握手,需要客户端和服务器总共发送3个报文。三次握手的目的是连接服务器指定端口,建立TCP连接,并同步连接双方的序列号和确认号,交换TCP窗口大小信息 ,确保通信双方都准备好进行数据传输。而UDP是无连接的协议,不需要进行连接建立过程,可以直接向目标发送数据包 。
TCP可以保证数据传输的可靠性,但会带来一定的延迟。而UDP主要用于那些对高速传输和实时性有较高要求的通信或广播通信 。
2,什么是正向代理和反向代理
正向代理和反向代理的主要区别在于它们所代理的对象不同。正向代理是客户端的代理,帮助客户端访问其无法访问的服务器资源。反向代理则是服务器的代理,帮助服务器做负载均衡,安全防护等。正向代理一般是客户端架设的,而反向代理一般是服务器架设的。
3,运行时数据区域有哪些
-
程序计数器是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器。
-
Java虚拟机栈是线程私有的,它的生命周期与线程相同。每个方法在执行的同时都会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息。
-
本地方法栈与Java虚拟机栈发挥的作用非常相似,区别是Java虚拟机栈为Java方法服务,而本地方法栈则为Native方法服务。
-
方法区是线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
-
堆是线程共享的内存区域,它几乎是虚拟机管理的内存中最大的一块。堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域唯一目的就是存放对象实例。
4,JVM怎么判断一个对象是否可用回收
在JVM里面,要判断一个对象是否可以被回收,最重要的是判断这个对象是否还在被使用,只有没被使用的对象才能回收。
-
引用计数器,也就是为每一个对象添加一个引用计数器,用来统计指向当前对象的引用次数,如果当前对象存在应用的更新,那么就对这个引用计数器进行增加,一旦这个引用计数器变成0,就意味着它可以被回收了。这种方法需要额外的空间来存储引用计数器,但是它的实现很简单,而且效率也比较高。不过主流的JVM都没有采用这种方式,因为引用计数器在处理一些复杂的循环引用或者相互依赖的情况时,可能会出现一些不再使用但是又无法回收的内存,造成内存泄露的问题。
-
可达性分析,它的主要思想是,首先确定一系列肯定不能回收的对象作为GC root,比如虚拟机栈里面的引用对象、本地方法栈引用的对象等,然后以GC ROOT作为起始节点,从这些节点开始向下搜索,去寻找它的直接和间接引用的对象,当遍历完之后如果发现有一些对象不可到达,那么就认为这些对象已经没有用了,需要被回收。可达性分析是目前主流JVM使用的算法。
5,JVM垃圾回收算法有哪些
JVM有几种垃圾回收算法。其中包括标记-清除算法、复制算法、标记-整理算法和分代收集算法。
- 标记-清除算法将垃圾回收分为两个阶段:标记阶段和清除阶段。在标记阶段,首先通过根节点,标记所有从根节点开始的对象,未被标记的对象就是未被引用的垃圾对象。然后,在清除阶段,清除所有未被标记的对象。
- 复制算法从根集合节点进行扫描,标记出所有的存活对象,并将这些存活的对象复制到一块新的内存上去,之后将原来的那一块内存全部回收掉。现在的商业虚拟机都采用这种收集算法来回收新生代。
- 标记-整理算法是一种老年代的回收算法,它在标记-清除算法的基础上做了一些优化。首先也需要从根节点开始对所有可达对象做一次标记,但之后,它并不简单地清理未标记的对象,而是将所有的存活对象压缩到内存的一端。之后,清理边界外所有的空间。
- 分代收集算法就是目前虚拟机使用的回收算法,它解决了标记整理不适用于老年代的问题,将内存分为各个年代。一般情况下将堆区划分为老年代和新生代,在堆区之外还有一个代就是永久代。在不同年代使用不同的算法,从而使用最合适的算法,新生代存活率低,可以使用复制算法。而老年代对象存活率搞,没有额外空间对它进行分配担保,所以只能使用标记清除或者标记整理算法。
6,JVM内存分配策略和回收策略
- JVM的内存分配策略包括对象优先在Eden区分配,大对象直接进入老年代,长期存活的对象将进入老年代。
- JVM的回收策略包括Minor GC和Full GC。Minor GC指发生在新生代的垃圾收集动作,因为Java对象大多都具备朝生夕灭的特性,因此Minor GC非常频繁,一般回收速度也比较快。Full GC也叫Major GC,对整个堆进行回收,包括新生代和老年代。Full GC发生频率比较低,老年代对象存活时间比较长,存活率标记高。Full GC的触发条件包括调用System.gc(),老年代空间不足,JDK 1.7及以前的永久代空间不足,Concurrent Mode Failure等。
7,类的生命周期
类的生命周期包括以下几个阶段:
- 加载:JVM会找到需要加载的类并把类的信息加载到JVM的方法区中,然后在堆区中实例化一个java.lang.Class对象,作为方法区中这个类的信息的入口。
- 连接:JVM会对类进行验证、准备和解析。
- 验证:确保加载的类符合JVM规范,不会危害JVM自身安全。
- 准备:为类的静态变量分配内存,并将其初始化为默认值。
- 解析:把类中的符号引用转换为直接引用。
- 初始化:如果一个类被直接引用,就会触发类的初始化。在这个阶段,JVM会根据程序员通过程序制定的初始化逻辑去初始化类变量和其他资源。
- 使用:在这个阶段,Java程序可以使用已经被初始化完成的类。
- 卸载:当一个类不再被需要时,它所占用的内存空间将被释放。在这个阶段,JVM会卸载类,并释放掉堆内存和方法区内存。
8,分布式事务常见解决方案
好的,这里是一些关于分布式事务解决方案的信息:
- 两阶段提交(2PC):这种方法将事务的提交分为两个阶段来进行处理。在第一阶段,协调者询问所有参与者是否准备好提交事务,然后根据参与者的反馈情况决定是否继续进行第二阶段。在第二阶段,如果所有参与者都同意提交事务,协调者将通知所有参与者提交事务,否则协调者将通知所有参与者中止事务。
- 三阶段提交(3PC):这种方法在两阶段提交的基础上增加了一个准备阶段。在准备阶段,协调者询问所有参与者是否准备好提交事务,并在超时时间内等待参与者的反馈。如果所有参与者都同意提交事务,则进入第二阶段,否则进入第三阶段。在第二阶段,协调者将通知所有参与者提交事务。在第三阶段,协调者将通知所有参与者中止事务。
- 补偿事务(TCC):这种方法通过为每个操作注册一个确认和补偿(撤销)操作来实现分布式事务。它分为三个阶段:Try、Confirm 和 Cancel。在 Try 阶段,系统执行所有业务检查并预留必要的业务资源;在 Confirm 阶段,系统执行真正的业务操作;在 Cancel 阶段,系统执行补偿操作以取消 Try 阶段执行的操作。
- 本地消息表:这种方法通过使用消息队列来实现分布式事务。它将需要分布式处理的任务通过消息的方式异步确保执行。
- 消息事务:这种方法通过使用消息中间件来实现分布式事务。它利用消息中间件提供的事务功能来确保消息的可靠传输。
- 最大努力通知:这种方法通过使用消息队列来实现分布式事务。它尽最大努力通知所有参与者提交或中止事务。
9,shiro认证流程
Shiro 认证流程大致如下:
- 首先调用
Subject.login(token)
进行登录,该方法会自动委托给Security Manager
。在调用之前,必须通过SecurityUtils.setSecurityManager()
设置Security Manager
。 Security Manager
负责真正的身份验证逻辑,它会委托给Authenticator
进行身份验证。Authenticator
执行身份验证操作。它会根据配置的Realm
来获取用户的身份信息。Realm
用于获取用户的身份信息。它可以从数据库、缓存或其他数据源中获取用户的身份信息。- 如果身份验证成功,
Authenticator
将返回一个包含用户信息的AuthenticationInfo
对象。 - 最后,
Security Manager
将返回一个包含用户信息的AuthenticationInfo
对象,并将其存储在Subject
中。
10,spring mvc处理请求流程
Spring MVC 处理请求的流程大致如下:
-
用户发送请求至前端控制器
DispatcherServlet
。 -
DispatcherServlet
收到请求后调用HandlerMapping
处理器映射器。 -
处理器映射器根据请求 URL 找到具体的处理器(后端控制器),生成处理器对象及处理器拦截器(如果有则生成)一并返回给
DispatcherServlet
。 -
DispatcherServlet
调用HandlerAdapter
处理器适配器去调用处理器。 -
处理器适配器执行处理器。
-
处理器执行完成后给处理器适配器返回
ModelAndView
。 -
处理器适配器向前端控制器返回
ModelAndView
。ModelAndView
是 Spring MVC 框架的一个底层对象,包括Model
和View
。 -
前端控制器请求视图解析器去进行视图解析,根据逻辑视图名来解析真正的视图。
-
视图解析器向前端控制器返回
View
。 -
前端控制器进行视图渲染,就是将模型数据(在
ModelAndView
对象中)填充到 request 域。 -
前端控制器向用户响应结果。