面试时间过去了都快一个月了,一直都忘记整理,今天整理出来。
两个月没面试过了,突然接到这么面试通知,准备不够充分,再加上平时学得很宽泛,一点也不深入,问得稍微深入一点就不懂了。最重要的是,回答之前,要好好理清思路,不要想到什么就答什么,这样会让面试官听起来很混乱,也容易让人感觉是是而非。这次面试我就感觉我的回答是是而非,非常混乱。面了差不多二十分钟,面完以后就感觉基本上凉凉了,回答的时候也没有好好组织语言,答得有些是是而非,估计是有些着急了,还有些问题没有答上,比如线程池相关的,主要是我用的不多,学的时候也就看了一遍例子就完事了。问对象去重的本质,我也没get到面试官是在问啥,我还在那里一口一个重写toString方法(重写equals方法)。不过面试官很nice,面我这种菜鸟能从头听到尾也着实委屈他了。
意思到自己的不足,那就要加油呀!
我将面试中的一些问题总结如下,可能与实际问题会有些出入。
问题1:对比Java8和Java11
问题2:用Lambda实现对象的去重,去重的本质
比如有一个Person类,里面有age和name属性。首先需要重写equals
方法和hashCode
方法。
package lambda;
import java.util.Objects;
/**
* @author simon
*/
public class Person {
private int age;
public String name;
public Person() {
}
public String getName() {
return name;
}
public Person(int age, String name) {
this.age = age;
this.name = name;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Person person = (Person) o;
return age == person.age &&
Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(age, name);
}
@Override
public String toString() {
return "Person{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}
先不考虑使用Lambda来进行去重
方法一:使用Set去重
HashSet中的元素是无序的,TreeSet中的元素是有序的。
使用HashSet
public static void main(String[] args) {
Person person1 = new Person(22, "ZhangSan");
Person person2 = new Person(22, "ZhangSan");
Person person3 = new Person(23, "LiSi");
Person person4 = new Person(24, "WangWu");
Person person5 = new Person(24, "WangWu");
Set<Person> set = new HashSet<>();
List<Person> personList = Arrays.asList(person1, person2, person3, person4, person5);
set.addAll(personList);
set.forEach(person -> System.out.println(person.toString()));
}
可以发现输出的确不包含重复的元素了。
使用TreeSet
需要重写Compartor
的Compare
方法。
public static void main(String[] args) {
Person person1 = new Person(22, "ZhangSan");
Person person2 = new Person(22, "ZhangSan");
Person person3 = new Person(23, "LiSi");
Person person4 = new Person(24, "WangWu");
Person person5 = new Person(24, "WangWu");
Person person6 = new Person(25, "WangLiu");
List<Person> personList = Arrays.asList(person1, person2, person3, person4, person5, person6);
Set<Person> set = new TreeSet<>((o1, o2) -> {
if (o1.equals(o2)) {
//return 0表示o1==o2
return 0;
} else if (o1.getName().charAt(0) >= o2.getName().charAt(0)) {
//return 1表示o1>o2
return 1;
} else {
//return -1表示o1<o2
return -1;
}
});
set.addAll(personList);
set.forEach(person -> System.out.println(person.toString()));
}
输出结果:按照name的首字母进行排序。如果首字母相同,后加入的默认大于先加入的。排序的时候,小的放在前面,大的放在后面。
方法二:使用排序然后进行去重
public static void main(String[] args) {
Person person1 = new Person(22, "ZhangSan");
Person person2 = new Person(22, "ZhangSan");
Person person3 = new Person(23, "LiSi");
Person person4 = new Person(24, "WangWu");
Person person5 = new Person(24, "WangWu");
Person person6 = new Person(25, "WangLiu");
List<Person> personList = Arrays.asList(person1, person2, person3, person4, person5, person6);
Object[] objects = personList.toArray();
Person[] persons = new Person[objects.length];
for (int i = 0; i < objects.length; ++i) {
persons[i] = (Person) objects[i];
}
Arrays.sort(persons, ((o1, o2) -> {
if (o1.equals(o2)) {
return 0;
} else if (o1.getName().charAt(0) >= o2.getName().charAt(0)) {
return 1;
} else {
return -1;
}
}));
System.out.println("------------去重前------------");
for (Person person : persons) {
System.out.println(person.toString());
}
List<Person> uniquePerson = new ArrayList<>();
for (int j = 0; j < persons.length; ++j) {
if (j < persons.length - 1 && persons[j].equals(persons[j + 1])) {
continue;
} else {
uniquePerson.add(persons[j]);
}
}
System.out.println("------------去重后------------");
uniquePerson.forEach(person -> System.out.println(person.toString()));
}
输出:
使用Lamda来去重
写法一
public static void main(String[] args) {
Person person1 = new Person(22, "ZhangSan");
Person person2 = new Person(22, "ZhangSan");
Person person3 = new Person(23, "LiSi");
Person person4 = new Person(24, "WangWu");
Person person5 = new Person(24, "WangWu");
Person person6 = new Person(25, "WangLiu");
List<Person> personList = Arrays.asList(person1, person2, person3, person4, person5, person6);
Set<Person> set = new HashSet<>();//使用set来临时存放不重复的元素
//使用stream方法将元素一个一个地发布
List<Person> uniquePerson = personList.stream().filter(person -> {
if (!set.contains(person)) {
set.add(person);
return true;
} else {
return false;
}
}).collect(Collectors.toList());
uniquePerson.forEach(System.out::println);
}
写法二
public static void main(String[] args) {
Person person1 = new Person(22, "ZhangSan");
Person person2 = new Person(22, "ZhangSan");
Person person3 = new Person(23, "LiSi");
Person person4 = new Person(24, "WangWu");
Person person5 = new Person(24, "WangWu");
Person person6 = new Person(25, "WangLiu");
List<Person> personList = Arrays.asList(person1, person2, person3, person4, person5, person6);
List<Person> uniquePerson = personList.stream().collect(
Collectors.collectingAndThen(
Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Person::getName))), ArrayList::new)
);
uniquePerson.forEach(System.out::println);
}
输出:
问题3:说一下线程池
参考我的这一篇文章:
Java中线程池的创建和使用。ThreadPoolExecutor和Executors
问题4:为什么要有Spring Boot
当初Spring就是为了干掉EJB的复杂而诞生的,但是Spring发展到今天,它也俨然成了一个庞然大物。Spring Framwork的模块大大小小就有几十个,使得开发人员的上手变得非常困难。
而Spring Boot就是为了简化Spring的开发而诞生的,让开发变得更加简单,让配置变得更加简单,让运行也变得更加简单。
Spring Boot就像是一个脚手架,能为我们提供了基础的配置。比如我们要开发一个简单的web应用,只需要引入一个web的starter的依赖即可,也不需要再做额外的配置。
问题5:如何自定义Spring Boot Starter
参考一下我的这篇文章:
Spring Boot两大核心原理:自动配置以及Starter,详细讲述starter并实践自定义一个spring boot starter