面试总结

2021-06-28  本文已影响0人  书虫大王X
1、数组和链表的区别和联系,他们是线程安全的吗
2、怎么保证线程安全:

线程安全的本质:当多个线程访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果,那这个对象就是线程安全的。

image.png
3、synchronize的作用和应用场景:
4、解释一下死锁:
5、线程状态的切换:

等待阻塞:运行状态中的线程执行 wait() 方法,使线程进入到等待阻塞状态。
同步阻塞:线程在获取 synchronized同步锁失败(因为同步锁被其他线程占用)。
其他阻塞:通过调用线程的 sleep() 或 join() 发出了 I/O请求时,线程就会进入到阻塞状态。当sleep() 状态超时,join() 等待线程终止或超时,或者 I/O 处理完毕,线程重新转入就绪状态。

6、hashmap介绍一下,hashmap在多线程中如果要保证它的线程安全该怎么做,它对应的安全的数据结构是什么:

1、hashMap线程不安全的原因及表现 - 简书 (jianshu.com)
2、第三天:HashMap为什么是线程不安全的 - 知乎 (zhihu.com)

1、个人觉得HashMap在并发时可能出现的问题主要是两方面,首先如果多个线程同时使用put方法添加元素,而且假设正好存在两个put的key发生了碰撞(hash值一样),那么根据HashMap的实现,这两个key会添加到数组的同一个位置,这样最终就会发生其中一个线程的put的数据被覆盖。第二就是如果多个线程同时检测到元素个数超过数组大小*loadFactor,这样就会发生多个线程同时对Node数组进行扩容,都在重新计算元素位置以及复制数据,但是最终只有一个线程扩容后的数组会赋给table,也就是说其他线程的都会丢失,并且各自线程put的数据也丢失。
2、关于HashMap线程不安全这一点,《Java并发编程的艺术》一书中是这样说的:
HashMap在并发执行put操作时会引起死循环,导致CPU利用率接近100%。因为多线程会导致HashMap的Node链表形成环形数据结构,一旦形成环形数据结构,Node的next节点永远不为空,就会在获取Node时产生死循环。

7、ArrayList对应的线程安全的类是什么:

1、多线程操作时,该数据结构容易出现越界现象
2、有些操作不具有原子性,例如:a = b++;
3、容易出现值的覆盖现象

8、介绍一下你对反射的理解,它的应用场景是什么:

1、Java反射就是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;并且能改变它的属性。而这也是Java被视为动态语言的一个关键性质。
2、反射机制允许程序在运行时取得任何一个已知名称的class的内部信息,包括包括其modifiers(修饰符),fields(属性),methods(方法)等,并可于运行时改变fields内容或调用methods。那么我们便可以更灵活的编写代码,代码可以在运行时装配,无需在组件之间进行源代码链接,降低代码的耦合度;还有动态代理的实现等等;但是需要注意的是反射使用不当会造成很高的资源消耗!

1、在运行时判定任意一个对象所属的类
2、在运行时构造任意一个类的对象;
3、在运行时判定任意一个类所具有的成员变量和方法;
4、在运行时调用任意一个对象的方法;
5、生成动态代理;

//第一种方式 通过对象getClass方法
Person person = new Person();
Class<?> class1 = person.getClass();
//第二种方式 通过类的class属性
class1 = Person.class;
//第三种方式 通过Class类的静态方法——forName()来实现
try {
class1 = Class.forName("com.whoislcj.reflectdemo.Person");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}

Java学习:反射的应用场景和解析方法 - 简书 (jianshu.com)
Java学习之反射机制及应用场景 - 总李写代码 - 博客园 (cnblogs.com)

9、抽象类和接口的区别是什么?
10、深拷贝和浅拷贝的区别,如果要深拷贝,该怎么做:

浅拷贝并不复制数据,只复制指向数据的指针,因此是多个指针指向同一份数据。 深拷贝会复制原始数据,每个指针指向一份独立的数据,例:
struct Test{
char ptr;
};
void shallow_copy(Test &src, Test &dest){
dest.ptr = src.ptr;
}
void deep_copy(Test &src, Test &dest){
dest.ptr = (char
)malloc(strlen(src.ptr) + 1);
memcpy(dest.ptr, src.ptr);
}

11、什么是序列化

12、java的IO的操作,字节和字符的却别,在项目中怎么操作一个文件
13、java中创建线程的方法
14、在并发情况中,如何控制创建线程的情况
15、线程池比较适合用于什么样的一些任务:

16、线程和进程的关系
17、java的内存模型,java中的内存区域
18、java中的一些类加载机制能不能说一下,类加载的整个过程
19、类加载器(classLoader)
20、jvm的垃圾回收算法
21、Android的内存管理和垃圾回收
22、介绍一下你做过的demo,你负责什么模块,涉及到哪些相关的技术
23、介绍一下activity的生命周期(好好看一下)
24、hander的机制
25、关于自定义view的流程
26、说一下二分查找:

27、快速排序,在大部分数据都是有序的情况下,怎么实现优化
28、介绍一下工厂设计模式,你还了解什么设计模式
29、介绍一下tcp/ip
30、HTTP发起一个请求,一般会经过几个步骤

上一篇下一篇

猜你喜欢

热点阅读