前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >01 详析一次腾讯一面 | 移动端开发岗

01 详析一次腾讯一面 | 移动端开发岗

作者头像
凌川江雪
发布2019-05-13 20:36:17
6480
发布2019-05-13 20:36:17
举报
文章被收录于专栏:李蔚蓬的专栏李蔚蓬的专栏
  • 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 URL传给一个URL对象的构造方法,创建出一个URL实例, 用这个URL实例调用其openConnection()方法,会返回一个对象, 将其返回的对象转型为HttpURLConnection对象并付给一个HttpURLConnection实例, 接着就可以调用HttpURLConnection实例的一系列set方法对这个请求做各种设置, 其中调用方法setRequestProperty("Connection", "Keep-Alive")即可完成这个请求的长连接的实现; 当然除了以上Android端的配置意外,我们还需要在服务器设置好Keep- Alive长连接模式, 是否能完成一个完整的Keep- Alive连接和服务器设置也相关;
  • HttpURLConnection 的 demo:
代码语言:txt
复制
        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会话。
代码语言:txt
复制
    - 而从HTTP/1.1起,默认使用长连接,用以保持连接特性。 使用长连接的HTTP协议,会在响应头加入这行代码:

在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,客户端再次访问这个服务器时,会继续使用这一条已经建立的连接。

Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。

实现长连接需要客户端和服务端都支持长连接。

代码语言:txt
复制
    - HTTP协议的长连接和短连接,实质上是TCP协议的长连接和短连接。
代码语言:txt
复制
-  **`长连接,短连接的适用场景?`** 

像WEB网站的http服务一般都用短链接

因为长连接对于服务端来说会耗费一定的资源,

而像WEB网站这么频繁的成千上万甚至上亿客户端的连接用短连接会更省一些资源,

如果用长连接,而且同时有成千上万的用户,如果每个用户都占用一个连接的话,那可想而知吧。

所以并发量大,但每个用户无需频繁操作情况下需用短连好

相关阅读:

5.客户端到服务器拉数据的时候你是用GET还是用POST去取的?

参考:拉数据的时候是用GET去取的,另外:

  • GETPOST本质上是没有区别的,它们都是**TCP**链接,
代码语言:txt
复制
-  **GET和POST能做(能做——具备实现的能力)的事情一样一样**。 技术上要给GET加上request body,给POST带上url参数,也是行的通的。
    - 只不过
  • 应用过程上的区别
代码语言:txt
复制
-  **00 关于服务器(2点):**
代码语言:txt
复制
    - **GET是从服务器上获取数据,** 
代码语言:txt
复制
    - GET产生一个TCP数据包, 浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
 POST产生两个TCP数据包,浏览器先发送header,
 服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。
 也就是说,
 
代码语言:txt
复制
    - http协议从未规定GET/POST的请求长度限制是多少; 但是实际应用上,
 
代码语言:txt
复制
    -  从`本质意义`上讲,GET是安全的,POST不安全:
代码语言:txt
复制
        - GET没有更改服务器内容;
        - POST对服务器就行写入、覆盖,会更改服务器内容;
    -  幂等性(同样的一个操作,它一次或者多次地操作,对系统资源产生的影响是一样的)
代码语言:txt
复制
        - GET具备幂等性;
        - POST不具备; (原因参照对服务器是否有修改)
代码语言:txt
复制
- GET与POST都有自己的语义,不能随便混用。
- 据研究,在网络环境好的情况下, 发一次包的时间和发两次包的时间差别基本可以无视。
 而在网络环境差的情况下,
 两次包的TCP在验证数据包完整性上,有非常大的优点。
    - 并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。

相关阅读:

6.在做的过程中有没有遇到过HTTP的错误,比如说HTTP的那些错误码?

  • 参考回答:状态码由三位数字组成,第一位数字表示响应的类型,常用的状态码有五大类:
代码语言:txt
复制
- 1xx:表示服务器已接收了客户端请求,客户端可继续发送请求
-  2xx:表示服务器已成功接收到请求并进行处理
代码语言:txt
复制
    - 200 OK:表示客户端请求成功
- 3xx:表示服务器要求客户端重定向
-  4xx:表示客户端的请求有非法内容
代码语言:txt
复制
    - 400 Bad Request:表示客户端请求有语法错误,不能被服务器所理解
    - 401 Unauthonzed:表示请求未经授权,该状态代码必须与 WWW-Authenticate 报头域一起使用
    - 403 Forbidden:表示服务器收到请求,但是拒绝提供服务,通常会在响应正文中给出不提供服务的原因
    - 404 Not Found:请求的资源不存在,例如,输入了错误的URL
    - 414     :Request-URI 太长
-  5xx:表示服务器未能正常处理客户端的请求而出现意外错误
代码语言:txt
复制
    - 500 Internal Server Error:表示服务器发生不可预期的错误,导致无法完成客户端的请求 503 Service Unavailable:表示服务器当前不能够处理客户端的请求,在一段时间之后,服务器可能会恢复正常

相关阅读:

3. Java(0.4-0.5)

1.String、StringBuffer、StringBuilder三个的分别?

  • 综述:
代码语言:txt
复制
- String:不可变字符串;
- StringBuffer:可变字符串、效率低、线程安全;
- StringBuilder:可变字符序列、效率高、线程不安全;
- 执行速度:StringBuilder > StringBuffer > String; (StringBuffer 很多方法可以带有synchronized关键字,在做字符串操作时需要做对应的操作,所以运行性能比StringBuilder稍微差些)
    -undefined 

StringBuffer、 StringBuilder的API基本一样:

  • 详析:
代码语言:txt
复制
-  **`String`****的值是不可变的,** 

JVM对于上图是这样处理的,

首先创建一个String对象str,并把“hello”赋值给str,

然后str=str+" world":

其实JVM又创建了一个新的对象也名为str,

然后再把原来的str的值和“ world”加起来再赋值给新的str,

而原来的str就会被JVM的垃圾回收机制(GC)给回收掉了,

所以,最开始的str实际上并没有被更改,

也就是前面说的String对象一旦创建之后就不可更改了(String的值是不可变的)。

这样短短的两个字符串,却需要开辟三次内存空间,不得不说这是对内存空间的极大浪费。

所以,

Java中对String对象进行的操作,

实际上是一个不断创建新的对象并且将旧的对象回收的一个过程,执行速度很慢。

代码语言:txt
复制
-  `StringBuffer`是**可变的、线程安全**的字符串操作类, 任何对它指向的字符串的操作都不会产生新的对象。
 每个StringBuffer对象都有一定的缓冲区容量,
 当字符串大小
代码语言:txt
复制
- String:适用于操作少量的字符串/数据的情况
- StringBuilder:适用于单线程操作字符串缓冲区下操作大量数据的情况
- StringBuffer:适用于多线程操作字符串缓冲区下操作大量数据的情况

相关阅读:

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,实现了MapCloneablejava.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,实现了MapCloneablejava.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接口的常用实现类有ArrayListLinkedList.
  • Set集合
代码语言:txt
复制
- Set集合中的对象`不按特定的方式排序`,只是`简单地把对象加入集合中`;
- Set集合中`不能包含重复对象`;
- Set集合由`Set接口`和`Set接口的实现类`组成。
- Set接口继承了`Collection接口`,因此包含`Collection接口的所有方法`。

Set接口常用的实现类有HashSet类TreeSet类

  • Map集合
代码语言:txt
复制
- Map集合没有继承`Collection`接口,其提供的是`key到value的映射`;
- Map中不能包含相同的`key`,每个`key`只能映射一个`value`;
- key还决定了`存储对象在映射中的存储位置`, 但不是由
代码语言:txt
复制
-  Map接口
代码语言:txt
复制
    - Map接口提供了将key映射到值的对象。
    - 一个映射不能包含重复的key,每个key最多只能映射到一个值。
    - Map接口中同样提供了集合的常用方法,除此之外还包括如下表所示的常用方法:  

注意:Map集合中允许值对象是null,而且没有个数限制,例如,可通过“map.put("05",null)”语句向集合中添加对象。

代码语言:txt
复制
-  Map接口的实现类
代码语言:txt
复制
    - Map接口常用的实现类有`HashMap`和`TreeMap`;
    - 建议使用`HashMap类`实现Map集合;
    - 由`HashMap类`实现的Map集合`添加和删除映射关系效率更高`;
    - HashMap是基于`哈希表`的`Map接口`的实现;
    - HashMap通过`哈希码`对其内部的映射关系进行`快速查找`;
    -  `TreeMap`中的映射关系存在`一定的顺序`;
    - 如果希望Map集合中的对象也存在一定的顺序,应该使用TreeMap类实现Map集合。

相关阅读:

底层实现源码分析详析可以见此:

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等使用场景)

相关阅读:

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);

相关阅读:

5.Java中实现多线程的方式有哪几种?

参考:

  • 不严谨地说,Java中实现多线程的方式有两类,即继承Thread类以及实现Runnable接口
    • 1.继承Thread类 创建一个类去继承Thread类并重写run()方法, 使用的时候构造一个这个类的对象去调用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();

实际上归根到底,

以上也便是实现线程执行单元线程的执行单元就是run方法)的两种方式,

创建线程的方式永远只有一种——构造Thread类

方才罗列的两类方法最终归结到new Thread().start();上来。

实际上在运用中,我们都可以围绕Thread的诸多构造方法,

做各种不一样实现线程执行单元的方式:

6.Java当中的内存管理是怎么做的?它和C++对应的有什么分别呢?

Java 程序运行时的内存分配策略有三种,分别是静态分配栈式分配堆式分配, 三种方式所使用的内存空间分别是静态存储区(方法区)栈区堆区

  • 静态存储区(方法区):主要存放静态变量。 这块「内存」在程序编译时就已经分配好了, 并且在程序整个运行期间都存在。
  • 栈区:当方法被执行时, 方法体内的局部变量(包括基础数据类型、对象的引用)都在栈上创建, 并在方法执行结束时, 这些局部变量所持有的内存将会自动被释放。 因为栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
  • 堆区:又称动态内存分配,通常就是指程序运行时直接 new 出来的内存,也就是对象的实例,这部分「内存」在不使用时将会被 Java 垃圾回收器来负责回收。

  • 另外一种划分理解: JVM会用一段空间来存储执行程序期间需要用到的数据和相关信息, 这段空间就是运行时数据区(Runtime Data Area),也就是常说的JVM内存。

JVM会将它所管理的内存划分为 线程私有数据区线程共享数据区两大类:

代码语言:txt
复制
-  **`线程私有数据区`**包含:
代码语言:txt
复制
    -  **`程序计数器`**:是当前线程所执行的字节码的行号指示器
    -  **`虚拟机栈`**:是Java方法执行的内存模型
    -  **`本地方法栈`**:是虚拟机使用到的Native方法服务
代码语言:txt
复制
-  **`线程共享数据区`**包含:
代码语言:txt
复制
    -  **`Java堆`**:用于存放几乎所有的对象实例和数组; 是垃圾收集器管理的主要区域,也被称做“GC堆”;
 是Java虚拟机所管理的内存中最大的一块
        -  

相关阅读:

7.对于虚拟机那些个新生代和持久代的,你有看过他们的策略吗?

参考回答:

  • (1) 判定对象可回收有两种方法
代码语言:txt
复制
-  **`引用计数算法`**:给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时刻计数器为0的对象就是不可能再被使用的。然而在主流的Java虚拟机里未选用引用计数算法来管理内存,主要原因是它难以解决对象之间相互循环引用的问题,所以出现了另一种对象存活判定算法。
-  **`可达性分析法`**:通过一系列被称为『GC Roots』的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。其中可作为GC Roots的对象:虚拟机栈中引用的对象,主要是指栈帧中的本地变量、本地方法栈中Native方法引用的对象、方法区中类静态属性引用的对象、方法区中常量引用的对象
  • (2)回收算法有以下四种
代码语言:txt
复制
-  **`分代收集算法`**:是当前商业虚拟机都采用的一种算法,根据对象存活周期的不同,将Java堆划分为新生代和老年代,并根据各个年代的特点采用最适当的收集算法。
代码语言:txt
复制
    -  **`新生代`**:大批对象死去,只有少量存活。使用『复制算法』,只需复制少量存活对象即可。
代码语言:txt
复制
        -  **`复制算法`**:把可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用尽后,把还存活着的对象『复制』到另外一块上面,再将这一块内存空间一次清理掉。
    -  **`老年代`**:对象存活率高。使用『标记—清理算法』或者『标记—整理算法』,只需标记较少的回收对象即可。
代码语言:txt
复制
        -  **`标记-清除算法`**:首先『标记』出所有需要回收的对象,然后统一『清除』所有被标记的
代码语言:txt
复制
        -  **`标记-整理算法`**:首先『标记』出所有需要回收的对象,然后进行『整理』,使得存活的对象都向一端移动,最后直接清理掉端边界以外的内存。

相关阅读:

8.Java当中判断两个对象是否相同的时候有哪些方法?

  • Java中判断两个对象是否相同时有两种方法——用==或者equals()
    • ==是比较两个对象在JVM中的地址。 cequals()是根类Obeject中的方法, 查看源码我们可以知道默认的equals()方法中, 首选也是直接调用==,比较对象地址:

当然真正使用的时候,我们需要在自定义类中对equals()进行重载,

从而能使重载后的equals()除了==的判断作用之外,

还可以判断两个对象中具体各成员的值或者构造是否相同;

基本数据类型的实例就不用我们费心了,JDK中已经重载好了。

相关阅读:

4. Android(0.66)

1. 能不能在子线程里面做UI更新(界面更新)?为什么?

  • 系统不建议在子线程访问UI: UI控件 非线程安全 ,在多线程中并发访问可能会导致UI控件处于不可预期的状态。
  • 而不对UI控件的访问加上锁机制的原因有: 上锁会让UI控件变得复杂和低效; 上锁后会阻塞某些进程的执行;

如此,既然UI不能上锁,非线程安全,

那自然是只能有一个线程有权操作它,

在整个程序中,只能有一个线程,那主线程(UI线程)自然当仁不让了。

2.有没有遇到过内存泄漏的场景?

  • Android内存泄漏指的是进程中某些对象(垃圾对象)已经没有使用价值了, 但是它们却可以直接或间接地引用到gc roots导致无法被GC回收。 无用的对象占据着内存空间,使得实际可使用内存变小,形象地说法就是内存泄漏了。
  • 场景
代码语言:txt
复制
- 类的静态变量持有大数据对象 静态变量长期维持到大数据对象的引用,阻止垃圾回收。
    - 非静态内部类的静态实例
 非静态内部类会维持一个到外部类实例的引用,
 如果非静态内部类的实例是静态的,
 就会间接长期维持着外部类的引用,阻止被回收掉。
    - 资源对象未关闭
 资源性对象如Cursor、File、Socket,应该在使用后及时关闭。
 未在finally中关闭,会导致异常情况下资源对象未被释放的隐患。
    - 注册对象未反注册
 未反注册会导致观察者列表里维持着对象的引用,阻止垃圾回收。
    - Handler临时性内存泄露
 Handler通过发送Message与主线程交互,
 Message发出之后是存储在MessageQueue中的,
 有些Message也不是马上就被处理的。
 在Message中存在一个 target,是Handler的一个引用,
 如果Message在Queue中存在的时间越长,就会导致Handler无法被回收。
 如果Handler是非静态的,则会导致Activity或者Service不会被回收。
 由于AsyncTask内部也是Handler机制,同样存在内存泄漏的风险。
 此种内存泄露,一般是临时性的。

3.Android中对于多个Activity之间的通讯,你是怎么做的?

  • 在service中执行完耗时操作后,将结果以广播的形式发送, 在所有的activity中注册广播,接收到结果后更新UI; 这种方式比较简单,也是比较推荐的方式。 因为耗时的操作结果不需要以handler的方式发送到主线程, 可以直接在子线程中发送广播,接收者始终运行在主线程中。
  • 在这种方法中,servicebroadcast都作为多个Activity之间通讯媒介; 所有绑定了媒介service的一系列Activity, 都可以把需要处理的数据传给service; 经过service中子线程的sendBroadcast()之手, 以广播的方式(把处理完毕的数据参数), 发送到同系列(绑定了同样的媒介service,注册了同样的媒介Receiver)的 各个Activity手中(包括发送待处理数据参数的Activity自身);
代码语言:txt
复制
- 各个`Activity`通过`绑定媒介service`,调用`service`中的`方法`, 把

结合以上模型图以及下面这篇博文可以进一步详细理解;

4.Activity的生命周期是什么样子的?

  • 在Activity的生命周期涉及到七大方法,分别是:
代码语言:txt
复制
- onCreate()表示Activity 正在创建,常做初始化工作,如setContentView界面资源、初始化数据
- onStart()表示Activity 正在启动,这时Activity 可见但不在前台,无法和用户交互
- onResume()表示Activity 获得焦点,此时Activity 可见且在前台并开始活动
- onPause()表示Activity 正在停止,可做 数据存储、停止动画等操作
- onStop()表示activity 即将停止,可做稍微重量级回收工作,如取消网络连接、注销广播接收器等
- onDestroy()表示Activity 即将销毁,常做回收工作、资源释放
- 另外,当Activity由后台切换到前台,由不可见到可见时会调用onRestart(),表示Activity 重新启动

5.具体的场景,横竖屏切换的时候,Activity的生命周期是什么样子的?

当非人为终止Activity时, 比如系统配置发生改变时导致Activity被杀死并重新创建、资源内存不足导致低优先级的Activity被杀死, 会调用 onSavaInstanceState()来保存状态。 该方法调用在**onStop**之前,但和**onPause**没有时序关系。 Activity被重新创建时会调用onRestoreInstanceState(该方法在onStart之后), 并将onSavaInstanceState保存的Bundle对象作为参数传到onRestoreInstanceState与onCreate方法。

  • 1.AndroidManifest没有设置configChanges属性
代码语言:txt
复制
- 竖(横)屏启动: 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"
代码语言:txt
复制
- 竖(横)屏启动:: onCreate -->onStart-->onResume
    -  切换横(竖)屏:
 
代码语言:txt
复制
    - 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
5. 数据结构(0.8)

常用的排序算法有哪些,各自的时间复杂度是怎么样的?

参考:如下表:

6. 其他

我看你学过一点神经网络对吧?

(简书之前因为导师鞭策,写了不少关于Python和机器学习的文章)

参考:根据自身所掌握的知识回答,自然是了解多少答多少,    内容可以涉及神经网络,神经网络节点,激励函数,节点的输入输出关系等等,有条件的同学可以讲一下TensorFlow。


关于结果

再接再厉

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019.05.02 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 综合
  • 1.1.可以先自我介绍一下吗?
  • 1.2.学了这么多东西,你觉得你学的最好的是哪一块?
  • 1.3.有没有什么实战项目做出来呢?
  • 1.4. 你觉得在这个项目当中做起来最难的地方是在哪里?
  • 1.5 除了做Android的话,对C/C++这一块了解吗?
    • 2. 计算机网络(0.4-0.45)
    • 1.Android端跟后台通讯的时候用的是什么协议?
    • 2.(接1. )HTTP是哪一层上面在用的呢?
    • 3.(接2.)那它是基于什么协议去实现的?
    • 4.在项目中,你有可能需要维持APP跟后台之间的长时间连接,那么在实际运用中你是如何实现维持长时间连接的?就是你的这种app跟后台服务的通讯,是一种 短连接 还是一种 长连接 的方式呢?
    • 5.客户端到服务器拉数据的时候你是用GET还是用POST去取的?
    • 6.在做的过程中有没有遇到过HTTP的错误,比如说HTTP的那些错误码?
    • 1.String、StringBuffer、StringBuilder三个的分别?
    • 2.有没有用过Java对应的数据结构的类?
    • 3.HashMap跟HashTable有什么分别?
    • 4.HashMap里面的Hash函数是用什么算法去写的?或者是说当中的Hash有没有可能出现冲突的?
    • 5.Java中实现多线程的方式有哪几种?
    • 6.Java当中的内存管理是怎么做的?它和C++对应的有什么分别呢?
    • 7.对于虚拟机那些个新生代和持久代的,你有看过他们的策略吗?
    • 8.Java当中判断两个对象是否相同的时候有哪些方法?
    • 1. 能不能在子线程里面做UI更新(界面更新)?为什么?
    • 2.有没有遇到过内存泄漏的场景?
    • 3.Android中对于多个Activity之间的通讯,你是怎么做的?
    • 4.Activity的生命周期是什么样子的?
    • 5.具体的场景,横竖屏切换的时候,Activity的生命周期是什么样子的?
    • 常用的排序算法有哪些,各自的时间复杂度是怎么样的?
    • 我看你学过一点神经网络对吧?
    相关产品与服务
    数据保险箱
    数据保险箱(Cloud Data Coffer Service,CDCS)为您提供更高安全系数的企业核心数据存储服务。您可以通过自定义过期天数的方法删除数据,避免误删带来的损害,还可以将数据跨地域存储,防止一些不可抗因素导致的数据丢失。数据保险箱支持通过控制台、API 等多样化方式快速简单接入,实现海量数据的存储管理。您可以使用数据保险箱对文件数据进行上传、下载,最终实现数据的安全存储和提取。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档