- 4.2 20:12 电话办法,确认时刻;
- 4.3 14:03 开端电话面试 时长32min
1. 概括
1.1.能够先自我介绍一下吗?
- 参阅:依据自己的状况提早准备好即可。
1.2.学了这么多东西,你觉得你学的最好的是哪一块?
- 参阅:这里只能说平时留意自己核心竞争力和技能特征的培养;
- 打个比如:嗯我觉得我在Android这一方面相对比较有把握,然后在***(某个方向)的知识和运用上比较有心得;
1.3.有没有什么实战项目做出来呢?
要点:平时留意多上GitHub、各种网课上或许找导师多扒些项目去做
- 参阅思路:
- 最好提早准备好表述,留意
表达的功率
!当被长辈发问时,简略简明
地把重点说了解!切忌
拖泥带水含糊不清,没有功率地说了一堆话,很扣分
!项目最难的当地
,最有价值的问题
和处理方案
,最好自己总结好, 告知好项目重点之后顺带提出来,否则面试官长辈会问下面1.4.
这个问题。 所以有必要注重答复问题的完整性
和谨慎性
;
1.4. 你觉得在这个项目傍边做起来最难的当地是在哪里?
- 参阅:总结概括好所做项目对应的内容重点,简明阐述; 或可从
所用技能及所触及知识点
、规划思路
、处理办法
等方向概括答复;
1.5 除了做Android的话,对C/C++这一块了解吗?
- 参阅:此问题天然是知道多少答复多少,不过最好是有组织有条理地描述; 这里能够从C++和Java的异同下手答复:
2. 计算机网络(0.4-0.45)
1.Android端跟后台通讯的时分用的是什么协议?
- 参阅:用的是依据“`HttpURLConnection类的HTTP协议
你们对HTTP平常用得了解吗?
2.(接1. )HTTP是哪一层上面在用的呢?
- 参阅:HTTP是运用层上面的协议;
3.(接2.)那它是依据什么协议去完结的?
- 参阅:它是依据TCP衔接的;
4.在项目中,你有或许需求坚持APP跟后台之间的长时刻衔接,那么在实践运用中你是怎样完结坚持长时刻衔接的?便是你的这种app跟后台服务的通讯,是一种 短衔接 还是一种 长衔接 的办法呢?
考点:网络的(短衔接跟)长衔接(即持久衔接)问题
- 参阅(完结长衔接):
在Android中,咱们在进行HTTP恳求的时分, 运用的是Java API的一个叫HTTPURLConnection
的封装类, 首要将一个web UR
L传给一个URL
目标的结构办法,创立出一个URL
实例, 用这个URL实例调用其openConnection()
办法,会回来一个目标, 将其回来的目标转型为HttpURLConnection
目标并交给一个HttpURLConnection实例
, 接着就能够调用HttpURLConnection
实例的一系列set
办法对这个恳求做各种设置, 其间调用办法setRequestProperty("Connection", "Keep-Alive")
即可完结这个恳求的长衔接
的完结; 当然除了以上Android端的配置意外,咱们还需求在服务器
设置好Keep- Alive长衔接办法
, 是否能完结一个完整的Keep- Alive衔接和服务器设置也相关;- HttpURLConnection 的 demo:
URL realUrl = new URL(url); HttpURLConnection conn = (HttpURLConnection) realUrl .openConnection(); // 发送POST恳求有必要设置如下两行 conn.setDoOutput(true); conn.setDoInput(true); // POST办法 conn.setRequestMethod("POST"); // 设置通用的恳求特色 conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("connection", "Keep-Alive"); conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); conn.connect();
- 额定:
- 能够聊一下
什么是长衔接、短衔接
:
- 在HTTP/1.0中默许运用短衔接。 也便是说,客户端和服务器每进行一次HTTP操作,就树立一次衔接,使命完毕就中止衔接。 当客户端浏览器拜访的某个HTML或其他类型的Web页中包括有其他的Web资源(如JavaScript文件、图像文件、CSS文件等),每遇到这样一个Web资源,浏览器就会从头树立一个HTTP会话。
- 而从HTTP/1.1起,默许运用长衔接,用以坚持衔接特性。 运用长衔接的HTTP协议,会在呼应头加入这行代码:
Connection:keep-alive
在运用长衔接的状况下,当一个网页打开完结后,客户端和服务器之间用于传输HTTP数据的TCP衔接不会封闭,客户端再次拜访这个服务器时,会持续运用这一条现已树立的衔接。 Keep-Alive不会永久坚持衔接,它有一个坚持时刻,能够在不同的服务器软件(如Apache)中设定这个时刻。 完结长衔接需求客户端和服务端都支撑长衔接。- HTTP协议的长衔接和短衔接,实质上是TCP协议的长衔接和短衔接。
长衔接,短衔接的适用场景?
长衔接多用于操作频频,点对点的通讯,而且衔接数不能太多状况。 每个TCP衔接都需求三次握手,这需求时刻,假如每个操作都是先衔接,再操作的话那么处理速度会降低许多, 所以每个操作完后都不断开,次处理时直接发送数据包就OK了,不必树立TCP衔接。 例如:数据库的衔接用长衔接, 假如用短衔接频频的通信会形成socket过错,而且频频的socket创立也是对资源的糟蹋。
而像WEB网站的http服务一般都用短链接, 由于长衔接关于服务端来说会耗费必定的资源, 而像WEB网站这么频频的不计其数甚至上亿客户端的衔接用短衔接会更省一些资源, 假如用长衔接,而且一同有不计其数的用户,假如每个用户都占用一个衔接的话,那可想而知吧。 所以并发量大,但每个用户无需频频操作状况下需用短连好。
相关阅览:
- HttpURLConnection运用【!留意其文第127行代码!】
- HTTP长衔接、短衔接终究是什么?(**)
- 长衔接和Keepalive详解
- HttpClient和HttpURLConnection的运用和差异(上)
- HttpClient和HttpURLConnection的运用和差异(下)
5.客户端到服务器拉数据的时分你是用GET还是用POST去取的?
参阅:拉数据的时分是用GET去取的,别的:
GET
和POST
本质上是没有差异的,它们都是TCP
链接,
- GET和POST能做(能做——具有完结的才能)的事情相同相同。 技能上要给GET加上request body,给POST带上url参数,也是行的通的。
- 只不过
HTTP
给TCP链接
披上了GET
和POST
的外衣, 打上了服务类型的标签,大多数的语言结构也对此作了一个约好俗成, 使得不同服务类型的TCP链接恳求在运用时,最好要进行各自不同的代码编写和机制处理, 一同加上浏览器/服务器或多或少地对URL等参数或许的约束, 导致他们在运用进程
中体现出一些不同。- 可是其实像**“POST恳求时数据就要放在BODY中, GET恳求时数据(参数)就要放在URL中而不能放在BODY中”**这样的说法, 仅仅HTML规范对HTTP协议的用法的约好,HTTP并没有做这姿态的要求;
运用进程上的差异
:
- 00 关于服务器(2点):
- GET是从服务器上获取数据, POST是向服务器传送数据;
- 关于GET办法, 服务器端用Request.QueryString获取变量的值, 关于POST办法, 服务器端用Request.Form获取提交的数据。
- 01 关于功率和安全性(3点):POST(传输含义上)安全性较高;GET(传输含义上)安全性非常低,可是履行功率比POST好;
- GET产生一个TCP数据包, 浏览器会把http header和data一并发送出去,服务器呼应200(回来数据); POST产生两个TCP数据包,浏览器先发送header, 服务器呼应100 continue,浏览器再发送data,服务器呼应200 ok(回来数据)。 也便是说, GET一步到位,而POST需求两步,这也是GET比POST更快的一个原因;
- GET会将数据缓存起来, 而POST不会,这是GET比POST更快的又一个原因; 据道友测验, 运用ajax选用GET办法恳求静态数据(比如html页面,图片)的时分, 假如两次传输的数据相同, 第二次以后耗费的时刻将会在10ms以内(chrome测验), 而POST每次耗费的时刻都差不多。 经测验, chrome和firefox下假如检测到get恳求的是静态资源,则会缓存, 假如是数据,则不会缓存,可是IE什么都会缓存起来;
- GET把恳求的数据放在url上,即HTTP协议头上,url参数可见; POST把数据放在HTTP的包体内(requrest body),url参数不行见; 所以原则上POST要比get安全,究竟传输参数时url不行见;
- 02 关于恳求长度约束(1点):
- http协议从未规则GET/POST的恳求长度约束是多少; 可是实践运用上, GET提交的数据的约束,取决于浏览器和web服务器设置的URL恳求长度约束; 各种浏览器和web服务器的设定均不相同, 这依赖于各个浏览器厂家的规则或许能够依据web服务器的处理才能来设定。 IE 约束 2k,Firefox 约束 8k(非常老的版别 256byte), 假如超出了最大长度,大部分的服务器直接截断,也有一些服务器会报414过错。 POST默许没有约束。理论上IIS4中最很多为80KB,IIS5中为100KB。
- 03 其他(2点):
- 从
本质含义
上讲,GET是安全的,POST不安全:
- GET没有更改服务器内容;
- POST对服务器就行写入、掩盖,会更改服务器内容;
- 幂等性(相同的一个操作,它一次或许屡次地操作,对系统资源产生的影响是相同的)
- GET具有幂等性;
- POST不具有; (原因参照对服务器是否有修正)
“用GET替换POST来优化网站功用”是一个坑,慎入;何出此言?
- GET与POST都有自己的语义,不能随便混用。
- 据研讨,在网络环境好的状况下, 发一次包的时刻和发两次包的时刻不同根本能够无视。 而在网络环境差的状况下, 两次包的TCP在验证数据包完整性上,有非常大的优点。
- 并不是一切浏览器都会在POST中发送两次包,Firefox就只发送一次。
相关阅览:
- GET和POST两种根本恳求办法的差异【质量详文】
- http GET 和 POST 恳求的优缺点、差异以及误区【质量详文】
- get和post的差异–面试经常被问到!【质量详文】
- 2019校招Android面试题解1.0(下篇)
- GET和POST有什么差异?【指出HTML约好HTTP】
- 面试中get和post的差异【简略指出运用上差异】
- 浅谈HTTP中get与post的差异
6.在做的进程中有没有遇到过HTTP的过错,比如说HTTP的那些过错码?
参阅答复:状况码由三位数字组成,第一位数字表明呼应的类型,常用的状况码有五大类:
1xx:表明服务器已接纳了客户端恳求,客户端可持续发送恳求
2xx:表明服务器已成功接纳到恳求并进行处理
- 200 OK:表明客户端恳求成功
3xx:表明服务器要求客户端重定向 重定向(Redirect)便是经过各种办法将各种网络恳求从头定个方向转到其它方位(如:网页重定向、域名的重定向、路由挑选的变化也是对数据报文经由途径的一种重定向)
4xx:表明客户端的恳求有不合法内容
- 400 Bad Request:表明客户端恳求有语法过错,不能被服务器所了解
- 401 Unauthonzed:表明恳求未经授权,该状况代码有必要与 WWW-Authenticate 报头域一同运用
- 403 Forbidden:表明服务器收到恳求,可是拒绝供给服务,一般会在呼应正文中给出不供给服务的原因
- 404 Not Found:恳求的资源不存在,例如,输入了过错的URL
- 414 :Request-URI 太长
5xx:表明服务器未能正常处理客户端的恳求而呈现意外过错
500 Internal Server Error:表明服务器产生不行预期的过错,导致无法完结客户端的恳求 503 Service Unavailable:表明服务器当时不能够处理客户端的恳求,在一段时刻之后,服务器或许会恢复正常
相关阅览:
- www.jianshu.com/p/168e52336…
- HTTP恳求过错…解析
3. Java(0.4-0.5)
1.String、StringBuffer、StringBuilder三个的别离?
总述:
- String:不行变字符串;
- StringBuffer:可变字符串、功率低、线程安全;
- StringBuilder:可变字符序列、功率高、线程不安全;
- 履行速度:StringBuilder > StringBuffer > String; (StringBuffer 许多办法能够带有synchronized关键字,在做字符串操作时需求做对应的操作,所以运转功用比StringBuilder略微差些)
- StringBuffer、 StringBuilder的API根本相同:
详析:
String
的值是不行变的, 每次对String的操作都会生成新的String目标, 不只功率低下,而且糟蹋很多优先的内存空间: JVM关于上图是这样处理的, 首要创立一个String目标str,并把“hello”赋值给str, 然后str=str+” world”: 其实JVM又创立了一个新的目标也名为str, 然后再把本来的str的值和“ world”加起来再赋值给新的str, 而本来的str就会被JVM的废物收回机制(GC)给收回掉了, 所以,最开端的str实践上并没有被更改, 也便是前面说的String目标一旦创立之后就不行更改了(String的值是不行变的)。 这样短短的两个字符串,却需求拓荒三次内存空间,不得不说这是对内存空间的极大糟蹋。 所以, Java中对String目标进行的操作, 实践上是一个不断创立新的目标而且将旧的目标收回的一个进程,履行速度很慢。StringBuffer
是可变的、线程安全的字符串操作类, 任何对它指向的字符串的操作都不会产生新的目标。 每个StringBuffer目标都有必定的缓冲区容量, 当字符串巨细没有超越容量时,不会分配新的容量, 当字符串巨细超越容量时,会主动增加容量;StringBuilder
是可变的、线程不安全的字符串操作类, 任何对它指向的字符串的操作都不会产生新的目标。 每个StringBuilder目标都有必定的缓冲区容量, 当字符串巨细没有超越容量时,不会分配新的容量, 当字符串巨细超越容量时,会主动增加容量;适用场景:
- String:适用于操作少数的字符串/数据的状况
- StringBuilder:适用于单线程操作字符串缓冲区下操作很多数据的状况
- StringBuffer:适用于多线程操作字符串缓冲区下操作很多数据的状况
StringBuilder/StringBuffer的缓冲区会不会满?
StringBuilder/StringBuffer的缓冲区的巨细默许初始化为16个字符, 或许能够运用其他重载的结构办法初始化缓冲区的巨细, 缓冲区最大容量的巨细视内存而定,一般都是数以M计,有极限可是一般用不满的;相关阅览:
- String、StringBuffer和StringBuilder这三兄弟别离是做什么的?
- 图析:String,StringBuffer与StringBuilder的差异
- StringBuffer与StringBuilder的差异,及完结原理【提及初始化及扩容机制】
- 获取StringBuffer目标的容量
- Java中的String,StringBuilder,StringBuffer三者的差异
- Java中String、StringBuilder、StringBuffer常用源码剖析及比较(二):StringBuilder、StringBuffer源码剖析
- [源码]String StringBuffer StringBudlider(2)StringBuffer StringBuilder源码剖析
2.有没有用过Java对应的数据结构的类?
参阅:概述许多
调集类的特性
,特别留意底层完结
、内部算法完结
、线程安全
、同类差异
等问题;
ArrayList
类 a. 完结了可变的数组
,答应保存一切元素
,包括null
,并能够依据索引方位对调集进行快速的随机拜访; b. 缺点是向指定的索引方位刺进目标或删去目标的速度较慢。
LinkedList
类 a.选用链表结构
保存目标。 b.优点是便于向调会集刺进和删去目标,需求向调会集刺进、删去目标
时,运用LinkedList类完结的List调集的功率较高: c. 但关于随机拜访调会集的目标
,运用LinkedList类完结List调集的功率较低。
HashSet
类 a. 完结Set接口
,由哈希表(实践上是一个HashMap实例)
支撑。 b. 它不确保Set的迭代次序
,特别是它不确保该次序恒久不变
。 c .此类答应运用null元素
。
TreeSet
类 a. 不只完结了Set接口
,还完结了java.util.SortedSet接口
, b. 因而,TreeSet类完结的Set调集在遍历调集时
依照天然次序递加排序
;*********%%%%%%%%%%***********
c. 也能够依照指定比较器
递加排序; d. 即能够经过比较器对用TreeSet类完结的Set调会集的目标进行排序。
HashMap
类 a .承继于AbstractMap
,完结了Map
、Cloneable
、java.io.Serializable
接口; b. 此完结供给一切可选的映射操作
,并答应运用null值和null键
,但有必要确保键的唯一性
。 c .HashMap经过哈希表
对其内部的映射联系进行快速查找
。 d. 此类不确保
映射的次序,特别是它不确保该次序恒久不变。
TreeMap
类 a. 不只完结了Map接口,还完结了java.util.SortedMap接囗,因而,调会集的映射联系具有必定的次序。 b. 但在增加、删去和定位映射联系
时,TreeMap类比HashMap类功用稍差
。 c. 由于TreeMap类完结的Map调会集的映射联系是依据**键目标
**依照必定的次序排列
的,因而不答应键目标是null
。能够经过HashMap类创立Map调集,当需求次序输出时,再创立一个完结相同映射联系的TreeMap类实例。
HashTable
类 a. 承继于Dictionary
,完结了Map
、Cloneable
、java.io.Serializable
接口。 b.Hashtable 的函数都是同步
的,这意味着它是线程安全
的。 它的key、value都不能够为null。 此外,Hashtable中的映射不是有序的。 c .HashMap经过哈希表
对其内部的映射联系进行快速查找
。
Vector
类 a.Vector
是矢量行列,它是JDK1.0
版别增加的类。承继于AbstractList
,完结了List
,RandomAccess
,Cloneable
这些接口。 b.Vector
承继了AbstractList
,完结了List
;所以,它是一个行列,支撑相关的增加、删去、修正、遍历等功用。 c.Vector
完结了RandmoAccess
接口,即供给了随机拜访功用。RandmoAccess是java中用来被List完结,为List供给快速拜访功用的。在Vector中,咱们即能够经过元素的序号快速获取元素目标;这便是快速随机拜访。 d.Vector
完结了Cloneable
接口,即完结clone()
函数。它能被克隆。 e. 和ArrayList
不同,Vector
中的操作是线程安全的。
Stack
类 a.Stack
是栈。它的特性
是:先进后出
(FILO, First In Last Out)。 b. java工具包中的Stack是承继于Vector(矢量行列)的,由于Vector是经过数组完结的, 这就意味着,Stack也是经过数组完结的,而非链表。 当然,咱们也能够将LinkedList当作栈来运用;
- 线程安全
- 线程安全:Hashtable、Vector、Stack
- 线程不安全:HashMap 、ArrayList、LinkedList 、HashSet、TreeSet、TreeMap
- HashMap 四种同步办法的功用比较
- HashSet同步办法:
Set s = Collections.synchronizedSet(new HashSet(...));
synchronizedSet()回来的Set是同步的;
- key/value 可否为空(关于List,Set,Map能否存储null)
key/value 可为空: ArrayList、LinkedList 能够存储多个null; HashSet(只能有一个null的节点)、 HashMap (key、value都能够为null,只能有一个key == null的节点)、 Vector 底层是数组,所以不会管你元素的内容是什么,能够存储多个null、
key/value 不行为空: TreeSet不能有key为null的元素、 TreeMap不能有key为null的元素、 HashTable(key、value都不能够为null)
- 是否有序(遍历时是否按增加元素时的次序) ( 常见Map 及 List 是否有序总结 ) (java中ArrayList 、LinkList差异) (知乎:Java遍历HashSet为什么输出是有序的?)
有序:LinkedList、ArrayList、TreeSet、Vector、Stack(先进后出)、 TreeMap (依据其键的天然次序进行排序)、
无序: HashMap中的映射不是有序、 Hashtable、HashSet(“不确保有序”,但也不是“确保无序”,时有时无)
弥补:
List接口的完结类 List接口的常用完结类有
ArrayList
与LinkedList
.Set调集
- Set调会集的目标
不按特定的办法排序
,仅仅简略地把目标加入调会集
;- Set调会集
不能包括重复目标
;- Set调集由
Set接口
和Set接口的完结类
组成。- Set接口承继了
Collection接口
,因而包括Collection接口的一切办法
。
Set接口常用的完结类有HashSet类
与TreeSet类
。Map调集
- Map调集没有承继
Collection
接口,其供给的是key到value的映射
;- Map中不能包括相同的
key
,每个key
只能映射一个value
;- key还决议了
存储目标在映射中的存储方位
, 但不是由key目标本身
决议的,而是经过一种“散列技能”
进行处理,产生一个散列码的整数值
;散列码
一般用作一个偏移量
,该偏移量对应分配给映射的内存区域的开端方位
,然后确认存储目标在映射中的存储方位
;- Map调集包括Map接口以及Map接口的一切完结类。
- Map接口
- Map接口供给了将key映射到值的目标。
- 一个映射不能包括重复的key,每个key最多只能映射到一个值。
- Map接口中相同供给了调集的常用办法,除此之外还包括如下表所示的常用办法: 留意:Map调会集答应值目标是null,而且没有个数约束,例如,可经过“map.put(“05”,null)”句子向调会集增加目标。
- Map接口的完结类
- Map接口常用的完结类有
HashMap
和TreeMap
;- 主张运用
HashMap类
完结Map调集;- 由
HashMap类
完结的Map调集增加和删去映射联系功率更高
;- HashMap是依据
哈希表
的Map接口
的完结;- HashMap经过
哈希码
对其内部的映射联系进行快速查找
;TreeMap
中的映射联系存在必定的次序
;- 假如期望Map调会集的目标也存在必定的次序,应该运用TreeMap类完结Map调集。
相关阅览:
- Java知识梳理 | 详析三大调集类
- 图解调集 4 :HashMap【存储单元Entry】
- Java 调集系列14之 Map总结(HashMap, Hashtable, TreeMap, WeakHashMap等运用场景)
底层完结
与源码剖析
详析能够见此:
Java 调集系列03之 ArrayList具体介绍(源码解析)和运用示例
Java 调集系列05之 LinkedList具体介绍(源码解析)和运用示例
Java 调集系列06之 Vector具体介绍(源码解析)和运用示例
Java 调集系列07之 Stack具体介绍(源码解析)和运用示例
Java 调集系列10之 HashMap具体介绍(源码解析)和运用示例
Java 调集系列11之 Hashtable具体介绍(源码解析)和运用示例
Java 调集系列12之 TreeMap具体介绍(源码解析)和运用示例
Java 调集系列16之 HashSet具体介绍(源码解析)和运用示例
Java 调集系列17之 TreeSet具体介绍(源码解析)和运用示例
Java HashMap源码剖析
详解 equals() 办法和 hashCode() 办法
java中hashCode()办法的效果
java源码剖析之LinkedList
LinkedList源码剖析(依据JDK8)
3.HashMap跟HashTable有什么别离?
HashMap和Hashtable的相同点:
- HashMap和Hashtable都是存储“键值对(key-value)”的散列表,而且都是选用拉链法完结的。
- 增加key-value键值对的根本逻辑;
- 删去key-value键值对的根本逻辑;
HashMap和Hashtable的不同点:
- 承继和完结办法不同
- 线程安全不同
- 对null值的处理不同
- 支撑的遍历品种不同
- 经过Iterator迭代器遍历时,遍历的次序不同
- 容量的初始值 和 增加办法都不相同
- 增加key-value时的hash值算法不同
- 部分API不同
具体见此文章:Java 调集系列14之 Map总结(HashMap, Hashtable, TreeMap, WeakHashMap等运用场景)
相关阅览:
- HashMap和Hashtable的差异
- 《HashMap底层完结原理/HashMap与HashTable差异/HashMap与HashSet差异》
- 《面试必备:HashMap、Hashtable、ConcurrentHashMap的原理与差异》
4.HashMap里边的Hash函数是用什么算法去写的?或许是说傍边的Hash有没有或许呈现抵触的?
依据JDK1.6.0_45
-
HashMap是依据
“拉链法”
完结的散列表
。 -
存储思维
:经过table
数组存储,数组的每一个元素都是一个Entry
; 而一个Entry
便是一个单向链表
,Entry链表
中的 每一个节点
就保存了key-value键值对数据
。 关于table界说的两行源码:static class Entry<K,V> implements Map.Entry<K,V>
transient Entry[] table;
-
增加key-value键值对
: 首要依据key值
计算出哈希值
,再计算出数组索引
(即,该key-value节点在table中的索引)。 然后,依据数组索引
找到Entry
(即,单向链表),再遍历单向链表,将key和链表中的每一个节点的key进行对比。 若key
现已存在Entry链表
中(抵触
),则用该value值取代旧的value值; 若key
不存在Entry链表
中,则新建一个key-value节点,并将该节点刺进Entry链表的表头方位。
“首要依据
key值
计算出哈希值
” 一言的更深一步了解: 即咱们在用HashMap(或许HashMTable)的put(K key, V value)
办法时, 实参值会传给形参变量key,这时分JVM会为形参key分配一块内存,并赋予其地址, 随后在put办法中,进行int hash = hash(key.hashCode());
,即双重哈希,减少抵触率;
默许状况下,Object中的hashCode() 回来目标的 32位JVM内存地址。 也便是说假如目标不重写该办法,则回来相应目标的 32为JVM内存地址。 即key调用hashCode()办法得到其hashCode 值(该办法适用于每个Java目标), 接着再用HashMap中的hash办法进行第二重哈希,
计算出哈希值
;
-
删去key-value键值对
:删去键值对
的逻辑比较于增加键值对
简略一些。 首要,还是依据key计算出哈希值,再计算出数组索引(即,该key-value在table中的索引)。 然后,依据索引找出Entry(即,单向链表)。 若节点key-value存在与链表Entry中(抵触
),则删去链表中的节点即可。
依据JDK1.8
- JDK1.8对
“拉链法”
进行了 “晋级”, 即引入了 红黑树,大程度优化了HashMap的功用; 在增加key-value键值对
时分, 某个数组元素table[i]
的链表长度
假如**大于8
**, 则把链表
转换为红黑树
,在红黑树中履行刺进操作, 否则仍旧进行链表
的刺进操作(似同JDK1.6);
相关阅览:
- 图解调集 4 :HashMap【存储单元Entry】
- Java 调集系列10之 HashMap具体介绍(源码解析)和运用示例
- Java 调集系列14之 Map总结(HashMap, Hashtable, TreeMap, WeakHashMap等运用场景)
- 用拉链法和线性探测法处理哈希抵触
- HashMap中的hash与rehash
- Java8系列之从头认识HashMap
- 【调集结构】JDK1.8源码剖析之HashMap(一)
- JDK1.8源码阅览系列之四:HashMap (原创)
- 五分钟搞懂什么是红黑树(全程图解)
- 史上最清晰的红黑树讲解(上)
- 红黑树刺进的结点为什么着为红色
- 图解调集 8 : 红黑树的移除节点操作
- 图解调集7:红黑树概念、红黑树的刺进及旋转操作具体解读
5.Java中完结多线程的办法有哪几种?
参阅:
- 不谨慎地说,Java中完结多线程的办法有两类,即
承继Thread类
以及完结Runnable接口
;
- 1.
承继Thread类
创立一个类【普通具体类
或许匿名内部类
皆可!!!】去承继Thread类并重写run()
办法, 运用的时分结构一个这个类的目标去调用start()
办法,【匿名内部类
直接new完就start()
】 即可让run()办法中的代码在子线程中运转;
class MyThread extends Thread{ @Override public void run(){ //处理具体逻辑 } }
new MyThread().start();
- 可是运用承继的办法耦合性有点高, 更多的时分咱们都会挑选运用
完结Runnable接口
的办法来界说一个线程;或许运用匿名内部类
去完结简略的线程敞开;
- 2.
完结Runnable接口
- 2.1 界说一个类,让它完结Runnable接口并重写run()办法, 运用的时分结构一个这个类的目标, 然后将这个类目标作为参数传给Thread类的结构办法, 结构好Thread之后调用start()办法即可让run()办法中的代码在子线程中运转;
class MyThread implements Runnable{ @Override public void run(){ //处理具体逻辑 } }
MyThread myThread = new MyThread(); new Thread(myThread).start;//Thread的结构函数接纳一个Runnable参数
- .
- .
- 2.2 运用匿名内部类的办法,调用Runnable的结构办法并重写run()办法, 得到一个匿名内部类, 然后把整个匿名内部类作为参数传给Thread类的结构办法, 结构好Thread之后调用start()办法即可让run()办法中的代码在子线程中运转;
new Thread(new Runnable(){ @Override public void run(){ //处理具体逻辑 } }).start();
- .
- .
- 2.3 准备好一个
Runnable
实例(实例化
还是匿名内部类
的办法都行), 再运用绑定子线程Looper
的一个Handler实例
的post()
或许postDelayed()
, post这个Runnable
实例到子线程处理,即可完结子线程使命敞开! 【Handler实例
要绑定子线程Looper
才是处理子线程使命, 否则绑定mainLooper
便是提交到主线程
处理了!!!】实践上归根到底, 以上也便是
完结线程履行单元
(线程的履行单元
便是run
办法)的两种办法, 而创立线程的办法
永远只有一种——结构Thread类
, 刚才罗列的两类办法最终归结到new Thread().start();
上来。
实践上在运用中,咱们都能够环绕Thread的许多结构办法,
做各种不相同完结线程履行单元
的办法:
6.Java傍边的内存办理是怎样做的?它和C++对应的有什么别离呢?
Java 程序运转时的内存分配战略有三种,别离是
静态分配
、栈式分配
和堆式分配
, 三种办法所运用的内存空间别离是静态存储区(办法区)
、栈区
和堆区
。
静态存储区(办法区)
:首要寄存静态变量
。 这块「内存」在程序编译时就现已分配好了, 而且在程序整个运转期间都存在。栈区
:当办法被履行时, 办法体内的局部变量(包括根底数据类型、目标的引证)都在栈上创立, 并在办法履行完毕时, 这些局部变量所持有的内存将会主动被开释。 由于栈内存分配运算内置于处理器的指令会集,功率很高,可是分配的内存容量有限。堆区
:又称动态内存分配,一般便是指程序运转时直接 new 出来的内存,也便是目标的实例,这部分「内存」在不运用时将会被 Java 废物收回器来负责收回。
别的一种区分了解: JVM会用一段空间来存储履行程序期间需求用到的数据和相关信息, 这段空间便是运转时数据区(Runtime Data Area),也便是常说的JVM内存。
JVM会将它所办理的内存区分为 线程私有数据区 和 线程同享数据区两大类:
线程私有数据区
包括:
程序计数器
:是当时线程所履行的字节码的行号指示器虚拟机栈
:是Java办法履行的内存模型本地办法栈
:是虚拟机运用到的Native办法服务
线程同享数据区
包括:
Java堆
:用于寄存简直一切的目标实例和数组; 是废物搜集器办理的首要区域,也被称做“GC堆”; 是Java虚拟机所办理的内存中最大的一块办法区
:用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据; Class文件中除了有类的版别、字段、办法、接口等描述信息外, 还有一项信息是常量池(Constant Pool Table),用于寄存编译期生成的各种字面量和符号引证, 这部分内容将在类加载后进入办法区的运转时常量池中寄存;
相关阅览:
- 你真的懂 Java 的内存办理和引证类型吗?
- 2019校招Android面试题解1.0(下篇)
7.关于虚拟机那些个新生代和持久代的,你有看过他们的战略吗?
参阅答复:
(1)
断定目标可收回有两种办法
:
引证计数算法
:给目标中增加一个引证计数器,每逢有一个当地引证它时,计数器值就加1;当引证失效时,计数器值就减1;任何时刻计数器为0的目标便是不行能再被运用的。可是在干流的Java虚拟机里未选用引证计数算法来办理内存,首要原因是它难以处理目标之间彼此循环引证的问题,所以呈现了另一种目标存活断定算法。可达性剖析法
:经过一系列被称为『GC Roots』的目标作为开端点,从这些节点开端向下查找,查找所走过的途径称为引证链,当一个目标到GC Roots没有任何引证链相连时,则证明此目标是不行用的。其间可作为GC Roots的目标:虚拟机栈中引证的目标,首要是指栈帧中的本地变量、本地办法栈中Native办法引证的目标、办法区中类静态特色引证的目标、办法区中常量引证的目标
(2)
收回算法有以下四种
:
分代搜集算法
:是当时商业虚拟机都选用的一种算法,依据目标存活周期的不同,将Java堆区分为新生代和老时代,并依据各个时代的特色选用最恰当的搜集算法。
新生代
:大批目标死去,只有少数存活。运用『仿制算法』,只需仿制少数存活目标即可。
仿制算法
:把可用内存按容量区分为巨细相等的两块,每次只运用其间的一块。当这一块的内存用尽后,把还存活着的目标『仿制』到别的一块上面,再将这一块内存空间一次收拾掉。
老时代
:目标存活率高。运用『符号—收拾算法』或许『符号—收拾算法』,只需符号较少的收回目标即可。
符号-铲除算法
:首要『符号』出一切需求收回的目标,然后统一『铲除』一切被符号的
符号-收拾算法
:首要『符号』出一切需求收回的目标,然后进行『收拾』,使得存活的目标都向一端移动,最后直接收拾掉端边界以外的内存。相关阅览:
- 你真的懂 Java 的内存办理和引证类型吗?
- 2019校招Android面试题解1.0(下篇)
8.Java傍边判别两个目标是否相同的时分有哪些办法?
- Java中判别两个目标是否相一同有两种办法——用
==
或许equals()
;
==
是比较两个目标在JVM中的地址
。 cequals()
是根类Obeject
中的办法, 查看源码咱们能够知道默许的equals()
办法中, 首选也是直接调用==
,比较目标地址:
当然真正运用的时分,咱们需求在自界说类中对
equals()
进行重载, 然后能使重载后的equals()
除了==
的判别效果之外, 还能够判别两个目标中具体各成员的值或许结构
是否相同; 而根本数据类型的实例
就不必咱们操心了,JDK中现已重载好了。相关阅览:
- java中的==、equals()、hashCode()源码剖析
- Java hashCode() 和 equals()的若干问题解答
4. Android(0.66)
1. 能不能在子线程里边做UI更新(界面更新)?为什么?
- 系统不主张在子线程拜访UI: UI控件 非线程安全 ,在多线程中并发拜访或许会导致UI控件处于不行预期的状况。
- 而不对UI控件的拜访加上锁机制的原因有: 上锁会让UI控件变得复杂和低效; 上锁后会堵塞某些进程的履行;
如此,既然UI不能上锁,非线程安全, 那天然是只能有一个线程有权操作它, 在整个程序中,只能有一个线程,那主线程(UI线程)天然见义勇为了。
2.有没有遇到过内存泄漏的场景?
Android内存泄漏指的是进程中某些目标(废物目标)现已没有运用价值了, 可是它们却能够直接或间接地引证到gc roots导致无法被GC收回。 无用的目标占据着内存空间,使得实践可运用内存变小,形象地说法便是内存泄漏了。
场景
类的静态变量持有大数据目标 静态变量长时间坚持到大数据目标的引证,阻挠废物收回。
非静态内部类的静态实例 非静态内部类会坚持一个到外部类实例的引证, 假如非静态内部类的实例是静态的, 就会间接长时间坚持着外部类的引证,阻挠被收回掉。
资源目标未封闭 资源性目标如Cursor、File、Socket,应该在运用后及时封闭。 未在finally中封闭,会导致异常状况下资源目标未被开释的危险。
注册目标未反注册 未反注册会导致观察者列表里坚持着目标的引证,阻挠废物收回。
Handler临时性内存走漏 Handler经过发送Message与主线程交互, Message发出之后是存储在MessageQueue中的, 有些Message也不是马上就被处理的。 在Message中存在一个 target,是Handler的一个引证, 假如Message在Queue中存在的时刻越长,就会导致Handler无法被收回。 假如Handler对错静态的,则会导致Activity或许Service不会被收回。 由于AsyncTask内部也是Handler机制,相同存在内存泄漏的风险。 此种内存走漏,一般是临时性的。
- BAT Android常见面试题详解 (你假如有两个当地一同引证这块内存的话,那其实仅仅这块内存被复用了而已,为什么会引起内存泄漏呢?) (假如a引证了一个当地,你假如不必的话,你能够把a开释掉,那b还能够持续正常运用啊)
3.Android中关于多个Activity之间的通讯,你是怎样做的?
- 在service中履行完耗时操作后,将成果以播送的办法发送, 在一切的activity中注册播送,接纳到成果后更新UI; 这种办法比较简略,也是比较引荐的办法。 由于耗时的操作成果不需求以handler的办法发送到主线程, 能够直接在子线程中发送播送,接纳者始终运转在主线程中。
在这种办法中,
service
和broadcast
都作为多个Activity之间通讯
的前言
; 一切绑定了前言service
的一系列Activity
, 都能够把需求处理的数据
传给service
; 经过service
中子线程的sendBroadcast()
之手, 以播送的办法(把处理完毕的数据参数), 发送到同系列(绑定了相同的前言service
,注册了相同的前言Receiver
)的 各个Activity
手中(包括发送待处理数据参数的Activity
本身);
各个
Activity
经过绑定前言service
,调用service
中的办法
, 把需求处理的数据
作为service中办法的参数
传给service
;
service
接纳到Activity
送来的待处理数据参数, 将之送进子线程
中处理,子线程
处理完数据之后, 将处理完毕的数据
作为参数putExtra
到intent
中,intent
发送播送
,将处理完毕的数据
发送出去;相关
Activity
接纳到处理完毕的数据
, 回调onReceive()
,进行数据的获取、接纳处理
以及UI的更新
;
– 下面这个是模型图
(其间name
是概念笼统出来的 多个Activity之间通讯
的数据内容
,
在实践运用中咱们能够用各种数据办法
来 掩盖这个参数name
的方位):
结合以上模型图以及下面这篇博文能够进一步具体了解;
- Android中Service与多个Activity通信的三种办法
4.Activity的生命周期是什么姿态的?
在Activity的生命周期触及到七大办法,别离是:
onCreate()表明Activity 正在创立,常做初始化工作,如setContentView界面资源、初始化数据
onStart()表明Activity 正在发动,这时Activity 可见但不在前台,无法和用户交互
onResume()表明Activity 取得焦点,此时Activity 可见且在前台并开端活动
onPause()表明Activity 正在停止,可做 数据存储、停止动画等操作
onStop()表明activity 行将停止,可做略微重量级收回工作,如取消网络衔接、刊出播送接纳器等
onDestroy()表明Activity 行将销毁,常做收回工作、资源开释
别的,当Activity由后台切换到前台,由不行见到可见时会调用onRestart(),表明Activity 从头发动
- 2019校招Android面试题解1.0(上篇)
5.具体的场景,反正屏切换的时分,Activity的生命周期是什么姿态的?
当非人为停止Activity时, 比如系统配置产生改变时导致Activity被杀死并从头创立、资源内存不足导致低优先级的Activity被杀死, 会调用 onSavaInstanceState() 来保存状况。 该办法调用在
onStop
之前,但和onPause
没有时序联系。Activity被从头创立时会调用onRestoreInstanceState(该办法在onStart之后), 并将onSavaInstanceState保存的Bundle目标作为参数传到onRestoreInstanceState与onCreate办法。
1.AndroidManifest没有设置configChanges特色
竖(横)屏发动: onCreate –>onStart–>onResume
切换横(竖)屏: onPause –>onSaveInstanceState –>onStop –>onDestroy –>onCreate–>onStart –> onRestoreInstanceState–>onResume (Android 6.0 Android 7.0 Android 8.0)
2.AndroidManifest设置了configChanges
android:configChanges="orientation"
竖(横)屏发动:: onCreate –>onStart–>onResume
切换横(竖)屏:
onPause –>onSaveInstanceState –>onStop –>onDestroy –>onCreate–>onStart –> onRestoreInstanceState–>onResume (Android 6.0)
onConfigurationChanged–>onPause –>onSaveInstanceState –>onStop –>onDestroy –> onCreate–>onStart –>onRestoreInstanceState–>onResume (Android 7.0)
onConfigurationChanged (Android 8.0)
总结: 设置了configChanges特色为orientation之后,Android6.0 同没有设置configChanges状况相同; Android 7.0则会先回调onConfigurationChanged办法,剩余的流程跟Android 6.0 坚持一致; Android 8.0 则仅仅回调了onConfigurationChanged办法。
3.AndroidManifest设置了configChanges
android:configChanges="orientation|keyboardHidden|screenSize"
竖(横)屏发动:onCreate –>onStart–>onResume 切换横(竖)屏:onConfigurationChanged (Android 6.0 Android 7.0 Android 8.0)总结: 设置android:configChanges=”orientation|keyboardHidden|screenSize” 则都不会调用Activity的其他生命周期办法, 只会调用onConfigurationChanged办法。
- 浅析Activity反正屏切换时的生命周期
5. 数据结构(0.8)
常用的排序算法有哪些,各自的时刻复杂度是怎样样的?
- 参阅:如下表:
6. 其他
我看你学过一点神经网络对吧?
(简书之前由于导师鞭笞,写了不少关于Python和机器学习的文章)
参阅:依据本身所掌握的知识答复,天然是了解多少答多少,
内容能够触及神经网络,神经网络节点,激励函数,节点的输入输出联系等等,有条件的同学能够讲一下TensorFlow。