百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程网 > 正文

(答案三) 高级Java面试试题 java高级工程师面试题及答案

yuyutoo 2024-10-26 16:08 7 浏览 0 评论

开源框架知识

1、简单讲讲tomcat结构,以及其类加载器流程,线程模型等。

模块组成结构:

Tomcat 的核心组件就 Connector 和 Container,一个Connector+一个Container(Engine)构成一个Service,Service就是对外提供服务的组件,有了Service组件Tomcat就能对外提供服务了,但是光有服务还不行,还需要有环境让你提供服务才行,所以最外层的Server就是为Service提供了生存的土壤。

Connector是一个连接器,主要负责接受请求并把请求交给Container,Container就是一个容器,主要装的是具有处理请求的组件。Service主要是为了关联 Container与 Connect,只有两个结合起来才能够处理一个请求。Server负责管理 Service集合,从图中我们可以看到Tomcat可以提供多种服务,那么这些Service就是由Server来管理的。具体工作包括:对外提供一个接口访问Service,对内维护 Service集合,维护 Service集合包括管理 Service声明周期等等。

类加载器流程

当tomcat启动时,会创建几种类加载器:

1 Bootstrap 引导类加载器

加载JVM启动所需的类,以及标准扩展类(位于jre/lib/ext下)

2 System 系统类加载器

加载tomcat启动的类,比如bootstrap.jar,通常在catalina.bat或者catalina.sh中指定。位于CATALINA_HOME/bin下

3 Common 通用类加载器

加载tomcat使用以及应用通用的一些类,位于CATALINA_HOME/lib下,比如servlet-api.jar

4 webapp 应用类加载器

每个应用在部署后,都会创建一个唯一的类加载器。该类加载器会加载位于 WEB-INF/lib下的jar文件中的class 和 WEB-INF/classes下的class文件。

当应用需要到某个类时,则会按照下面的顺序进行类加载:

1 使用bootstrap引导类加载器加载

2 使用system系统类加载器加载

3 使用应用类加载器在WEB-INF/classes中加载

4 使用应用类加载器在WEB-INF/lib中加载

5 使用common类加载器在CATALINA_HOME/lib中加载

线程模型

2、tomcat如何调优,涉及哪些参数 。

Tomcat 的缺省配置是不能稳定长期运行的,也就是不适合生产环境,它会死机,让你不断重新启动,甚至在午夜时分唤醒你。对于操作系统优化来说,是尽可能地增大可使用的内存容量、提高CPU 的频率,保证文件系统的读写速率等。经过压力测试验证,在并发连接很多的情况下,CPU 的处理能力越强,系统运行速度越快。

硬件上选择,操作系统选择,版本选择,jdk选择,配置jvm参数,配置connector的线程数量,开启gzip压缩,trimSpaces,集群等
a) 内存优化:主要是对Tomcat启动参数进行优化,我们可以在Tomcat启动脚本中修改它的最大内存数等等。

b) 线程数优化:Tomcat的并发连接参数,主要在Tomcat配置文件中server.xml中配置,比如修改最小空闲连接线程数,用于提高系统处理性能等等。

c) 优化缓存:打开压缩功能,修改参数,比如压缩的输出内容大小默认为2KB,可以适当地修改。

3、讲讲Spring加载流程。

3.1. 转化 BeanName
3.2. 合并 RootBeanDefinition
3.3. 处理循环依赖
3.4. 创建实例
3.5. 注入属性
3.6. 初始化
3.7. 类型转换

4、Spring AOP的实现原理。

实现AOP的主要设计模式就是动态代理。
Spring的动态代理有两种:一是JDK的动态代理;另一个是cglib动态代理。

5、讲讲Spring事务的传播属性。

所谓spring事务的传播属性,就是定义在存在多个事务同时存在的时候,spring应该如何处理这些事务的行为。这些属性在TransactionDefinition中定义,具体常量的解释见下表:

6、Spring如何管理事务的。

1、就是@Transactional注解保证的是每个方法处在一个事务,如果有try一定在catch中抛出运行时异常。

2、方法必须是public修饰符。否则注解不会生效,但是加了注解也没啥毛病,不会报错,只是没卵用而已。

3、this.本方法的调用,被调用方法上注解是不生效的,因为无法再次进行切面增强。

7、Spring怎么配置事务(具体说出一些关键的xml 元素)。

一般都是 @Transactional 注解完事儿,里面有一些属性字段,看自己需求配置即可

8、说说你对Spring的理解,非单例注入的原理?它的生命周期?循环注入的原理,aop的实现原理,说说aop中的几个术语,它们是怎么相互工作的。

Spring的理解:1)、Spring是一个开源框架,主要是为简化企业级应用开发而生。可以实现EJB可以实现的功能,Spring是一个IOC和AOP容器框架。

? 控制反转(IOC):Spring容器使用了工厂模式为我们创建了所需要的对象,我们使用时不需要自己去创建,直接调用Spring为我们提供的对象即可,这就是控制反转的思想。

? 依赖注入(DI):Spring使用Java Bean对象的Set方法或者带参数的构造方法为我们在创建所需对象时将其属性自动设置所需要的值的过程就是依赖注入的基本思想。

? 面向切面编程(AOP):在面向对象编程(OOP)思想中,我们将事物纵向抽象成一个个的对象。而在面向切面编程中,我们将一个个对象某些类似的方面横向抽象成一个切面,对这个切面进行一些如权限验证,事物管理,记录日志等公用操作处理的过程就是面向切面编程的思想。

2)、在Spring中,所有管理的都是JavaBean对象,而BeanFactory和ApplicationContext就是Spring框架的那个IOC容器,现在一般使用ApplicationContext,其不但包括了BeanFactory的作用,同时还进行了更多的扩展。

? 非单例注入原理:在大部分情况下,容器中的bean都是singleton类型的。如果一个singleton bean要引用另外一个singleton bean或者一个非singleton bean要引用另外一个非singleton,通常情况下将一个bean定义为另一个bean的property值就可以了。不过对于具有不同生命周期的bean来说这样做就会有问题了,比如在调用一个singleton类型bean A的某个方法时,需要引用另一个非singleton(prototype)类型的bean B,对于bean A来说,容器只会创建一次,这样就没法在需要的时候每次让容器为bean A提供一个新的的bean B实例。

9、Springmvc 中DispatcherServlet初始化过程。

DispatcherServlet extends FrameworkServlet extends HttpServletBean extends HttpServlet

初始化:HttpServletBean.init() -> FrameworkServlet.initServletBean -> FrameworkServlet.initWebApplicationContext()

initWebApplicationContext: 

1. 调用WebApplicationContextUtils.getWebApplicationContext(ServletContext)获取当前web容器中的根WebApplicationContext rootContext,该rootContext通常由ContextLoaderListener生成(因为该方法实际是获取web容器中attrName为org.springframework.web.context.WebApplicationContext.ROOT的WebApplicationContext,而该attrName由ContextLoaderListener设置到web容器中)

2. 判断本Servlet所属的WebApplicationContext wac是否在init之前就由别的步骤注入了?即判断wac是否为null

2.1. 若非空(wac已存在),则将rootContext设为wac的parent,再调用configureAndRefreshWebApplicationContext(wac)

2.2. 若为空(wac不存在),则先调用findWebApplicationContext寻找web容器中是否已经存在同名(attrName,定义见5)的WebApplicationContext(首次启动web容器时通常不存在;当servlet初始化失败,web容器自动重启时可能存在),若还是不存在则调用createWebApplicationContext生成一个新的WebApplicationContext

2.2.1. createWebApplicationContext(rootContext): 首先创建一个全新的WebApplicationContext wac,再将rootContext设为wac的parent,再调用configureAndRefreshWebApplicationContext(wac)

3. configureAndRefreshWebApplicationContext(wac): 先设置wac的各项配置和环境参数,后调用wac.refresh()

4. DispatcherServlet.onRefresh(wac): 初始化与web mvc相关的spring组件

5. 调用ServletContext.setAttribute将wac注册到web容器中,attrName为org.springframework.web.servlet.FrameworkServlet.CONTEXT.${servlet-name

10、netty的线程模型,netty如何基于reactor模型上实现的。

(1)Reactor单线程模型

(2)Reactor多线程模型

(3)主从Reactor多线程模型

(4)netty的多线程模型

Netty整体架构是Reactor模型,采用epoll机制,所以往深地说还是IO多路复用模式,所以可以说Netty是同步非阻塞模型。但是很多人说这是netty基于java NIO类库实现的异步通信框架。

Netty特点是:异步非阻塞,基于事件驱动,性能高,高可靠性,高可定制性。

11、为什么选择netty。

开发出高质量的NIO 程序并不是一件简单的事情,除去NIO 固有的复杂性和Bug不谈,作为一个NIO 服务端,需要能够处理网络的闪断、客户端的重复接入、客户端的安全认证、消息的编解码、半包读写等情况, 如果你没有足够的NIO 编程经验积累, 一个NIO 框架的稳定往往需要半年甚至更长的时间。更为糟糕的是, 一旦在生产环境中发生问题, 往往会导致跨节点的服务调用中断, 严重的可能

会导致整个集群环境都不可用, 需要重启服务器,这种非正常停机会带来巨大的损失。

从可维护性角度看,由于NIO 采用了异步非阻塞编程模型,而且是一个I/O 线程处理多条链路,它的调试和跟踪非常麻烦, 特别是生产环境中的问题,我们无法进行有效的调试和跟踪, 往往只能靠一些日志来帮助分析,定位难度很大。

对于java原生的IO我们之所以不选择使用是因为:

NIO的类库和API繁杂使用麻烦,你需要熟练掌握Selectol,ServerSocketChannel,

SocketChannel,ByteBuffer 等。

需要具备其他的额外技能做制垫,例如熟悉Java 多线程编程。这是因为NIO编程涉及到Reactor 模式,你必须对多线程和网络编程非常熟悉,才能编写出高质量的NIO程序。

可靠性能力补齐, 工作量和难度都非常大。例如客户端面临断连重连、网络间断、半包读写、失败缓存、网络拥塞和异常码流的处理等问题, NI0 编程的特点是功能开发相对容易,但是可靠性能力补齐的工作量和难度都非常大。

JDK NIO的BUG,比如epoll bug,这个BUG会在linux上导致cpu 100%,使得nio server/client不可用,这个BUG直到jdk 6u4才解决,但是直到JDK1.7中仍然有这个问题,该问题并未被完全解决,只是发生的频率降低了而已。

基于上述原因大多数场景下都不建议直接使原生NIO,除非你精通NIO编程或者是有特殊的需要,否则作为服务器编程的NIO可能会带来巨大的生产隐患。

12、netty的心跳处理在弱网下怎么办。

  1. 使用 Netty 实现心跳机制的关键就是利用 IdleStateHandler 来产生对应的 idle 事件.
  2. 一般是客户端负责发送心跳的 PING 消息, 因此客户端注意关注 ALL_IDLE 事件, 在这个事件触发后, 客户端需要向服务器发送 PING 消息, 告诉服务器"我还存活着".
  3. 服务器是接收客户端的 PING 消息的, 因此服务器关注的是 READER_IDLE 事件, 并且服务器的 READER_IDLE 间隔需要比客户端的 ALL_IDLE 事件间隔大(例如客户端ALL_IDLE 是5s 没有读写时触发, 因此服务器的 READER_IDLE 可以设置为10s)
  4. 当服务器收到客户端的 PING 消息是, 会发送一个 PONG 消息作为回复. 一个 PING-PONG 消息对就是一个心跳交互.
  5. 断线重连的关键一点是检测连接是否已经断开. 因此我们改写了 ClientHandler, 重写了 channelInactive 方法. 当 TCP 连接断开时, 会回调 channelInactive 方法, 因此我们在这个方法中调用 client.doConnect() 来进行重连.

13、netty的通讯协议是什么样的。

二种实现方式:

  • 第一种方式利用了自定义协议,传递消息的时候,对消息的前几位(比如2位)进行自定义的位置(比如AB)解码器解析的时候前二位为AB表示一种协议类型,CD一种协议类型。这种方式没有利用protobuf,而是直接使用Netty自定义协议来解决的方案。
  • 第二种方式使用protobuf来实现,实际上是对消息的定义方式进行规定,因为netty本身,客户端和服务器端建立的是一条TCP连接,一方必须要判断对方发送过来的对象是什么类型。

https://www.jianshu.com/p/9466c24beaa2

14、springmvc用到的注解,作用是什么,原理。

复制代码

@Controller 声明Action组件

@Service 声明Service组件 @Service(“myMovieLister”)

@Repository 声明Dao组件

@Component 泛指组件, 当不好归类时.

@RequestMapping(“/menu”) 请求映射

@Resource 用于注入,( j2ee提供的 ) 默认按名称装配, @Resource(name=”beanName”)

@Autowired 用于注入,(srping提供的) 默认按类型装配

@Transactional( rollbackFor={Exception.class}) 事务管理

@ResponseBody

@Scope(“prototype”) 设定bean的作用域

原理的话,自己根据自己需要感兴趣的注解,去转向了解一下吧,太多了,,写不完。。

15、springboot启动机制。

我们可以将自动配置的关键几步以及相应的注解总结如下:

@Configuration&与@Bean------>>>基于java代码的bean配置

@Conditional-------->>>>>>设置自动配置条件依赖

@EnableConfigurationProperties与@ConfigurationProperties->读取配置文件转换为bean。

@EnableAutoConfiguration、@AutoConfigurationPackage 与@Import->实现bean发现与加载。

相关推荐

12、高阶组件:魔法增幅器——React 19 HOC模式

一、魔法增幅器的本质"高阶组件是魔法师用咒语叠加的炼金术,"霍格沃茨魔咒研究院院长凝视着发光的增幅器,"通过函数式能量场的嵌套,让基础组件获得预言家日报式的逻辑继承!"...

深入理解nodejs的异步IO与事件模块机制

一、node为什么要使用异步I/O异步最先诞生于操作系统的底层,在底层系统中,异步通过信号量、消息等方式有广泛的应用。但在大多数高级编程语言中,异步并不多见,这是因为编写异步的程序不符合人习惯的思维逻...

前端时间同步利器:React + useEffect 实现高性能动态时钟

前言在你奋笔疾敲代码的瞬间,是不是突然一低头,发现时间像偷偷跑路的变量,一眨眼就从上午飘到下午?饭没吃、会没开、工位也快被前端猫霸占了。仿佛你写的不是代码,而是“时间穿梭机”。别慌,咱们今天就来用R...

JavaScript 异步编程指南 - 聊聊 Node.js 中的事件循环

作者:五月君来源:编程界|事件循环是一种控制应用程序的运行机制,在不同的运行时环境有不同的实现,上一节讲了浏览器中的事件循环,它们有很多相似的地方,也有着各自的特点,本节讨论下Node.js中...

10个Vue开发技巧「实践」

作者:WahFung转发链接:https://juejin.im/post/5e8a9b1ae51d45470720bdfa路由参数解耦一般在组件内使用路由参数,大多数人会这样做:...

通过番计时器实例学习 React 生命周期函数 componentDidMount

大家好,今天我们将通过一个实例——番茄计时器,学习下如何使用函数生命周期的一个重要函数componentDidMount():componentDidMount(),在组件加载完成,render之后...

SRE监控四大黄金指标,任何一个有异常都会是灾难……

导读...

前端必看!10 个 Vue3 救命技巧,解决你 90% 的开发难题?

写Vue3项目时,是不是总被数据更新延迟、组件间传值混乱、页面加载缓慢这些问题折磨得头秃?别担心!作为摸爬滚打多年的老前端,今天掏出压箱底的10个实战技巧,从性能优化到复杂逻辑处理,每一个都能...

如何用2 KB代码实现3D赛车游戏?2kPlus Jam大赛了解一下

选自frankforce作者:Frank机器之心编译参与:王子嘉、GeekAI控制复杂度一直是软件开发的核心问题之一,一代代的计算机从业者纷纷贡献着自己的智慧,试图降低程序的计算复杂度。然而,将一款...

证明你访问的网站是你想访问的,Safari 真的需要

安全研究员在Safari上找到了一个新漏洞,能让网站在浏览器的地址栏内将自己伪装成另一个网站——得益于Safari地址栏的“智能缩略”功能。在Deusen最近公开的攻击演示(PoC,P...

抓狂!TS 组件性能拉胯到崩溃?4 个绝杀技巧逆风翻盘!

前端兄弟姐妹们五一假期快乐,咱们谁还没被TypeScript组件的性能问题折磨过?页面加载转圈圈,点击按钮没反应,代码改了一轮又一轮,性能却还是原地踏步,分分钟想砸电脑!别慌,今天这4个绝杀技...

让小球做圆周运动,你有几种办法?

最近在阅读外国技术文章中无意中发现了一个神奇的CSS属性motion-path,它可以让Dom元素可以按照自定义的路径移动。又想起了很久之前参加校招面试的时候,面试官问了我一个问题“能不能不借助库实现...

前端基础进阶(十四):深入核心,详解事件循环机制

EventLoopJavaScript的学习零散而庞杂,很多时候我们学到了一些东西,但是却没办法感受到进步!甚至过了不久,就把学到的东西给忘了。为了解决自己的这个困扰,在学习的过程中,我一直在试图寻...

从0搭建一个WebRTC,实现多房间多对多通话,并实现屏幕录制

这篇文章开始会实现一个一对一WebRTC和多对多的WebRTC,以及基于屏幕共享的录制。本篇会实现信令和前端部分,信令使用fastity来搭建,前端部分使用Vue3来实现。为什么要使用WebRTCWe...

Vue2 开发卡壳?这 10 个实战技巧专治各种不服

干前端开发的兄弟,谁还没被Vue2折腾过?数据不更新、组件通信乱成麻、性能差到想砸电脑……这些痛点,我都懂!今天直接甩出10个超实用的实战技巧,每一个都是从项目“血坑”里爬出来总结的,专...

取消回复欢迎 发表评论: