2021/6/17 科韵智慧科技公司面试总结
一开始就是自我介绍,然后简单介绍一下简历上的项目,作为一个零项目的菜鸟,我把学校的课程设计写上去了。就大概说了一个项目是怎么什么的,没深问项目。之后就开始问问题。
1、怎么理解Java的跨平台性,它是怎么做到跨平台、实现独立性的?
我们编写的Java源码,编译后会生成一种 .class 字节码文件,Java虚拟机就是负责将字节码文件翻译成特定平台下的机器码,然后运行。也就是说,只要在不同平台上安装对应的JVm,就可以运行字节码文件,运行我们编写的Java程序。
2、说下JDK和JRE 的区别
- JDK(Java Development Kit):Java开发工具包,提供了Java的开发环境和运行环境。
- JRE(Java Runtime Environment):java运行环境,为Java的运行提供了所需环境。
具体来说JDK其实包含了JRE,同时还包含了编译Java源码的编译器Javac,还包含了很多Java程序调试和分析的工具。简单来说:如果你需要运行Java程序,只需安装JRE就可以了,如果你需要编写Java程序,需要安装JDK。
我面试的时候给说反了(┬┬﹏┬┬)
3、Java的8种数据类型
short、int、long、float、double、boolean、byte、char
4、重载和重写的区别
5、Java异常的体系结构
Java 中的异常类均以 Throwable 类为父类,而 Throwable 又派生出 Error类 和 Exception类 这两大子类。Exception 类及其子类又可以划分为两大类:运行时异常、非运行时异常。
6、Error和Exception有什么区别?
- Error:代表 JVM 自身的异常,无法通过程序来修正,最可靠的方式就是尽可能快地停止 JVM 的运行。
- Exception:代表程序运行中发生了意料之外的事情,这些意外的事情可以被Java异常处理机制处理。
7、常见的异常
空指针异常、字符串转换为数字异常、数组下标越界异常、方法传递参数异常、数据类型转换异常
8、异常的处理方式,有什么区别?
处理异常主要有两种方式:一种try catch,一种是throws。
- try / catch:try{} 中放入可能发生异常的代码。catch{} 中放入对捕获到异常之后的处理。
- throw、throws:
- throw 是语句抛出异常,出现于方法内部,用来抛出一个具体异常实例,throw 被执行后面的语句不起作用,直接转入异常处理阶段。
- throws是函数方法抛出异常,一般写在方法的头部,抛出异常,给方法的调用者进行解决。
9、说一下finally块
- finally是一个关键字。
- finally在异常处理时提供 finally 块来执行任何清除操作。不管有没有异常被抛出或者捕获,finally块都会执行,通常用于释放资源。
- finally块正常情况下一定会被执行。但是有至少两个极端情况:
- 如果对应的try块没有执行,则这个try块的finally块并不会被执行。
- 如果在try块中JVM关机,例如System.exit(n),则finally块也不会执行(都拔电源了,怎么执行)
- finally块中如果有return语句,则会覆盖try或者catch中的return语句,导致二者无法return,所以强烈建议finally块中不要存在return关键字。
- try块里面有return语句,finally块里面的语句也会执行。
10、说一下你在使用HashMap过程中,对它的认识。
- HashMap 是基于哈希表实现的,每一个元素是一个键值对,其内部通过单链表或者红黑树解决冲突问题,容量不足(超过了阀值)时,会自动扩容。
- HashMap是非线程安全的,只适用于单线程环境,多线程环境可以采用并发包下的concurrentHashMap。
- HashMap 实现了Serializable接口,因此它支持序列化,实现了Cloneable接口,能被克隆。
- HashMap是基于哈希表的 Map 接口的非同步实现,此实现提供所有可选的映射操作,并允许使用 null 值和 null 键,此类不保证映射的顺序,特别是它不保证该顺序恒久不变。
我觉得这个没有固定答案,随便说说HashMap的特性应该都可以。
11、说一下HashMap的扩容机制
HashMap 每次扩容都是建立一个新的 table 数组,长度和容量阈值都变为原来的两倍,然后把原数组元素重新映射到新数组上,具体步骤如下:
- 首先会判断 table 数组长度,如果大于 0 说明已被初始化过,那么按当前 table 数组长度的 2 倍进行扩容,阈值也变为原来的 2 倍;如果旧数组容量已经是最大值了,那只需把 threshold 阈值设为整数的最大值即可;
- 若 table 数组未被初始化过,且 threshold(阈值)大于 0 说明调用了 有参构造方法,那么就把数组大小设为 threshold;
- 若 table 数组未被初始化,且 threshold 为 0 说明调用无参构造方法,那么就把数组大小设为 16,threshold 设为 16*0.75;
- 接着需要判断如果不是第一次初始化,那么扩容之后,要重新计算键值对的位置,并把它们移动到合适的位置上去,如果节点是红黑树类型的话则需要进行红黑树的拆分。
12、HashMap的初始容量是多少?
在一开始初始化 HashMap 的时候,并没有初始化里面的数组 table,所以一开始 HashMap 的容量是0。
13、你平时是怎么学习这些知识的?
14、在项目中有用到多线程吗?说一下多线程。
我这里回答了多线程的实现方式:
- 继承Thread类
- 实现 Runnable 接口
- 实现 Callable 接口
- 线程池
- 容量为1的单一线程池
- 容量固定的线程池
- 容量不固定的线程池
- 自定义线程池
15、实现 Runnable 接口 和 实现 Callable 接口 有什么区别?
- Runnable 接口:调用 run() 方法,没有返回值,不需要抛出异常
- Callable 接口:调用 call() 方法,有返回值,返回值类型是泛型,需要抛出异常
16、自定义线程池的7大参数、4大拒绝策略
17、线程池的工作流程
18、HashMap 是线程安全的吗?
HashMap 是线程不安全的,ConcurrentHashMap 才是线程安全的。
19、JUC包下的 ConcurrentHashMap 这类集合,有用过吗?
我回答在学习JUC的时候有了解过,但是没有实际使用过,之后面试官就没有再问我这个知识点,转到了下一个话题。
20、如果存在线程安全的话,怎么解决线程安全这个问题呢?
- 将数据设置为仅读。
- 加锁:sychronized锁或者lock锁。
21、synchronizd 和 lock 锁的区别
- sychronized 是一个内置关键字,lock 是一个类;
- sychronized 是一个隐式锁,出了作用域会自动释放锁,lock 是显式锁,需要手动释放锁;
- Synchronized 无法得知是否获取锁成功,Lock可以判断是否获取了锁;
- Synchronized 如果线程获取不到锁,就傻傻地等;Lock锁就不一定会等待下去;
- synchronized 有代码块锁和方法锁,Lock只有代码块锁。
- Synchronized 可重入锁,不可以中断的,非公平锁;Lock 可重入锁,可以中断锁,默认非公平锁(可以自己设置);
- Synchronized 适合锁少量的代码同步问题,Lock 适合锁大量的同步代码!
22、JDK8 的新特性
- Lambda 表达式 : Lambda 允许把函数作为一个方法的参数(函数作为参数传递到方法中)。
- 方法引用:可以直接引用已有Java类或对象(实例)的方法或构造器。
- 默认方法 :默认方法就是一个在接口里面有了一个实现的方法。
- Stream API :新添加的Stream API(java.util.stream) 把真正的函数式编程风格引入到Java中。
- Date Time API:加强对日期与时间的处理。
- Optional 类 :Optional 类已经成为 Java 8 类库的一部分,用来解决空指针异常。
网上有好多答案,随便说两三个应该就可以了。
23、再问一下项目中的技术,在项目中用到了 mysql,说一下 mysql 的优化吧
我的回答不知道对不对,大家可以参考一下:
如果是想要提高查询效率,可以使用索引,通过 explain 来分析一条 sql 语句的优劣。
24、explain 查询结果中,有哪几个字段是比较有用的?
- id:表示SQL的执行顺序,从大到小开始执行
- id相同时,执行顺序由上至下;
- 如果是子查询,id的序号会递增,id值越大优先级越高,越先被执行;
- id如果相同,可以认为是一组,从上往下顺序执行;在所有组中,id值越大,优先级越高,越先执行;
- select_type:主要用来区分查询的类型,如普通查询、联合查询、子查询等类型。
- table:显示这一步所访问数据库中表名称(显示这一行的数据是关于哪张表的),不一定是真实的表名字,可能是别称,也可能是第几步执行的结果的简称。
- ⭐type:关键参考项之一,表示MySQL在表中找到所需行的方式,又称“访问类型”。比如找到所需行是通过全文搜索,还是借助索引,或者其他方式。
- possible_keys:显示可能应用在这张表中的索引,一个或多个。查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询实际使用。
- ⭐key:显示MySQL实际决定使用的键(索引),必然包含在possible_keys中。如果没有选择索引,键是NULL。
- key_len:显示MySQL决定使用的键长度,在不损失精确性的情况下,长度越短越好。
- ⭐ref:表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值。
- ⭐rows:显示MySQL认为它执行查询时必须检查的行数。
- filtered:(MySQL 5.7缺省就会输出filtered),它指返回结果的行占需要读到的行(rows列的值)的百分比。
- ⭐Extra: 包含MySQL解决查询的详细信息,也是关键参考项之一。
以上是 explain 的大部分字段,加了⭐的,是我认为比较重要的字段。
25、mysql建立索引的原则?
- 索引不是越多越好。 每个额外的索引都要占用额外的磁盘空间,并降低写操作的性能。在修改表的内容时,索引必须进行更新,有时可能需要重构。因此,索引越多,所花的时间越长。
- 不要对经常变动的数据加索引。
- 小数据量的表没必要加索引。
- 索引一般加在常用来查询的字段上。 最适合索引的列是出现在WHERE子句中的列,或连接子句中指定的列,而不是出现在SELECT关键字后的选择列表中的列。
26、建立复合索引时应该注意些什么?
我回答最左前缀匹配原则,然后举例解释一下最左前缀匹配原则,比如在 a、b、c三个字段上建立联合索引,只有当查询字段为 a、ab、abc 这三种情况才有可能使用该联合索引树进行查询。
27、写SQL的熟练程度怎么样?
28、join 、left join 、right join 有什么区别?
- join:取两个表的公共部分
- left join:以左边的表为主,右边表对应的数据如果不存在,则填null
- right join:以右边的表为主,左边的表对应的数据如果不存在,则填null
29、假设现在有两个表A、B,我只想取A表中存在的、B表中不存在的数据,SQL应该怎么写?
这个之前在牛客网的SQL编程题中做过,但是我没回答出来o(╥﹏╥)o
30、有用过什么框架吗?SSM、SpringBoot之类的,还有 Redis 数据库?
我的回答是都没有,我简历上的项目经验其实都是学校的课程设计,用的纯Java,自己看学习视频学过Spring,但是没有实际应用过,这一点我觉得是我找工作的一个很大的劣势,有部分公司招聘要求上会明确要求会框架的。
31、那你Spring学到哪里了
(这里我其实没有准备,但是她问到了,我就想试试脑子里还记得多少)了解IOC、AOP的原理,xml配置文件、注解自动配置这些。
32、简单说一下IOC和AOP吧
我这里只解释了IOC,说完IOC,我脑海突然想起Spring创建bean的三种方式,然后我就自顾自地说下去,完全忘了提问中还有AOP,面试官也没打断我,就这么继续下去。
33、你刚提到了注解,那注解你举几个例子
(听到问题一脸懵,我真的忘了,好几周之前学的Spring,还只是看过视频,没有实战过)我就说了一个 @Bean
、 @Value
,但是面试官好像不太满意。接着问:你刚刚说可以使用注解创建Bean,有哪几个注解呢?这个我其实没回答出来,面试官还提示了,但是我没想起来,事后去查了一下笔记,归纳常见注解如下:
- 用于注册 Bean 对象的注解
- @Component:pojo包,创建 bean 对象
- @Repository:dao包
- @Service:service包
- @Controller:controller包
- @Bean:用于把当前方法的返回值作为bean对象存入spring的ioc容器中
- 用于依赖注入的注解
- @Autowired:默认按照类型来装配(byType)
- @Resource:默认按照名称来装配(byName)
- @Qualifier:在自动按照类型注入的基础之上,再按照 Bean 的 id 注入。它在给字段注入时不能独立使用,必须和 @Autowire一起使用;但是给方法参数注入时,可以独立使用。
- @Value:通过@Value可以将外部的值动态注入到Bean中,可以为基本类型数据和String类型数据的变量注入数据
- 改变 Bean 作用范围的注解:
- @Scope:指定bean的作用范围。单例、多例等等
- 生命周期相关的注解
- @PostConstruct:指定初始化方法
- @PreDestroy:指定销毁方法
@Resource 的装配顺序:
1.如果同时指定name和type属性,则找到唯一匹配的bean装配,未找到则抛异常;
2.如果指定name属性,则按照名称(byName)装配,未找到则抛异常;
3.如果指定type属性,则按照类型(byType)装配,未找到或者找到多个则抛异常;
4.既未指定name属性,又未指定type属性,则按照名称(byName)装配;如果未找到,则按照类型(byType)装配。
34、@AutoWired 和 @Resource 有什么区别
35、在开发过程中遇到问题,你是怎么处理的
36、你觉得你是一个比较爱学习的人吗?
这是一个视频面试,用的腾讯会议。整个过程大概用了 50min 左右,问的都是比较基础的问题,网上面经都有的,没有问算法。面试官比较友好,如果回答说错了,她不会纠正你,而是听完回答就继续提问下一题。面试体验感还不错!
#面经##校招##科韵智慧##Java工程师#