赞
踩
3.ArrayMap
提供了数组收缩的功能,在clear
或remove
后,会重新收缩数组,是否空间
ArrayMap
采用二分法查找;21.HashMap和HashTable的区别
=======================
HashMap
不是线程安全的,效率高一点、方法不是Synchronize
的要提供外同步,有containsvalue
和containsKey
方法。
hashtable
是线程安全,不允许有null
的键和值,效率稍低,方法是是Synchronize
的。有contains
方法方法。Hashtable
继承于Dictionary
类
22.HashMap与HashSet的区别
=====================
hashMap:
HashMap
实现了Map
接口,HashMap
储存键值对,使用put()
方法将元素放入map
中,HashMap
中使用键对象来计算hashcode
值,HashMap
比较快,因为是使用唯一的键来获取对象。
HashSet
实现了Set
接口,HashSet
仅仅存储对象,使用add()
方法将元素放入set
中,HashSet
使用成员对象来计算hashcode
值,对于两个对象来说hashcode
可能相同,所以equals()
方法用来判断对象的相等性,如果两个对象不同的话,那么返回false
。HashSet
较HashMap
来说比较慢。
23.HashSet与HashMap怎么判断集合元素重复?
=============================
HashSet
不能添加重复的元素,当调用add(Object)
方法时候,
首先会调用Object
的hashCode
方法判hashCode
是否已经存在,如不存在则直接插入元素;如果已存在则调用Object
对象的equals
方法判断是否返回true
,如果为true
则说明元素已经存在,如为false
则插入元素。
24.ArrayList和LinkedList的区别,以及应用场景
=================================
ArrayList
是基于数组实现的,ArrayList
线程不安全。
LinkedList
是基于双链表实现的:
使用场景:
如果应用程序对各个索引位置的元素进行大量的存取或删除操作,ArrayList
对象要远优于LinkedList
对象;
如果应用程序主要是对列表进行循环,并且循环时候进行插入或者删除操作,LinkedList
对象要远优于ArrayList
对象;
25.数组和链表的区别
===========
数组:
是将元素在内存中连续存储的;它的优点:因为数据是连续存储的,内存地址连续,所以在查找数据的时候效率比较高;它的缺点:在存储之前,我们需要申请一块连续的内存空间,并且在编译的时候就必须确定好它的空间的大小。在运行的时候空间的大小是无法随着你的需要进行增加和减少而改变的,当数据两比较大的时候,有可能会出现越界的情况,数据比较小的时候,又有可能会浪费掉内存空间。在改变数据个数时,增加、插入、删除数据效率比较低。
链表:
是动态申请内存空间,不需要像数组需要提前申请好内存的大小,链表只需在用的时候申请就可以,根据需要来动态申请或者删除内存空间,对于数据增加和删除以及插入比数组灵活。还有就是链表中数据在内存中可以在任意的位置,通过应用来关联数据(就是通过存在元素的指针来联系)
26.开启线程的三种方式?
=============
Java有三种创建线程的方式,分别是
继承Thread类
、实现Runable接口
和使用线程池
。
27.线程和进程的区别?
============
线程是进程的子集,一个进程可以有很多线程,每条线程并行执行不同的任务。不同的进程使用不同的内存空间,而所有的线程共享一片相同的内存空间。别把它和栈内存搞混,每个线程都拥有单独的栈内存用来存储本地数据。
28.run()和start()方法区别
====================
这个问题经常被问到,但还是能从此区分出面试者对Java
线程模型的理解程度。start()
方法被用来启动新创建的线程,而且start()
内部调用了run()
方法,这和直接调用run()
方法的效果不一样。当你调用run()
方法的时候,只会是在原来的线程中调用,没有新的线程启动,start()
方法才会启动新线程。
30.如何控制某个方法允许并发访问线程的个数?
=======================
semaphore.acquire()
请求一个信号量,这时候的信号量个数-1
(一旦没有可使用的信号量,也即信号量个数变为负数时,再次请求的时候就会阻塞,直到其他线程释放了信号量)
semaphore.release()
释放一个信号量,此时信号量个数+1
31.在Java中wait和seelp方法的不同;
=========================
Java
程序中wait
和sleep
都会造成某种形式的暂停,它们可以满足不同的需要。wait()
方法用于线程间通信,如果等待条件为真且其它线程被唤醒时它会释放锁,而sleep()
方法仅仅释放CPU
资源或者让当前线程停止执行一段时间,但不会释放锁。
32.谈谈wait/notify关键字的理解
======================
等待对象的同步锁,需要获得该对象的同步锁才可以调用这个方法,否则编译可以通过,但运行时会收到一个异常:IllegalMonitorStateException。
调用任意对象的 wait()
方法导致该线程阻塞,该线程不可继续执行,并且该对象上的锁被释放。
唤醒在等待该对象同步锁的线程(只唤醒一个,如果有多个在等待),注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。
调用任意对象的notify()
方法则导致因调用该对象的wait()
方法而阻塞的线程中随机选择的一个解除阻塞(但要等到获得锁后才真正可执行)。
33.什么导致线程阻塞?线程如何关闭?
===================
阻塞式方法是指程序会一直等待该方法完成期间不做其他事情,ServerSocket
的accept()
方法就是一直等待客户端连接。这里的阻塞是指调用结果返回之前,当前线程会被挂起,直到得到结果之后才会返回。此外,还有异步和非阻塞式方法在任务完成前就返回。
一种是调用它里面的stop()
方法
另一种就是你自己设置一个停止线程的标记 (推荐这种)
34.如何保证线程安全?
============
1.synchronized;
2.Object方法中的wait,notify;
3.ThreadLocal机制 来实现的。
35.如何实现线程同步?
============
synchronized
关键字修改的方法。
synchronized
关键字修饰的语句块
使用特殊域变量(volatile)
实现线程同步
36.线程间操作List
============
List list = Collections.synchronizedList(new ArrayList());
37.谈谈对Synchronized关键字,类锁,方法锁,重入锁的理解
===================================
java
的对象锁和类锁:
java
的对象锁和类锁在锁的概念上基本上和内置锁是一致的,但是,两个锁实际是有很大的区别的,对象锁是用于对象实例方法,或者一个对象实例上的,类锁是用于类的静态方法或者一个类的class
对象上的。我们知道,类的对象实例可以有很多个,但是每个类只有一个class
对象,所以不同对象实例的对象锁是互不干扰的,但是每个类只有一个类锁。但是有一点必须注意的是,其实类锁只是一个概念上的东西,并不是真实存在的,它只是用来帮助我们理解锁定实例方法和静态方法的区别的
38.synchronized 和volatile 关键字的区别
================================
1.volatile
本质是在告诉jvm
当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取;synchronized
则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住。
volatile
仅能使用在变量级别;synchronized
则可以使用在变量、方法、和类级别的
volatile
仅能实现变量的修改可见性,不能保证原子性;而synchronized
则可以保证变量的修改可见性和原子性
4.volatile
不会造成线程的阻塞;synchronized
可能会造成线程的阻塞。
5.volatile
标记的变量不会被编译器优化;synchronized
标记的变量可以被编译器优化
39.ReentrantLock 、synchronized和volatile比较
=========================================
Java
在过去很长一段时间只能通过synchronized
关键字来实现互斥,它有一些缺点。比如你不能扩展锁之外的方法或者块边界,尝试获取锁时不能中途取消等。Java 5
通过Lock
接口提供了更复杂的控制来解决这些问题。 ReentrantLock
类实现了 Lock
,它拥有与synchronized
相同的并发性和内存语义且它还具有可扩展性。
40.死锁的四个必要条件?
=============
死锁产生的原因
系统资源的竞争导致系统资源不足,以及资源分配不当,导致死锁。
互斥条件:
一个资源每次只能被一个进程使用,即在一段时间内某 资源仅为一个进程所占有。此时若有其他进程请求该资源,则请求进程只能等待。
请求与保持条件:
进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源 已被其他进程占有,此时请求进程被阻塞,但对自己已获得的资源保持不放。
不可剥夺条件:
进程所获得的资源在未使用完毕之前,不能被其他进程强行夺走,即只能 由获得该资源的进程自己来释放(只能是主动释放)。
循环等待条件:
若干进程间形成首尾相接循环等待资源的关系
这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。
死锁的避免与预防
死锁避免的基本思想:
系统对进程发出每一个系统能够满足的资源申请进行动态检查,并根据检查结果决定是否分配资源,如果分配后系统可能发生死锁,则不予分配,否则予以分配。这是一种保证系统不进入死锁状态的动态策略。
理解了死锁的原因,尤其是产生死锁的四个必要条件,就可以最大可能地避免、预防和解除死锁。所以,在系统设计、进程调度等方面注意如何让这四个必要条件不成立,如何确定资源的合理分配算法,避免进程永久占据系统资源。此外,也要防止进程在处于等待状态的情况下占用资源。因此,对资源的分配要给予合理的规划。
死锁预防是设法至少破坏产生死锁的四个必要条件之一,严格的防止死锁的出现,而死锁避免则不那么严格的限制产生死锁的必要条件的存在,因为即使死锁的必要条件存在,也不一定发生死锁。死锁避免是在系统运行过程中注意避免死锁的最终发生。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
其实Android开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。
上面分享的腾讯、头条、阿里、美团、字节跳动等公司2019-2021年的高频面试题,博主还把这些技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,上面只是以图片的形式给大家展示一部分。
【Android思维脑图(技能树)】
知识不体系?这里还有整理出来的Android进阶学习的思维脑图,给大家参考一个方向。
【Android高级架构视频学习资源】
一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!
AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算
视频学习资源】**
一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!
AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。