2020上半年百度Android岗(初级到高级)面试真题全收录+解析,备战金九银十!(上篇)
版权声明:本文为博主原创文章,首发简书。未经博主允许不得转载。
https://www.jianshu.com/u/3348b92f77a4
前言
今天给大家带来的是百度2020上半年网友分享以及我个人收录的面试真题大全。并且花了大量时间为大家寻找到了最佳的答案解析。希望可以收到帮助到大家。喜欢的朋友可以点个赞支持一下,谢谢。
Java相关
1、HashMap 有用过吗?您能给我说说他的主要用途吗?
有用过,我在平常工作中经常会用到HashMap 这种数据结构,HashMap 是基于Map 接口实现的一种键-值对<key,value>的存储结构,允许null 值,同时非有序,非同步(即线程不安全)。HashMap 的底层实现是数组+ 链表+ 红黑树(JDK1.8 增加了红黑树部分)。它存储和查找数据时,是根据键key 的hashCode的值计算出具体的存储位置。HashMap 最多只允许一条记录的键key 为null,HashMap 增删改查等常规操作都有不错的执行效率,是ArrayList 和LinkedList等数据结构的一种折中实现。
2、说一说自己对于synchronized 关键字的了解
synchronized 关键字解决的是多个线程之间访问资源的同步性,synchronized关键字可以保证被它修饰的方法或者代码块在任意时刻只能有一个线程执行。另外,在Java 早期版本中,synchronized 属于重量级锁,效率低下,因为监视器锁(monitor)是依赖于底层的操作系统的Mutex Lock 来实现的,Java 的线程是映射到操作系统的原生线程之上的。如果要挂起或者唤醒一个线程,都需要操作系统帮忙完成,而操作系统实现线程之间的切换时需要从用户态转换到内核态,这个状态之间的转换需要相对比较长的时间,时间成本相对较高,这也是为什么早期的synchronized 效率低的原因。庆幸的是在Java 6 之后Java 官方对从JVM 层面对synchronized 较大优化,所以现在的synchronized 锁效率也优化得很不错了。JDK1.6 对锁的实现引入了大量的优化,如自旋锁、适应性自旋锁、锁消除、锁粗化、偏向锁、轻量级锁等技术来减少锁操作的开销。
3、synchronized 和volatile 、ReentrantLock 、CAS 的区别。
这个问题被问频率不在HashMap 之下,因为并发编程,真的很重要。能问到这几个点的方式真的是太多了,我们能发挥的空间也同样很大。CAS 的ABA 问题?上面几个东西的特性?使用场景?大概我不用再例举了吧?对了,我多次被问到的一个问题是:synchronized 修饰实例方法和修饰静态方法有啥不一样。
4、String、StringBuffer、StringBuilder 区别
都是字符串类,String 类中使用字符数组保存字符串,因有final 修饰符,String 对象是不可变的,每次对String 操作都会生成新的String 对象,这样效率低,且浪费内存空间。但线程安全。StringBuilder 和StringBuffer 也是使用字符数组保存字符,但这两种对象都是可变的,即对字符串进行append 操作,不会产生新的对象。它们的区别是:StringBuffer 对方法加了同步锁,是线程安全的,StringBuilder 非线程安全。
5、进程和线程的区别
进程:具有一定独立功能的程序,是系统进行资源分配和调度运行的基本单位。
线程:进程的一个实体,是CPU 调度的苯单位,也是进程中执行运算的最小单位,即执行处理机调度的基本单位,如果把进程理解为逻辑上操作系统所完成的任务,线程则表示完成该任务的许多可能的子任务之一。
关系:一个进程可有多个线程,至少一个;一个线程只能属于一个进程。同一进程的所有线
程共享该进程的所有资源。不同进程的线程间要利用消息通信方式实现同步。
区别:进程有独立的地址空间,而多个线程共享内存;进程具有一个独立功能的程序,线程不能
独立运行,必须依存于应用程序中;
6、序列化Serializable 和Parcelable 的区别
序列化:将一个对象转换成可存储或可传输的状态,序列化后的对象可以在网络上传输,也
可以存储到本地,或实现跨进程传输;
Serializable:表示将一个对象转换成可存储或可传输的状态。
Parcelable:与Serializable 实现的效果相同,也是将一个对象转换成可传输的状态,但它的实现原理是将一个完整的对象进行分解,分解后的每一部分都是Intent 所支持的数据类型,这样实现传递对象的功能。
区别:Serializable 在序列化时会产生大量临时变量,引起频繁GC。Serializable 本质上使用了反射,序列化过程慢。Parcelable 不能将数据存储在磁盘上,在外界变化时,它不能很好的保证数据的持续性。
7、静态代理和动态代理的区别,什么场景使用?
代理是一种常用的设计模式,目的是:为其他对象提供一个代理以控制对某个对象的访问,将两个类的关系解耦。代理类和委托类都要实现相同的接口,因为代理真正调用的是委托类的方法。
区别:
1)静态代理:由程序员创建或是由特定工具生成,在代码编译时就确定了被代理的类是哪一个是静态代理。静态代理通常只代理一个类;
2)动态代理:在代码运行期间,运用反射机制动态创建生成。动态代理代理的是一个接口下的多个实现类;
实现步骤:a.实现InvocationHandler 接口创建自己的调用处理器;b.给Proxy 类提供ClassLoader 和代理接口类型数组创建动态代理类;c.利用反射机制得到动态代理类的构造函数;d.利用动态代理类的构造函数创建动态代理类对象;
使用场景:Retrofit 中直接调用接口的方法;Spring 的AOP 机制
8、说说你对Java 反射的理解
在运行状态中,对任意一个类,都能知道这个类的所有属性和方法,对任意一个对象,都能调用它的任意一个方法和属性。这种能动态获取信息及动态调用对象方法的功能称为java语言的反射机制。
反射的作用:开发过程中,经常会遇到某个类的某个成员变量、方法或属性是私有的,或只对系统应用开放,这里就可以利用java 的反射机制通过反射来获取所需的私有成员或是方法。
9、说一下泛型原理
泛型就是将类型变成参数传入,使得可以使用的类型多样化,从而实现解耦。Java 泛型是在Java1.5 以后出现的,为保持对以前版本的兼容,使用了擦除的方法实现泛型。擦除是指在一定程度无视类型参数T,直接从T 所在的类开始向上T 的父类去擦除,如调用泛型方法,传入类型参数T 进入方法内部,若没在声明时做类似public T methodName(T extends Fathert){},Java 就进行了向上类型的擦除,直接把参数t 当做Object 类来处理,而不是传进去的T。即在有泛型的任何类和方法内部,它都无法知道自己的泛型参数,擦除和转型都是在边界上发生,即传进去的参在进入类或方法时被擦除掉,但传出来的时候又被转成了我们设置的T。在泛型类或方法内,任何涉及到具体类型(即擦除后的类型的子类)操作都不能进行,如new T(),或者T.play()(play 为某子类的方法而不是擦除后的类的方法)
10、哪些情况下的对象会被垃圾回收机制处理掉?
利用可达性分析算法,虚拟机会将一些对象定义为GC Roots,从GC Roots 出发沿着引用链
向下寻找,如果某个对象不能通过GC Roots 寻找到,虚拟机就认为该对象可以被回收掉。
11、谈谈你对解析与分派的认识。
解析指方法在运行前,即编译期间就可知的,有一个确定的版本,运行期间也不会改变。解析是静态的,在类加载的解析阶段就可将符号引用转变成直接引用。
分派可分为静态分派和动态分派,重载属于静态分派,覆盖属于动态分派。静态分派是指在重载时通过参数的静态类型而非实际类型作为判断依据,在编译阶段,编译器可根据参数的
静态类型决定使用哪一个重载版本。动态分派则需要根据实际类型来调用相应的方法。
12、线程中sleep 和wait 的区别
(1)这两个方法来自不同的类,sleep 是来自Thread,wait 是来自Object;
(2)sleep 方法没有释放锁,而wait 方法释放了锁。
(3)wait,notify,notifyAll 只能在同步控制方法或者同步控制块里面使用,而sleep 可以在任何地
方使用。
13、Thread 中的start()和run()方法有什么区别
start()方法是用来启动新创建的线程,而start()内部调用了run()方法,这和直接调用run()方法是不一样的,如果直接调用run()方法,则和普通的方法没有什么区别。
14、Jvm 内存区域是如何划分的?
程序计数器:当前线程的字节码执行位置的指示器,线程私有。
Java 虚拟机栈:描述的Java 方法执行的内存模型,每个方法在执行的同时会创建一个栈帧,存储着局部变量、操作数栈、动态链接和方法出口等,线程私有。
本地方法栈:本地方法执行的内存模型,线程私有。
Java 堆:所有对象实例分配的区域。
方法区:所有已经被虚拟机加载的类的信息、常量、静态变量和即时编辑器编译后的代码数据。
15、GC 的常用算法?
- 标记- 清除:首先标记出需要回收的对象,标记完成后统一回收所有被标记的对象。容易产生碎片空间。
- 复制算法:它将可用的内存分为两块,每次只用其中的一块,当需要内存回收的时候,将存活的对象复制到另一块内存,然后将当前已经使用的内存一次性回收掉。需要浪费一半的内存。
- 标记- 整理:让存活的对象向一端移动,之后清除边界外的内存。
- 分代搜集:根据对象存活的周期,Java 堆会被分为新生代和老年代,根据不同年代的特性,选择合适的GC 收集算法。
16、说一下四种引用以及他们的区别?
- 强引用:强引用还在,垃圾搜集器就不会回收被引用的对象。
- 软引用:对于软引用关联的对象,在系统发生内存溢出异常之前,将会把这些对象列进回收范围进行第二次回收,如果这次回收还没有足够的内存,才会抛出内存溢出异常。
- 弱引用:被若引用关联的对象只能存活到下一次GC 之前。
- 虚引用:为对象设置虚引用的目的仅仅是为了GC 之前收到一个系统通知。
17、类加载的过程?
类加载的过程可以分为:
- 加载:将类的全限定名转化为二进制流,再将二进制流转化为方法区中的类型信息,从而生成一个Class 对象。
- 验证:对类的验证,包括格式、字节码、属性等。
- 准备:为类变量分配内存并设置初始值。
- 解析:将常量池的符号引用转化为直接引用。
- 初始化:执行类中定义的Java 程序代码,包括类变量的赋值动作和构造函数的赋值。
- 使用
- 卸载
只有加载、验证、准备、初始化和卸载的这个五个阶段的顺序是确定的。
计算机网络相关
1、HTTP 是哪一层的协议,常见的HTTP 状态码有哪些,分别代表什么意思?
HTTP 协议是应用层的协议。
常见的HTTP 状态码有:
2、HTTP 1.1 和HTTP 2 有什么区别?
HTTP 2.0 基于HTTP 1.1,与HTTP 2.0 增加了:
1.二进制格式:HTTP 1.1 使用纯文本进行通信,HTTP 2.0 使用二进制进行传输。
2.Head 压缩:对已经发送的Header 使用键值建立索引表,相同的Header 使用索引表示。
3.服务器推送:服务器可以进行主动推送
4.多路复用:一个TCP 连接可以划分成多个流,每个流都会分配Id,客户端可以借助流和服务端建立全双工进行通信,并且流具有优先级。
3、HTTP 和HTTPS 有什么区别?
简单来说,HTTP 和HTTPS 的关系是这样的:HTTPS = HTTP + SSL/TLS
区别如下:
HTTP 作用于应用层,使用80 端口,起始地址是http://,明文传输,消息容易被拦截,串改。
HTTPS 作用域传输层,使用443 端口,起始地址是https://,需要下载CA 证书,传输的过程需要加密,安全性高。
4、为什么连接的时候是三次握手,关闭的时候却是四次挥手?
为当Server 端收到Client 端的SYN 连接请求报文后,可以直接发送SYN+ACK报文,其中ACK 报文是用来应答的,SYN 报文是用来同步的。但是关闭连接时,当Server 端收到FIN 报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK 报文,告诉Client 端,"你发的FIN 报文我收到了"。只有等到我Server 端所有的报文都发送完了,我才能发送FIN 报文,因此不能一起发送。故需要四步挥手。
5、OKHttp的特点和缺点
特点:
1.相较于Volley,它的最大并发量为64
2.使用连接池技术,支持5 个并发的socket 连接默认keepAlive 时间为5 分钟,解决TCP 握手和挥手的效率问题,减少握手次数
3.支持Gzip 压缩,且操作对用户透明,可以通过header 设置,在发起请求的时候自动加入headerAccept-Encoding: gzip,而我们的服务器返回的时候header中有Content-Encoding: gzip
4.利用响应缓存来避免重复的网络请求
5.很方便的添加拦截器,通常情况下,拦截器用来添加,移除,转换请求和响应的头部信息,比如添加公参等
6.请求失败,自动重连,发生异常时重连,看源码调用recover 方法重连了一次
7.支持SPDY 协议(SPDY 是Google 开发的基于TCP 的应用层协议,用以最小化网络延迟,提升网络速度,优化用户的网络使用体验。SPDY 并不是一种用于替代HTTP 的协议,而是对HTTP 协议的增强。新协议的功能包括数据流的多路复用、请求优先级以及HTTP 报头压缩。谷歌表示,引入SPDY 协议后,在实验室测试中页面加载速度比原先快64%)
8.使用Okio 来简化数据的访问与存储,提高性能
缺点:
1.消息回来需要切到主线程,主线程要自己去写。
2.调用比较复杂,需要自己进行封装。
3.缓存失效:网络请求时一般都会获取手机的一些硬件或网络信息,比如使用的网络环境。同时为了信息传输的安全性,可能还会对请求进行加密。在这些情况下OkHttp 的缓存系统就会失效了,导致用户在无网络情况下不能访问缓存。
6、WebSocket 与Socket 的区别
为了解决Web 端即时通讯的需求就出现了WebSocket
WebSocket 与Socket 的区别:
Socket 是传输控制层的接口。用户可以通过Socket 来操作底层TCP/IP 协议族通信。
WebSocket 是一个完整应用层协议。
Socket 更灵活,WebSocket 更易用。
两者都能做即时通讯复制代码
7、请解释安卓为什么要加签名机制?
为什么要签名:
1.发送者的身份认证
2.保证信息传输的完整性
3.防止交易中的抵赖发生
给apk 签名可以带来以下好处
1.应用程序升级
2.应用程序模块化
3.代码或者数据共享
签名的说明
1.所有的应用程序都必须有数字证书
2.Android 程序包使用的数字证书可以是自签名的
3.使用一个合适的私钥生成的数字证书来给程序签名
4.数字证书都是有有效期的
8、TCP 和UDP 有什么区别?
- TCP:基于字节流、面向连接、可靠、能够进行全双工通信,除此以外,还能进行流量控制和拥塞控制,不过效率略低
- UDP:基于报文、面向无连接、不可靠,但是传输效率高。
9、TCP 为什么是一种可靠的协议?如何做到流量控制和拥塞控制?
- TCP 可靠:是因为可以做到数据包发送的有序、无差错和无重复。
- 流量控制:是通过滑动窗口实现的,因为发送发和接收方消息发送速度和接收速度不一定对等,所以需要一个滑动窗口来平衡处理效率,并且保证没有差错和有序的接收数据包。
- 拥塞控制:慢开始和拥塞避免、快重传和快恢复算法。这写算法主要是为了适应网
络中的带宽而作出的调整。
10、如何验证证书的合法性?
证书的安全性
证书存在的目的就是避免中间人攻击,避免发生经典的传令兵问题
由CA 组织认可的根证书Root 签发的
DV Digital Verification、OV Organization Verification、EV Extended Verification
证书是需要预装的,特别是根证书。
证书的校验
- 证书是否为值得信任的有效证书。是否为信任根(浏览器内置有信任的根证书)或信任根的二级证书机构颁发的。是否为信任根(浏览器内置有信任的根证书)或信任根的二级证书机构颁发的。
- 对方是否持有证书对应的私钥。验证方式有两种:
o 对方签名,浏览器用证书对签名进行验证。
o 使用证书作为信封,判断对方是否能够解开。
检查流程:
1.客户端发送信息,带上支持的SSL 或者TLS 版本(不同浏览器支持程* * 度不同)。
2.服务器返回确认使用的加密通信协议版本以及加密随机数和CA 证书。
3.浏览器验证证书(存在双向验证和单项验证) -> OCSP 或者CRL * 结合自带truststore。
4.检查CA 证书的根证书颁发机构是否受浏览器信任。
5.检查CA 证书中的证书吊销列表,检查证书是否被吊销。
6.检查CA 证书是否在有效期内。
7.检查部署CA 证书的网站域名与证书颁发的域名是否一致。
8.浏览器核对该网站是否存在于欺诈网站数据库中。
草草收尾
写着写着发现篇幅太长,写不下了,所以放到下一篇讲了,喜欢的小伙伴可以点个收藏关注,插个眼,下集在我的主页,马上更新~
BATJ大厂面试真题收录大全PDF电子书已上传在GitHub:【BATJ面试大全】需要的小伙伴自取就好了。别忘了给文章点个赞~