Java实习面试题
笔试
1. 请说明重载(Overload)和重写(Override)的区别。重载的方法能否根据返回类型进行区分?
重载:
发生在一个类中,方法名相同,参数列表不同。
Java允许重载任何方法,而不只是构造器方法。
因此要完整地描述一个方法,需要指定方法名以及参数类型。(这叫做方法的签名)
例如,String类有4个名为indexOf的公共方法。它们的签名是
indexOf(int)
indexOf(int, int)
indexOf(String)
indexOf(String, int)
返回类型不是方法签名的一部分。所以,不能有两个名字相同、参数类型也相同却有不同返回类型的方法。
以下不构成重载
public double add(int a,int b)
public int add(int a,int b)
重写:
发生在子类继承父类时。当超类中的一些方法不适用于子类。子类就需要提供一个新的方法来覆盖超类中的这个方法。也就是重写。
返回值类型,方法名相同,参数列表也相同。
如果想调用超类中的方法,可以使用关键字super。例如super.getSalary();
2. 给一个Person类,把List转成Map
3. 使用BigDecimal进行运算
java.math包中的BigDecimal类可以实现任意精度的浮点数运算。
BigDecimal常用构造函数:
BigDecimal(int) // 创建一个具有参数所指定整数值的对象
BigDecimal(double) // 创建一个具有参数所指定双精度值的对象
BigDecimal(long) // 创建一个具有参数所指定长整数值的对象
BigDecimal(String) // 创建一个具有参数所指定以字符串表示的数值的对象
不能使用算术运算符处理(如,“+”,“*”),需要使用add和multiply方法。
// BigDecimal常用方法
add(BigDecimal) //BigDecimal对象中的值相加,返回BigDecimal对象
subtract(BigDecimal) //BigDecimal对象中的值相减,返回BigDecimal对象
multiply(BigDecimal) //BigDecimal对象中的值相乘,返回BigDecimal对象
divide(BigDecimal) //BigDecimal对象中的值相除,返回BigDecimal对象。
toString() //将BigDecimal对象中的值转换成字符串
doubleValue() //将BigDecimal对象中的值转换成双精度数
floatValue() //将BigDecimal对象中的值转换成单精度数
longValue() //将BigDecimal对象中的值转换成长整数
intValue() //将BigDecimal对象中的值转换成整数
4. 删除数据库表中重复字段
5. 给一个静态类,里面有一个非静态字段。求try,catch,finally之后的结果。
6. 懒汉式的线程不安全怎么改。
public class Singleton {
private Singleton(){}
private volatile static Singleton instance;
public static Singleton getInstance(){
if(instance == null){
synchronized(Singleton.class){
if(instance == null){
instance = new Singleton();
}
}
}
return instance;
}
}
最好使用枚举来实现单例模式
【狂神说Java】单例模式-23种设计模式系列
漫画:什么是单例模式? – 小灰的文章 – 知乎
面试
1. servlet生命周期
servlet的生命周期分为:加载Servlet,实例化,初始化,处理请求,卸载Servlet
- servlet初始化之后调用init()方法
- 然后调用service()方法处理客户端请求
- 销毁前调用destory()方法
- 最后,servlet由jvm的垃圾回收器进行回收
2. spring和spring boot的区别
spring是个容器,可以用来整合其他的框架。
而spring boot是一个开发的脚手架,可以通过starter来开启其他的框架。
spring boot的核心在于它的自动装配。EnableAutoConfiguration
注解
spring boot和SSM开发中有什么区别? – 陈龙的回答 – 知乎
淘宝一面:“说一下 Spring Boot 自动装配原理呗?” – JavaGuide的文章 – 知乎
3. ArrayList和LinkedList的区别
ArrayList:
查询效率高,增删改效率低。因为插入需要移动插入位置后的所有元素。但是当插入的元素离末尾很近的时候效率就不低。
底层是动态数组,占用的内存是连续的,所以遍历的效率很高。
LinkedList:
查询效率低,增删改效率高。
更加占用内存,因为需要存放指向前节点和后节点的引用。
坑人无数的Java面试题之ArrayList – 老钱的文章 – 知乎
ArrayList和LinkedList区别及使用场景_ForgetSky的博客-CSDN博客_arraylist和linkedlist
4. HashSet和HashMap的区别
HashSet:
实现了Set接口,它不允许集合中出现重复元素。
HashMap:
实现了Map接口,Map接口对键值对进行映射。Map中不允许出现重复的键(Key)。
HashSet与HashMap的区别 – 崔先森 – 博客园
java中Map有哪些实现类和使用场景_此心光明,亦复何言~-CSDN博客_map实现类
HashMap实现原理及源码分析 – dreamcatcher-cx – 博客园
5. 数据结构中的树有哪些?介绍二叉树。
6. spring cloud怎么调用服务
Eureka作为注册中心,各个服务提供者把自己注册给Eureka。
服务之间的调用是使用RestTemplate,使用Ribbon进行负载均衡。
但是由于使用RestTemplate进行调用很麻烦,每次都得使用它的api。
为了像原代码一样直接进行各个服务之间的调用,可以采用映射的方式,被调用的服务映射到消费者端,也就是使用OpenFeign
通过使用@FeignClient
注解来指定提供者的名字
然后就可以在Controller层像调用Service层一样调用
Spring Cloud 入门总结 – 老刘的文章 – 知乎
7. mybatis中#{}和${}有什么区别
-
#{}
是预编译处理,${}是字符串替换。 - mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;
- mybatis在处理 $ { } 时,就是把 ${ } 替换成变量的值。
- 使用 #{} 可以有效的防止SQL注入,提高系统安全性。
对于这个题目要抓住两点:
(1)$ 符号一般用来当作占位符,常使用Linux脚本的人应该对此有更深的体会吧。既然是占位符,当然就是被用来替换的。知道了这点就能很容易区分$和#,从而不容易记错了。
(2)预编译的机制。预编译是提前对SQL语句进行预编译,而其后注入的参数将不会再进行SQL编译。我们知道,SQL注入是发生在编译的过程中,因为恶意注入了某些特殊字符,最后被编译成了恶意的执行操作。而预编译机制则可以很好的防止SQL注入。
回答2
${param}传递的参数会被当成sql语句中的一部分,比如传递表名,字段名
<!-例子:(传入值为id)-->
order by ${param}
<!-则解析成的sql为:-->
order by id
<!-这时只能用${},因为用#{}后会变成order by "id" 这是不合法的-->
#{parm}传入的数据都当成一个字符串,会对自动传入的数据加一个双引号
<!-例子:(传入值为id)-->
select * from table where name = #{param}
<!-则解析成的sql为:-->
select * from table where name = "id"
为了安全,能用#的地方就用#方式传参,这样可以有效的防止sql注入攻击
回答3#{}
的参数替换是发生在 DBMS 中,而 ${} 则发生在动态解析过程中。
8. 介绍一下数据库中的索引
索引(Index)是帮助MySQL高效获取数据的数据结构。
所以,索引是一种数据结构,可以快速检索数据库中的数据。
索引分类:
- 主键索引(PRIMARY KEY):唯一的标识,主键不可重复,只能有一个列作为主键。
- 唯一索引(UNIQUE KEY):避免重复的列出现,唯一索引可以重复,多个列都可以被标识为唯一索引。
- 常规索引(KEY/INDEX):默认的,可以用key或者index来设置。
- 全文索引(FullText):在特定的数据库引擎下才有,快速定位数据。
常见的MySQL主要有两种结构:Hash索引和B+ Tree索引,MySQL目前默认使用的是InnoDB引擎,默认的是B+树
我以为我对Mysql索引很了解,直到我遇到了阿里的面试官 – walking的文章 – 知乎
9. JDBC操作数据库的步骤
1. 加载数据库驱动
2. 连接数据库
3. 创建Statement对象
4. 执行sql语句
5. 处理结果集
6. 关闭数据库连接
public static void main(String[] args) throws ClassNotFoundException, SQLException {
// 1、加载驱动
Class.forName("com.mysql.jdbc.cj.Driver"); // 固定写法
// 2、连接信息:用户信息和url
String url = "jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=true";
String username = "root";
String password = "123456";
// 3、连接成功,返回数据库对象 Connection代表数据库
Connection connection = DriverManager.getConnection(url, username, password);
// 4、执行sql对象 Statement就是用来执行sql的对象
Statement statement = connection.createStatement();
// 5、使用sql对象去执行sql,执行后可能存在结果,要查看返回结果
String sql = "select * from users";
ResultSet resultSet = statement.executeQuery(sql); //返回的结果集
while(resultSet.next()){
System.out.println(resultSet.getObject("id"));
}
// 6、释放连接
resultSet.close();
statement.close();
connection.close();
}