JAVA软件面试之杭州

两周的时间,面试了杭州将近20多家软件公司,有时下热门的互联网行业,也有传统行业。涉及的行业众多,社交直播平台的、安防监控的、消费信贷的、大数据风控、互联网医疗、电商的等等。这里写一下自己面试过程中的遇到的面试题,借以反思一下自己面试的不足。

1.Spring框架的IOC和AOP原理;

IOC:在传统的程序实现里,由代码来控制组件之间的关系,使用new关键字来实现两个组件之间的结合,这样会带来对象之间的耦合,像齿轮转动一样,有了IOC,它将实现组件关系从内部像外部转移,由容器在运行期间将依赖关系注入到组件中。根据类名动态的生成对象,这种编程方式可以在对象生成的时候才决定到底是哪一种对象。

AOP:通过在代理对象中包裹切面,运行期间将切面织入到容器管理的bean中,代理类封装了目标类,并拦截被通知方法的调用,再将调用转发给真正的目标bean。当拦截到方法调用,在调用目标bean之前代理会执行切面逻辑。AOP提供了两种方式来生成代理对象:JDKProxy和Cglib,具体使用哪种方式由AopProxyFactory根据AdvisedSupport对象的配置来决定。默认策略是如果目标类是接口就使用JDK动态代理请求,否则使用Cglib来代理。

2.类加载机制

Class文件由类装载器装载后,在jvm中将形成一份描述class结构元信息对象,通过该对象可以获知class的结构信息,如构造函数、属性和方法。

双亲委派模型:

如果一个类加载器接收到类加载请求,它首先把这个请求委托给父类加载器去完成,因此,所有加载请求都应该传送到顶层启动类加载器中,只有父加载器反馈自己无法完成这个加载请求,子加载器才会尝试自己去加载。

装载:

  • 通过一个类的全限定名获取此类的二进制字节流;
  • 将这个字节流所代表的静态存储结构转化为方法区运行时的数据结构;
  • 在java堆中生成一个代表这个类的java.lang.Class作为方法区这些数据的入口;

验证:

  • 文件格式验证:保证输入的字节流能正确解析并存储于方法区内;
  • 元数据验证:对类中的各个数据类型进行校验分析;
  • 对方法体验证,保证被校验的类的方法在运行中不会做出危害虚拟机安全的行为;
  • 符号引用验证:对常量池中的各种符号引用进行匹配校验;

准备:

正式为类变量分配内存,并设置变量初始值,内存都将在方法区进行分配;

解析:

虚拟机将常量池中的符号引用替换为直接引用的过程

3.分布式事务

基于XA协议的两阶段提交和消息+最终一致性

4.常用设计模式

单例、工厂、适配器、责任链、门面、装饰、策略、观察者等 说出几个,并知道实现方法和应用场景。

5.sql调优

  • 尽量避免使用查询模糊匹配,会导致索引失效。like‘%param%‘
  • 避免对索引字段进行计算操作,在索引字段上使用not/<>/!=等,避免在索引字段上出现isNull/isNotNull,以及不要在索引上使用函数或空值;
  • 嵌套子查询可以考虑使用临时表
  • union all能解决的场景不要使用union
  • 避免在where语句中出现in/not in/having
  • 不要以字符格式声明数字
  • select 语句要标识要查询的字段,不要总是select *!!

6.分库分表策略

  • 中间变量=user_id%(分库数量*每个分表数量)
  • 库=取整(中间变量/每个库表数量)
  • 表=中间变量%每个库表数量

[email protected]和@Autowired区别

同:都是做bean注入使用

异:@AutoWired默认按照类型byType装配对象,依赖对象必须存在,如果允许null值,可以设置required属性为false。@Resource默认按照byName注入,由j2ee提供;

8.java7新特性、java8新特性

9.servlet生命周期

初始化阶段调用init方法

响应客户请求调用service方法

终止阶段调用destory方法

10.页面加载慢的原因

减少请求数、减少资源大小、找最快的服务器三方面去优化。

优化图片资源的格式和大小;

开启网络压缩;

使用浏览器缓存;

减少重定向,每一次重定向都会导致浏览器重新加载请求,延长加载时间;

使用cdn缓存静态资源

减少dns解析次数

压缩js和css去掉空格等

11.set底层实现

利用map的key不能重复

12.jvm分代垃圾回收

Eden区用来创建新对象,满触发一次young GC,将还被使用的对象复制到from区,Eden区再次用完再次用完,再触发一次young GC,将eden和from区的还在被使用的对象复制到to区,下一次young GC则是将Eden区和to区还被使用的对象复制到from区,超过阈值对象还没有被释放,复制到old generation。old用完触发full GC。合理设置young generation和old generation避免产生full gc.

13.负载均衡算法

轮询、加权轮询、随机、最少连接、源地址散列。

14.高可用架构设计

主要手段:数据和服务的冗余备份和失效转移

15.高可用服务

分级管理,核心应用与服务优先使用更好的硬件

超时设置,一旦超时,通信框架抛出异常,应用可选择重试和请求转移

异步调用,消费者在消息队列取

服务降级,拒绝服务和关闭服务,保证核心应用和功能能正常运行

幂等性设计,保证服务调用多次和一次结果相同;

16.反射机制

17.分布式缓存的一致性hash(网易)

18.https原理(网易)

19.乐观锁和悲观锁(网易)

20.数据库隔离级别

21.spring事务传播属性

22.301与302区别(网易)

301永久转移 302暂时转移

23.get与post区别

24.表建索引规则

避免对大数据类型建立索引

经常使用group by和order by的建立索引

用于连接的列建立索引

对那些频繁出现在where子句中的建立索引

确定表是大量查询还是增删改

25.跨域有几种方式(网易)

26.HashMap与ConcurrentHashMap

27.分布式锁如何实现?

28.kafka技术优点,以及是怎么实现的?

29.Tcp/IP协议的三次握手与四次挥手

30.线程间如何通信?(网易)

同步(synchronized)比如线程A和线程B都持有一个object,线程B需要等到A执行后才能运行。A与B就实现了通信,本质上是共享内存通信,多个线程需要访问同一个共享变量,谁拿了锁就可以先执行

wait/notify机制,A调用wait进入阻塞,条件满足时,B调用notify唤醒A

管道通信就是使用PipedInputStream和PipedOutputStream进行通信

31.spring如何处理循环依赖?

构造器循环依赖:

<bean id="A" class="com.donsun.student.StudentA">
2     <constructor-arg index="0" ref="B"></constructor-arg>
3 </bean>
4 <bean id="B" class="com.donsun.student.StudentB">
5     <constructor-arg index="0" ref="C"></constructor-arg>
6 </bean>
7 <bean id="C" class="com.donsun.student.StudentC">
8     <constructor-arg index="0" ref="A"></constructor-arg>
9 </bean>

Spring容器会将每一个正在创建的Bean 标识符放在一个“当前创建Bean池”中,Bean标识符在创建过程中将一直保在这个池中,因此如果在创建Bean过程中发现自己已经在“当前创建Bean池”里时将抛出BeanCurrentlyInCreationException异常表示循环依赖;而对于创建完毕的Bean将从“当前创建Bean池”中清除掉。

setter循环依赖(单例):

<!--scope="singleton"(默认就是单例方式)  -->
 2 <bean id="A" class="com.donsun.student.StudentA" scope="singleton">
 3     <property name="studentB" ref="B"></property>
 4 </bean>
 5 <bean id="B" class="com.donsun.student.StudentB" scope="singleton">
 6     <property name="studentC" ref="C"></property>
 7 </bean>
 8 <bean id="C" class="com.donsun.student.StudentC" scope="singleton">
 9     <property name="studentA" ref="A"></property>
10 </bean>

这种情况下,Spring先实例化Bean对象 ,此时Spring会将这个实例化结束的对象放到一个Map中,并且Spring提供了获取这个未设置属性的实例化对象引用的方法。当Spring实例化了StudentA、StudentB、StudentC后,紧接着会去设置对象的属性,此时StudentA依赖StudentB,就会去Map中取出存在里面的单例StudentB对象,以此类推,不会出来循环的问题;

下面是Spring源码中的实现方法,。以下的源码在Spring的Bean包中的DefaultSingletonBeanRegistry.Java类中

 1   /** Cache of singleton objects: bean name --> bean instance(缓存单例实例化对象的Map集合) */
 2     private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(64);
 3
 4     /** Cache of singleton factories: bean name --> ObjectFactory(单例的工厂Bean缓存集合) */
 5     private final Map<String, ObjectFactory> singletonFactories = new HashMap<String, ObjectFactory>(16);
 6
 7     /** Cache of early singleton objects: bean name --> bean instance(早期的单身对象缓存集合) */
 8     private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);
 9
10     /** Set of registered singletons, containing the bean names in registration order(单例的实例化对象名称集合) */
11     private final Set<String> registeredSingletons = new LinkedHashSet<String>(64);
12     /**
13      * 添加单例实例
14      * 解决循环引用的问题
15      * Add the given singleton factory for building the specified singleton
16      * if necessary.
17      * <p>To be called for eager registration of singletons, e.g. to be able to
18      * resolve circular references.
19      * @param beanName the name of the bean
20      * @param singletonFactory the factory for the singleton object
21      */
22     protected void addSingletonFactory(String beanName, ObjectFactory singletonFactory) {
23         Assert.notNull(singletonFactory, "Singleton factory must not be null");
24         synchronized (this.singletonObjects) {
25             if (!this.singletonObjects.containsKey(beanName)) {
26                 this.singletonFactories.put(beanName, singletonFactory);
27                 this.earlySingletonObjects.remove(beanName);
28                 this.registeredSingletons.add(beanName);
29             }
30         }
31     }

setter循环依赖(prototype):

 2 <bean id="A" class="com.donsun.student.StudentA" scope="prototype">
 3     <property name="studentB" ref="B"></property>
 4 </bean>
 5 <bean id="B" class="com.donsun.student.StudentB" scope="prototype">
 6     <property name="studentC" ref="C"></property>
 7 </bean>
 8 <bean id="C" class="com.donsun.student.StudentC" scope="prototype">
 9     <property name="studentA" ref="A"></property>
10 </bean>

因为“prototype”作用域的Bean,Spring容器不进行缓存,因此无法提前暴露一个创建中的Bean。抛出BeanCurrentlyInCreationException

32.try{}catch(){}finally{}return各种变化返回值

1、不管有没有出现异常,finally块中代码都会执行;
2、当try和catch中有return时,finally仍然会执行;
3、finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,不管finally中的代码怎么样,返回的值都不会改变,仍然是之前保存的值),所以函数返回值是在finally执行前确定的;
4、finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值。

33.redis回收策略

34.集合迭代效率对比

35.ArrayList与LinkedList区别

36.jvm内存模型

37.java序列化算法

38.红黑树

39.synchronized用到的场景

40.线程池配置关键参数

41.平时用过哪些框架,看过哪些源码以及实现原理

42.画出你做过项目的架构图

43.广度优先遍历与深度优先遍历

44.你觉得你最擅长什么?
45.项目怎么改为分布式?

46.HashMap中有个对象transient Entry[] table,为什么要加上关键字transient呢?

1.看一下HashMap.get()/put()知道, 读写Map是根据Object.hashcode()来确定从哪个bucket读/写. 而Object.hashcode()是native方法, 不同的JVM里可能是不一样的,如果你使用默认的序列化,那么反序列化后,元素的位置和之前的是保持一致的,可是由于 hashCode 的值不一样了,那么定位函数 indexOf()返回的元素下标就会不同,这样不是我们所想要的结果.

2.transient 是表明该数据不参与序列化。因为 HashMap 中的存储数据的数组数据成员中,数组还有很多的空间没有被使用,没有被使用到的空间被序列化没有意义。所以需要手动使用 writeObject() 方法,只序列化实际存储元素的数组。

47.分布式锁使用场景(网易)

48.dubbo版本号作用(网易)

当一个接口实现,出现不兼容升级时,可以用版本号过渡,版本号不同的服务相互间
不引用。
在低压力时间段,先升级一半提供者为新版本
再将所有消费者升级为新版本
然后将剩下的一半提供者升级为新版本

49.秒杀系统设计(网易)

50.内部类与嵌套类区别

51.算法:递归实现回文(网易)

52.算法:程序实现字符串有哪些英文字母空格数字,不能用ascii码来判断

53.zookeeper分布式锁节点与其他节点区别(网易)

PERSISTENT 持久化节点

PERSISTENT_SEQUENTIAL 顺序自动编号持久化节点,这种节点会根据当前已存在的节点数自动加1

EPHEMERAL 临时节点, 客户端session超时这类节点就会被自动删除

EPHEMERAL_SEQUENTIAL 临时自动编号节点

54.项目中遇到的问题以及如何解决的?

55.springMvc完整工作流程,哪些关键的类

56.spring用到的设计模式举例

57.死锁条件

教训:

1.按照STAR法则制作简历;

2.不同的公司岗位需求肯定不同,简历要有针对性,不要只准备一份简历;

3.要按照岗位需求,在项目中突出与之匹配的技能,先过了筛选这关;

4.要准备好才投简历,不然自己心仪的公司让你去面试,结果你没怎么准备,被刷了,那么机会可能就没有了!

5.项目里列出的技术,不能停留于表面的认识,至少你自己心里能过的去,不然你的简历在面试官那里不是羊入虎口吗~!

6.互联网公司比较关注分布式、中间件、并发编程、锁之类的,建议多了解下java并发包以及市面流行的中间件;

原文地址:https://www.cnblogs.com/donfly/p/8124583.html

时间: 2024-11-13 10:18:32

JAVA软件面试之杭州的相关文章

2020 Java核心面试问题 100+(附代码)

[本文参考原文地址]http://bjbsair.com/2020-03-09/it/1875/ 毋庸置疑,Java是获得丰厚薪资的主要编程选择之一.毕竟,基于类的通用,面向对象的编程语言是世界上使用最广泛的编程语言之一. Java面试问题 具有许多强大的功能,编程语言不仅是经验丰富的专家的首选,而且是编程领域的新手所追求的.因此,这里有一些重要的Java面试问题,可以帮助您完成Java工作,或者至少可以提高您的学习水平. 问题:什么是Java? 答:?Java是一种最初由James Gosli

JAVA软件工程师笔试试题

JAVA软件工程师笔试试题 (考试时间:120分钟 试卷分值:150分 ) 一. 逻辑推理题[10分] 1.甲.乙.丙.丁四位同学中有一位同学为海啸灾区捐款1000元,当老师询问时,他们分别这样回答: 甲:这1000元不是我捐的 乙:这1000元是丁捐的 丙:这1000元是乙捐的 丁:这1000元不是我捐的 这四人中只有一个人说了真话,由此可见这1000元是谁捐的( ).[2分] A.甲 B.乙 C.丙 D.丁 2. 甲.乙.丙三人是同一家公司的员工,他们的未婚妻A.B.C也都是这家公司的职员.

java异常面试常见题目

在Java核心知识的面试中,你总能碰到关于 处理Exception和Error的面试题.Exception处理是Java应用开发中一个非常重要的方面,也是编写强健而稳定的Java程序的关键,这自然使它成为面试题中的常客.关于Java中Error和Exception的面试题目多是关于Exception和Error的概念,如何处理Exception,以及 处理Exception时需要遵守的最佳实践等等.尽管关于多线程.垃圾回收.JVM概念和面向对象设计等方面的问题依然主宰着这类面试,你仍然需要为回答

JAVA软件工程师应该具备的技能有哪些?

前言:有朋友问我:学历和能力哪个重要?我个人觉得能力大于学历,没有能力哪来的学历,学历只是证明能力的一方面.为此在能力方面畅谈java软件工程师必备的能力.作为一名合格的java工程师,不仅需要学历,更重要要有扎实的能力(技能)功力. 1.编程语言能力. 作为一名专业的软件工程师,应该能够熟练掌握JAVA语言,并且能够深入理解OOP.OOA.OOD等编程思想.精通一门编程语言能为以后的软件开发打下坚实的基础. 2.编码能力. 这里说的编码可不是照着书本敲代码,而是能够独立的运用代码,编写一个程序

Java多线程面试15道

Java 线程面试问题 在任何Java面试当中多线程和并发方面的问题都是必不可少的一部分.如果你想获得任何股票投资银行的前台资讯职位,那么你应该准备很多关于多线程的问题.在投资银行业务中多线程和并发是一个非常受欢迎的话题,特别是电子交易发展方面相关的.他们会问面试者很多令人混淆的Java线程问题.面试官只是想确信面试者有足够的Java线程与并发方面的知识,因为候选人中有很多只浮于表面.用于直接面向市场交易的高容量和低延时的电子交易系统在本质上是并发的.下面这些是我在不同时间不同地点喜欢问的Jav

Java软件设计模式------装饰设计模式

Java软件设计模式一共分为23种; 一般常用的有: 单例设计模式 装饰设计模式 工厂设计模式 装饰设计模式 定义:英文叫Decorator Pattern,又叫装饰者模式.装饰模式是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能.它是通过创建一个包装对象,也就是装饰来包裹真实的对象. 在生活中我们用程序员和项目经理的例子来比喻,项目经理是从程序员开始的,经过不断地积累工作经验.不断的学习新的知识,才有可能升职. 在装饰设计模式中项目经理就是程序员的增强. 程序猿: 写程序 项目

java模拟面试 试题

java 四类八种基本数据类型 第一类:整型 byte short int long 第二类:浮点型 float double 第三类:逻辑型 Boolean(取值为 true false) 第四类:字符型 char & 与 运算符. | 或 是java中的位运算符,对二进制进行计算,两位都是1返回1,否则返回0. ^ 异或 是java中的位运算符,对二进制进行计算,两位不同返回1,否则返回0. == 可以用来比较引用类型(比较的是虚地址),也可以用来比较基本数据类型(比较的是二进制). 值得注

Java基础面试:集合、内部类、线程

package test; import java.util.Hashtable; import java.util.Map; public class test { public static String change(String param){ param=null; return param; } public static void main(String[] args) { String param1="p1"; param1=change(param1); Map ta

Java多线程面试问题

原文链接:http://ifeve.com/java-multi-threading-concurrency-interview-questions-with-answers/ 多线程和并发问题是Java技术面试中面试官比较喜欢问的问题之一.在这里,从面试的角度列出了大部分重要的问题,但是你仍然应该牢固的掌握Java多线程基础知识来对应日后碰到的问题. Java多线程面试问题 1. 进程和线程之间有什么不同? 一个进程是一个独立(self contained)的运行环境,它可以被看作一个程序或者