T · Java
面试官表述特别清晰,是那种会担心我没有听懂题目的程度。
一、算法与数据结构
面:平时刷题多吗?
答:不多。【笑话,我哪敢说多】
题目:LC13. 罗马数字转整数。
【本菜鸡看到这题紧张得要死,不知道该用啥。最后用了十多个 if else,真的很想死!凉透了!!】
二、Java 基础
> 感觉面试官用的是一套可以用来问很多面试者的题,宽度比较广,深度不咋深。
1. == 和 equals 有什么区别?
答:== 比较的是地址,equals 比较的是内容。【这里应该回答 equals 是看类怎么写的】比如 String 类型,== 比较的就是两个 String 是不是同样的地址,equals 比较的是二者的内容是否一致。
追问:String a = "123"; String b = "123"; a == b 是什么?
答:由于 String 用的是常量池,使用上述方式创建的 a 和 b 指向的都是同一个字符串对象,所以答案应该是 true。
2. final 关键字的用法?
答:1) 变量是防止被修改;2) 类是防止被继承。【前两天刚好看了一眼 String 的结构,发现它被 final 修饰,不允许被继承】
追问:修饰方法呢?
答:不知道。
正解:
- 1) 对于一个 final 变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。
- 2) 修饰方法第一个原因是把方法锁定,以防任何继承类修改它的含义;第二个原因是效率。类的 private 方法会隐式地被指定为 final 方法。
- 3) 当用 final 修饰一个类时,表明这个类不能被继承。
3. 浅拷贝和深拷贝的区别是什么?
答:浅拷贝就是浅浅地拷贝一下,对基本数据类型是复制一份的,但是引用类型不会复制。深拷贝就是引用类型也会拷贝一份。
4. MyBatis 中 # 和 $ 的区别?
答:不知道,平时不咋用到。
正解:MyBatis 提供了两种支持动态 sql 的语法:#{} 以及 ${}, 其最大的区别则是前者方式能够很大程度防止sql注入(安全),后者方式无法防止Sql注入 。
5. MySQL 简单语句考察。商品表,type 和 id,问 type 对应的商品有多少种?
答:SELECT type, COUNT(id) AS cnt FROM t GROUP BY type
6. 聚集索引和非聚集索引是什么?
答:聚集索引是索引和索引的数据在一起;非聚集索引是索引和索引的数据不在一起。【尴尬的沉默...咱也不知道哪儿背的面经,净在这瞎说】
正解:聚集索引和非聚集索引是指物理存储的方式,InnoDB 的默认数据结构是聚簇索引,MyISAM 是非聚簇索引。聚簇索引的表索引和数据是通过聚合的方式结合,非聚簇索引的表索引和数据没有聚合。
追问:一个表里的主键是不是聚集索引呢?
答:InnoDB 里面的主键可以是聚集索引。【我猜测的,有没有知道的兄弟说一说】
7. 数据库中事务的原子性是什么?
答:从 begin 到 commit 中间的语句要么全部执行,要么全部都不执行。
8. Maven package 和 deploy 有什么区别?
答:不知道。【可恶,上个月还整理过,转眼咱就忘掉!】
正解:生命周期(lifecycle)主要包括clean、resources、complie、install、pacakge、testResources、testCompile、deploy等,其中带test开头的都是用业编译测试代码或运行单元测试用例的。
mvn clean package依次执行了clean、resources、compile、testResources、testCompile、test、jar(打包)等7个阶段。
mvn clean install依次执行了clean、resources、compile、testResources、testCompile、test、jar(打包)、install等8个阶段。
mvn clean deploy依次执行了clean、resources、compile、testResources、testCompile、test、jar(打包)、install、deploy等9个阶段。
由上面的分析可知主要区别如下,
package命令完成了项目编译、单元测试、打包功能,但没有把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库和远程maven私服仓库
install命令完成了项目编译、单元测试、打包功能,同时把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库,但没有布署到远程maven私服仓库
deploy命令完成了项目编译、单元测试、打包功能,同时把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库和远程maven私服仓库
————————————————
版权声明:本文为CSDN博主「阿童木-atom」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zhaojianting/article/details/80324533
9. 进程和线程的区别?
答:1) 定义:进程是操作系统进行资源调度的基本单位,线程是执行的基本单位。2) 线程会共享一些进程的资源,比如堆和方法区。3) 进程的崩溃不会影响其他的进程,但是线程的崩溃可能会导致其他线程一起崩溃。【这道题至少被问了 5 次,每次都答不利索】
正解:
1) 本质区别:进程是操作系统资源分配的基本单位,而线程是任务调度和执行的基本单位
2) 在开销方面:每个进程都有独立的代码和数据空间(程序上下文),程序之间的切换会有较大的开销;线程可以看做轻量级的进程,同一类线程共享代码和数据空间,每个线程都有自己独立的运行栈和程序计数器(PC),线程之间切换的开销小
3) 所处环境:在操作系统中能同时运行多个进程(程序);而在同一个进程(程序)中有多个线程同时执行(通过CPU调度,在每个时间片中只有一个线程执行)
4) 内存分配方面:系统在运行的时候会为每个进程分配不同的内存空间;而对线程而言,除了CPU外,系统不会为线程分配内存(线程所使用的资源来自其所属进程的资源),线程组之间只能共享资源
5) 包含关系:没有线程的进程可以看做是单线程的,如果一个进程内有多个线程,则执行过程不是一条线的,而是多条线(线程)共同完成的;线程是进程的一部分,所以线程也被称为轻权进程或者轻量级进程
10. i++ 是线程安全的吗?
答:不是。
11. 什么是 AOP?
答:面向切面编程。对非核心业务代码的提取。
正解:
在Java平台上,对于AOP的织入,有3种方式:
1) 编译期:在编译时,由编译器把切面调用编译进字节码,这种方式需要定义新的关键字并扩展编译器,AspectJ就扩展了Java编译器,使用关键字aspect来实现织入;
2) 类加载器:在目标类被装载到JVM时,通过一个特殊的类加载器,对目标类的字节码重新“增强”;
3) 运行期:目标对象和切面都是普通Java类,通过JVM的动态代理功能或者第三方库实现运行期动态织入。
最简单的方式是第三种,Spring的AOP实现就是基于JVM的动态代理。由于JVM的动态代理要求必须实现接口,如果一个普通类没有业务接口,就需要通过CGLIB或者Javassist这些第三方库实现。 Spring对接口类型使用JDK动态代理,对普通类使用CGLIB创建子类。如果一个Bean的class是final,Spring将无法为其创建子类。
12. redis 中两个线程 a 和 b 同时获取到一个锁,a 拿到锁了,但是卡住了。请问怎么办?
答:给锁设置一个过期时间,等时间一过,就释放资源给其他线程用。【不知道咋回答,我瞎说的】
13. 什么是反射?
答:通过类的全限定名称获取到类的类加载器,然后再通过类加载器获取到 class,用于运行时绑定等场景。
追问:反射有什么好处?一般在什么情况下会用到?
答:Spring Boot 中有很多反射的场景,好处主要是可以多态。【开始胡说八道...】
正解:通过Class实例获取class信息的方法称为反射(Reflection)。Java 的反射是指程序在运行期可以拿到一个对象的所有信息。反射是为了解决在运行期,对某个实例一无所知的情况下,如何调用其方法。反射甚至可以获取私有的方法和变量。
Java标准库提供了一种动态代理(Dynamic Proxy)的机制:可以在运行期动态创建某个interface的实例。我们先定义接口Hello,但是我们并不去编写实现类,而是直接通过JDK提供的一个Proxy.newProxyInstance()创建了一个Hello接口对象。这种没有实现类但是在运行期动态创建了一个接口对象的方式,我们称为动态代码。JDK提供的动态创建接口对象的方式,就叫动态代理。动态代理是通过Proxy创建代理对象,然后将接口方法“代理”给InvocationHandler完成的。
14. 接口和抽象类有什么区别?
答:抽象类是对实体的抽象,接口是对属性的抽象。【这里说错了,是对行为的抽象。】接口可以多继承。
正解:
1、语法层面上的区别
1)抽象类可以提供成员方法的实现细节,而接口中只能存在public abstract 方法;
2)抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的;
3)接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态方法;
4)一个类只能继承一个抽象类,而一个类却可以实现多个接口。
2、设计层面上的区别
1)抽象类是对一种事物的抽象,即对类抽象,而接口是对行为的抽象。
2)设计层面不同,抽象类作为很多子类的父类,它是一种模板式设计。而接口是一种行为规范,它是一种辐射式设计。
15. 什么是单例模式?
答:一个类只初始化一个对象。【真的不知道该咋说】
正解: 这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。 这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
双重校验锁实现单例模式
public class Singleton {
private static volatile Singleton instance = null;
private Singleton(){}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
16. Linux 用得多吗?
答:不多,每次都是百度或者 man help。
问:查看某个进程存不存在?
答:你看我清澈的眼神。【乖巧.jpg】
问:文本的最后几行?
答:tail!【骄傲.jpg】
问:或许知道是什么参数吗?
答:不知道!
正解:ps,tail -n
三、技术【个人特色,面试官会根据项目进行提问】
1. Kafka 消息队列
我真是疯了才把 Kafka 写简历上!我只知道调用接口,我是个调包侠啊!
消息队列的作用是异步、解耦、限流削峰。消息队列包括两种模式,点对点模式(point to point, queue)和发布/订阅模式(publish/subscribe,topic)
Kafka是一个分布式,分区的,多副本的,多订阅者的消息发布订阅系统(分布式MQ系统),可以用于搜索日志,监控日志,访问日志等。
Kafka对消息分类使用topic(一个分类,一个类别)
生产者:Producer(制造数据、生产数据的,将消息推送到队列的)
消费者:Consumer(读取数据的,浏览数据的,在队列中获取数据)
服务器:Broker
Kafka的优点:
1、可靠性:分布式的,分区,复制和容错。 2、可扩展性:kafka消息传递系统轻松缩放,无需停机。 3、耐用性:kafka使用分布式提交日志,这意味着消息会尽可能快速的保存在磁盘上,因此它是持久的。 4、性能:kafka对于发布和定于消息都具有高吞吐量。即使存储了许多TB的消息,他也爆出稳定的性能。 kafka非常快:保证零停机和零数据丢失
2. 你觉得你实习的项目里面,有哪些比较特别的价值点?有挑战性的内容?
答:需求都比较简单。【要不你看看我清澈的眼神?】
四、扯卵谈
1. 为什么想要加入我们公司?
答:你们公司牛啊!我特别喜欢你们公司所在的城市!
评价
对面试官的打分:7 / 10 【深度不够 -1,我做题的时候让我在二十分钟的时间里独自写了十几个 if else -1,项目没咋问 -1】
对本人的打分: 3 / 10 【写了十几个 if else -5,基础乱答 -1,实习没价值-1】
记录 Java 后端面试经验