校招 未知部门 / 后端-Java / 一面

[面试日期] 2024-07-11 [面试时长] 未知
[学校背景] 未知 | 未知 [学历背景] 未知
[发布人] 面试之星官方收录
<h2>北京用友实习java一面</h2> <p>自我介绍</p><p>学习 方式</p><h4>Springboot 和Spring的区别</h4><p>首先在配置上,spring需要是xml或者java类的配置,从而去定义bean的依赖关系,而springboot是约定大于配置的,只需要去使用一些注解就能够简化开发,并且springboot只需要去配使用starter就能实现依赖管理,</p><p>此外springboot还内嵌了Tomcat,实现热部署,快速重启的作用</p><p><strong>关键字:配置,启动,Tomcat,Starter</strong></p><h4>Spring 事务介绍一下</h4><p>​ 一般用@Transactional,<strong>声明式事务的实现</strong>,当然也可以进行编程式实现用TransactionTemplate 也可以实现,重点说一下注解的方式,还是基于AOP去实现的,大概了解就是他会有一个平台管理事务的接口**<code>PlatformTransactionManager</code><strong>,也有对应的事务的状态信息,比如什么隔离级别,回滚什么的,还有个接口是事务的运行状态。所以一共就是</strong>三个接口**</p><p><strong>事务的传播机制</strong>这个取决于注解里面对于的progation的属性配置,默认用的就是就是PROPAGATION_REQUIRED</p><p>如果外部方法没有开启事务的话,Propagation.REQUIRED修饰的内部方法会新开启自己的事务,且开启的事务相互独立,互不干扰。</p><p>如果外部方法开启事务并且被<code>Propagation.REQUIRED</code>的话,所有<code>Propagation.REQUIRED</code>修饰的内部方法和外部方法均属于同一事务 ,只要一个方法回滚,整个事务均回滚。</p><pre> @Service Class A { @Autowired B b; @Transactional(propagation = Propagation.xxx) public void aMethod { //do something b.bMethod(); } } @Service Class B { @Transactional(propagation = Propagation.xxx) public void bMethod { //do something } } </pre><p>在这种情况下就会当第二个方法报错,那么第一个方法也会进行回滚,因此如果我把第一个方法里面把第二个方法进行trycatch并且记录日志,由于异常被捕获,所以不会自动回滚。</p><p>此外的常用两种还有progation.new,使用这个后就会去开始对应新的事物,比如a方法报错,那么b就不会进行回滚,但是如果b方法报错,并且异常没有被捕获,因此a会判定为出现错误,因此都会回滚。</p><p>还有progation.nested,这个就相当于内嵌了一个事务,比如b用这个,a仍然是默认,那么b报错,b回滚。a不会回滚。取决于外部方法有木有开启一个事务</p><p><strong>使用上:</strong></p><p>如果对于数据库的操作,单条的sql语句就不需要去开启事务,反之成立</p><h4>SpringAOP在事务的运用呢</h4><p>首先刚刚说的注解仍然是在基于AOP实现的,AOP又是基于动态代理实现的,这取决于目标有没有去实现接口,如果实现了接口,会默认使用JDK的动态代理,如果没有,会走Cglib进行,其实也就是去生成对应的代理对象,如何走前后以及规定的回滚逻辑,此外还要注意在一个类里面实现自调用的问题,因为他是基于这是因为 Spring AOP 工作原理决定的。因为 Spring AOP 使用动态代理来实现事务的管理,它会在运行的时候为带有 <code>@Transactional</code> 注解的方法生成代理对象,并在方法调用的前后应用事物逻辑。如果该方法被其他类调用我们的代理对象就会拦截方法调用并处理事务。但是在一个类中的其他方法内部调用的时候,我们代理对象就无法拦截到这个内部调用,因此事务也就失效了。解决办法就是避免同一类中自调用或者使用 AspectJ 取代 Spring AOP 代理。</p><h4>Mysql的隔离级别默认</h4><p>四个隔离机制,默认是可重复读的操作,它主要去解决了脏读和不可重复读的操作。因为它只能看到事务的启动之前已经提交的数据</p><h4>@Qualifier的运用</h4><p>这里首先就是去解决不同的bean,或者说同种类型的bean,当自动注入的时候不知道如何进行注入,这个时候就可以用这个注解,并且去声明里面的name属性,在注入的时候进行指定名字进行注入就行</p><h4>@AutoWired和@Resource的区别</h4><p>首先是<strong>提供者</strong> @Autowired<code> 是 Spring 提供的注解,</code>@Resource` 是 JDK 提供的注解。</p><p>第一个注解主要是用根据类型去<strong>匹配</strong>的,优先去匹配对应接口类型进行匹配,那么当多个类型的时候就会用名字去注入,这时候建议是使用@Qualfier去操作,传入value指定bean的名字,一般是接口小写。第二个注解就是根据名字去注入,都要去传入对应的bean的名字,他的属性是name</p><p><strong>使用</strong>:<code>@Autowired</code> 支持在构造函数、方法、字段和参数上使用。<code>@Resource</code> 主要用于字段和方法上的注入,不支持在构造函数或参数上使用。</p><h4>GC 的CMS,并且思考如果并发过程老年区出现大对象,或者碎片化过多怎么办</h4><p>这里走一遍CMS的流程,<strong>标记-清除算法,jdk8,注重用户的暂停时间,流程</strong></p><p>首先就是老年代的算法,会先单独标记gcroot,并发标记剩下的,如何在单独标记刚刚并发造成的,最后并行清理</p><p>缺点就是会产生大量的内存碎片,这时候如果并发清理的时候出现大对象,他会要么OOM,要么退化成serial Old的算法,这时候进行的gc耗时就很长(多线成标记-整理)</p><h4>Docker基本使用</h4><p>只介绍一些基本命令,以及概念</p><p><strong>Kafka</strong></p><p>这里大概说一下他的架构,以及生产-订阅的设计模式</p><p>topic,partition,broker,consumer</p><h4>spring框架的设计模式</h4><p><strong>单例模式</strong></p><p>体现在bean的默认,prototype,底层用的是concurrentHashmap,去写的一个哈希表,大部分无状态是线程安全的</p><p><strong>工厂模式</strong></p><p><code>BeanFactory</code>:<strong>延迟注入</strong>(使用到某个 bean 的时候才会注入),相比于<code>ApplicationContext</code> 来说会占用更少的内存,程序启动速度更快。</p><p><code>ApplicationContext</code>:容器启动的时候,不管你用没用到,<strong>一次性创建所有 bean</strong> 。<code>BeanFactory</code> 仅提供了最基本的依赖注入支持,<code>ApplicationContext</code> 扩展了 <code>BeanFactory</code> ,除了有<code>BeanFactory</code>的功能还有额外更多功能,所以一般开发人员使用<code>ApplicationContext</code>会更多。</p><p><strong>代理模式</strong></p><p>实际上就是动态代理的一些操作</p><p>Spring AOP 属于运行时增强,而 AspectJ 是编译时增强。 Spring AOP 基于代理(Proxying),而 AspectJ 基于字节码操作(Bytecode Manipulation)</p><p><strong>适配器模式</strong></p><p>这个体现在Spring MVC里面的DispatchServlet,这个就会进行,并且映射出对应的handler,开始由<code>HandlerAdapter</code> 适配器处理。<code>HandlerAdapter</code> 作为期望接口,具体的适配器实现类用于对目标类进行适配,<code>Controller</code> 作为需要适配的类。</p><h4>@Component 和 @Bean 的区别是什么?</h4><ul><li><code>@Component</code> 注解作用于类,而<code>@Bean</code>注解作用于方法。</li><li><code>@Component</code>通常是通过类路径扫描来自动侦测以及自动装配到 Spring 容器中(我们可以使用 <code>@ComponentScan</code> 注解定义要扫描的路径从中找出标识了需要装配的类自动装配到 Spring 的 bean 容器中)。<code>@Bean</code> 注解通常是我们在标有该注解的方法中定义产生这个 bean,<code>@Bean</code>告诉了 Spring 这是某个类的实例,当我需要用它的时候还给我。</li><li><code>@Bean</code> 注解比 <code>@Component</code> 注解的自定义性更强,而且很多地方我们只能通过 <code>@Bean</code> 注解来注册 bean。比如当我们引用第三方库中的类需要装配到 <code>Spring</code>容器时,则只能通过 <code>@Bean</code>来实现。</li></ul><h4>Bean的作用域</h4><p><strong>singleton</strong> : IoC 容器中只有唯一的 bean 实例。Spring 中的 bean 默认都是单例的,是对单例设计模式的应用。</p><p><strong>prototype</strong> : 每次获取都会创建一个新的 bean 实例。也就是说,连续 <code>getBean()</code> 两次,得到的是不同的 Bean 实例。</p><p>剩下的比如什么seesion,request都是用于web应用</p><a>#我的实习日记#</a>
AI 推荐面试题