写在前面
本集锦预计持续更新,分享笔者面试时被一些平时不太关注的知识点拷打的经验。。。
大家引以为戒,知识图谱一定要全面且结合工程实践啊。
平时多看看和自己技术栈相关的开源项目,很有用。
1. 为什么要用List,不直接用ArrayList?
List<Integer> l = new ArrayList<>();
形如以上代码,为什么接口要用List,不直接用ArrayList? List中实现了ArrayList的各种方法吗?为什么不用更大的接口Collection呢?
这道题本质上在考察Java中接口的运用和面向接口编程的理念。
(1)为什么接口要用List,不直接用ArrayList?
首先要明确,List是接口,接口中的大部分方法只有定义,没有实现,高度依赖于实现类;而ArrayList是实现类,负责实现接口中定义的各种方法。注意,Java 8 及以后:允许接口包含默认实现/静态实现,使用default/static关键字修饰即可。Java 9 及以后,接口也支持实现私有方法。
答:
A. 为了遵循面向接口编程原则。通过依赖抽象(接口)而不是具体实现(类),可以降低代码之间的耦合性,提高模块化程度。这使得代码更容易维护和测试。
B. 通过将变量声明为 List 类型,你可以将代码与具体的实现解耦,提高灵便性和可拓展性。如果将来需要将 ArrayList 替换为其他 List 的实现,只需要更改实例化的部分,而不需要修改使用该变量的所有代码。因为 List 中定义的方法对于所有 List 的实现类来说都是存在的。
// 面向接口:后续可轻松切换实现
List<String> list = new ArrayList<>();
list = new LinkedList<>(); // 无需修改其他代码
// 直接依赖实现类:更换实现需修改多处
ArrayList<String> list = new ArrayList<>();
// 若改为 LinkedList,需修改所有声明为 ArrayList 的地方
注意,以上代码切换类型的时候并不会自动保存原类型的数据,如果要保存,参考如下:
List<String> arrayList = new ArrayList<>();
arrayList.add("A");
arrayList.add("B");
// 创建 LinkedList 并复制数据
List<String> linkedList = new LinkedList<>(arrayList)
// 或者使用 addAll 方法
List<String> linkedList2 = new LinkedList<>();
linkedList2.addAll(arrayList);
C. 便于与Java工具类和方法协作。Java的许多工具类和方法(如 Collections 类中的方法)通常返回接口类型,而不是具体实现类型。如果你的代码使用 List 类型声明变量,可以更自然地与这些方法配合使用。
(2) List中实现了ArrayList的各种方法吗?
答:
大部分常用的方法在 List 中定义,例如 get 、add、remove 等,但一般没有实现,接口方法的实现通常依赖于具体的实现类。 当然也有例外,基本上每一个实现类都有自己独特的方法,例如 ArrayList 的 trimtoSize ,如果确有必要使用这些独特的方法,则不能使用接口 List 。
(3)为什么不用更大的接口Collection呢?
答:
这个答案很简单,因为很多属于列表的方法在Collection里面没定义,用不了。在面向接口编程的时候,我们通常优先考虑最小的那个接口。
2. try () ... catch 语句中的try后的圆括号代表什么?
答:
在 Java 的 try () ... catch 语句中,try 后面的圆括号代表的是 try-with-resources 语法的一部分。这种语法是 Java 7 引入的,相对于传统的 try-catch-finally 语法, 它简化了资源管理,尤其是那些需要显式关闭的资源(例如文件流、数据库连接等)。圆括号内的内容是资源声明,用于定义需要自动关闭的对象。
圆括号内的内容在 try 块执行结束后会自动调用其 close 方法,例如 BufferedReader 、FileReader, 无需手动在 finally 中关闭资源。这种机制确保了资源的正确释放,避免了资源泄漏。
try (FileOutputStream fileOutputStream = new FileOutputStream(new File(filePath));
FileInputStream fileInputStream = new FileInputStream(new File(filePath))) {
// ...
}
// ...
Java 9 之后,再次优化了 try-with-resources 语法。
// Java9可以这样写
FileOutputStream fileOutputStream = new FileOutputStream(new File(filePath));
FileInputStream fileInputStream = new FileInputStream(new File(filePath));
try (fileOutputStream;fileInputStream) {
// ...
}
3. MySQL除了主键之外还能增加唯一性约束吗?
这题我其实一开始答对了,但是没底气,面试官一反问就回答说不敢确定了。
答:
是的,在 MySQL 中,除了主键(PRIMARY KEY)之外,还可以增加唯一性约束(UNIQUE CONSTRAINT),以确保某个列或一组列的值在表中是唯一的。它和外键约束一样,同属于MySQL约束(CONSTRAINT)的一种。MySQL 允许一个表拥有多个 UNIQUE 约束,这与 PRIMARY KEY 的限制不同(一个表只能有一个主键)。
// 创建表时添加唯一性约束
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY, -- 主键
email VARCHAR(100) UNIQUE, -- 单列上的唯一性约束
username VARCHAR(50),
CONSTRAINT unique_name UNIQUE (username) -- 命名约束
);
// 修改添加唯一性约束
ALTER TABLE users
ADD UNIQUE (email); -- 添加单列唯一性约束
ALTER TABLE users
ADD CONSTRAINT unique_name UNIQUE (username); -- 添加命名约束
// 多列组合成唯一性约束
CREATE TABLE orders (
order_id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT,
product_id INT,
UNIQUE (user_id, product_id) -- 确保用户和产品的组合唯一
);
关注一下,持续更新哦~
4510

被折叠的 条评论
为什么被折叠?



