写在前面:以下是自己在拟录用后回顾总结的了一下当时面试题目,把标答写了出来,供以后复习所使用,希望大家理性食用~~
预祝大家都能找到心仪的工作
笔试题目:
1.1. java中Collection和Collections的区别
- Collection:
-
- Collection 是一个集合接口,它代表集合框架,Collection 接口定义了操作集合元素的基本方法,比如添加、删除、遍历、查询等。一般来说,通过 Collection 接口的实现类(如 ArrayList、HashSet 等)来操作具体的集合对象。
- Collections:
-
- Collections 是一个工具类,它包含了各种静态方法,用于操作各种集合。这些方法包括对集合进行排序、搜索、同步化等操作。
- Collections 类提供了一系列静态方法,如sort()、binarySearch()、synchronizedCollection() 等,这些方法可以用来操作集合类对象,而不是操作具体的集合元素。
1.2. java中把数组转为list
拓展:数组转list,list转数组
- 数组转list
通过 Arrays.asList(strArray) 方式,将数组转换List后,不能对List增删,只能查改,否则抛异常。
-
- 1. 方式一(最常见,非最佳方法)
private void testArrayCastToListError() {
String[] strArray = new String[2];
List list = Arrays.asList(strArray);
//对转换后的list插入一条数据
list.add("1");
System.out.println(list);
}
执行结果:
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.add(AbstractList.java:148)
at java.util.AbstractList.add(AbstractList.java:108)
at com.darwin.junit.Calculator.testArrayCastToList(Calculator.java:19)
at com.darwin.junit.Calculator.main(Calculator.java:44)
原因:
Arrays.asList(strArray)返回值是java.util.Arrays类中一个私有静态内部类java.util.Arrays.ArrayList,它并非java.util.ArrayList类。java.util.Arrays.ArrayList类具有 set(),get(),contains()等方法,但是不具有添加add()或删除remove()方法,所以调用add()方法会报错。
使用场景:需要在将数组转换为List后,对List进行增删改查操作,在List的数据量不大的情况下,可以使用。
-
- 2.方式二(最高效)
通过Collections.addAll(arrayList, strArray)方式转换,根据数组的长度创建一个长度相同的List,然后通过Collections.addAll()方法,将数组中的元素转为二进制,然后添加到List中,这是最高效的方法。
String[] strArray = {"a","b","c"};
ArrayList< String> arrayList = new ArrayList<String>(strArray.length);
Collections.addAll(arrayList, strArray);
-
- 3.方式三(Java8+的stream API)
Integer[] array = {1, 2, 3, 4, 5};
List<Integer> list = Arrays.stream(array)
.collect(Collectors.toList());
-
- 4.方式四(方式一的改进,可增删)
通过ArrayList的构造器,将Arrays.asList(strArray)的返回值由java.util.Arrays.ArrayList转为java.util.ArrayList。
private void testArrayCastToListRight() {
String[] strArray = new String[2];
ArrayList<String> list = new ArrayList<String>(Arrays.asList(strArray)) ;
list.add("1");
System.out.println(list);
}
- list转数组
//要转换的list集合
List<Integer> testList = new ArrayList<>(){{add(1);add(2);add(3);}};
//使用toArray(T[] a)方法
int[] array2 = testList.toArray(new int[testList.size()]);
//打印该数组
for(int i = 0; i < array2.length; i++){
System.out.println(array2[i]);
}
1.3. cookie和session的区别
- Cookie可以存储在浏览器或者本地,Session只能存在服务器
- session 能够存储任意的 java 对象,cookie 只能存储 String 类型的对象
- Session比Cookie更具有安全性(Cookie有安全隐患,通过拦截或本地文件找得到你的cookie后可以进行攻击)
- Session占用服务器性能,Session过多,增加服务器压力
- 单个Cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个Cookie,Session是没有大小限制和服务器的内存大小有关。
1.4. Thread类start与run区别是什么?
- start() 方法:
-
- 作用:start() 方法用于启动一个新的线程,并执行线程的run()方法。
- 线程生命周期:调用start()方法会在后台启动一个新线程,使得线程处于就绪(Runnable)状态,当获取到CPU时间片后,会调用线程的run()方法来执行具体的任务。
- 并发执行:如果多次调用start()方法,每次都会创建一个新的线程实例,从而可以并发执行多个线程。
- run() 方法:
-
- 作用:run() 方法定义了线程的主要逻辑或任务代码。
- 普通方法调用:直接调用run()方法并不会创建新线程,而是在当前线程中同步执行run()方法的代码块,类似于普通的方法调用。
- 顺序执行:如果通过run()方法来启动线程,那么run()方法中的代码会按照顺序执行,而不会开启新的线程去并发执行。
1.5. throws和throw的区别是什么?
- throws:
-
- throws是一个用于方法签名中的关键字,用来指定方法可能抛出的受检查异常(checked exception),而不是运行时异常(unchecked exception)。它通常用在方法的定义处,用来说明该方法可能会抛出哪些异常,以便调用方(调用该方法的地方)知道需要处理哪些异常。
public void someMethod() throws IOException, SQLException {
// 方法体
}
-
- 在上述例子中,someMethod() 方法声明了可能抛出 IOException 和 SQLException 异常。调用该方法的代码在调用之前必须要么捕获这些异常,要么继续向上抛出这些异常。
- throw:
-
- throw是一个关键字,用于在代码块中显式地抛出一个异常对象。它通常用在方法体内部,用来抛出自定义的异常或者已有的异常实例。
throw new IOException("File not found");
-
- 在上述例子中,throw 语句抛出了一个新创建的 IOException 对象,并且可以选择传递一个描述性的字符串参数,用来描述异常的原因或者上下文信息。
1.6. 详解事务ACID原则
- 原子性(Atomicity):
-
- 原子性指的是事务是一个不可分割的工作单位,事务中的所有操作要么全部完成,要么全部不完成,不存在部分完成的情况。如果事务中的任何一步操作失败,整个事务都会被回滚(Rollback)到事务开始前的状态,以保证数据的一致性和完整性。
- 一致性(Consistency):
-
- 一致性确保了当事务完成时,数据从一个一致性状态转换到另一个一致性状态。事务在执行前后,数据库的完整性约束没有被破坏,如主键、外键、触发器等约束条件依然有效。这保证了数据库的结构和数据在事务开始和结束时都是有效的。
- 隔离性(Isolation):
-
- 隔离性指的是并发执行的事务之间是相互隔离的,一个事务的执行不应该受到其他事务的干扰。即使多个事务并发执行,各个事务之间也不会互相影响,每个事务看到的数据应该是一致的。数据库通过锁定机制来实现事务的隔离性,确保并发执行的事务不会相互干扰。
- 持久性(Durability):
-
- 持久性指的是一旦事务提交,所做的修改将永久保存在数据库中,即使系统发生故障,如数据库崩溃、服务器宕机,也不应该丢失提交的数据。系统通过将事务日志写入非易失性存储(如磁盘)来保证持久性,以便在系统恢复后可以重新应用这些日志,恢复数据的完整性。
1.7. 手写sql
1)查询没有合同的总人数(不可使用子查询):
select count(*) as TotalUsersWithoutContracts
from User u
left join Contract c on u.User_id = c .User_id
where c.Contract_id is null
2)列出所有用户姓名重复的用户姓名:
select DISTINCT(User_name)
from User
group by User_name
having count(User_name) > 1
3)列出2010-01-01至2010-05-01期间,没有登录过系统的用户:
SELECT U.User_name
from User U
left join Log L on U.User_id = L.User_id
where L.Login_time is NULL
and '2010-01-01' <= L.Login_time and L.Login_time <= '2010-05-01';
面试题目:
- Redis缓存击穿是什么?
- 说一下快速排序是怎么实现的?
- 冒泡排序的时间复杂度是多少?最好和最坏一样吗,为什么?
- ThreadLocal的底层数据结构是什么?
- 如何在前端代码中查找想要修改的内容,比如改页面的颜色(没答出来)
- 平时除了使用Mysql还使用过哪些数据库,比如MongoDB、Oracle(没有,只用过Mysql)
- 说说索引的使用场景和注意事项
- 有没有搭过Redis集群(回答没有)
- Redis的常用数据结构有哪些?
- 使用过哪些常用的linux命令,怎么查看当前运行进程的端口?
答:ps,追问:ps后面是什么,答:ps aux | grep "要查询的进程名称"
- top命令是什么?用过吗(回答没用过)
- 说一下SpringMVC中前端发送请求到后端执行的具体流程
- 具体说一下cookie和session的区别?session的底层数据结构是什么?
- 前端页面如何设置计时任务,比如设置10秒后显示一个图片?(不会,没答出来)
- 场景题:为什么要使用Redis,它的使用场景是什么,如果现在有一百万条访问量的数据,该如何存储?(说了一下Redis的缓存机制及作用,设置热点数据等等,感觉答的有点偏)