cvte 2018 春季实习生招聘 Android 在线测评考点节选

1. service生命周期(http://blog.csdn.net/todo_/article/details/51097453)

被启动的服务的生命周期:如果一个Service被某个Activity 调用

Context.startService 方法启动,那么不管是否有Activity使用bindService绑定或unbindService解除绑定到该Service,该Service都在后台运行。如果一个Service被startService 方法多次启动,那么onCreate方法只会调用一次,onStart将会被调用多次(对应调用startService的次数),并且系统只会创建Service的一个实例(因此你应该知道只需要一次stopService调用)。该Service将会一直在后台运行,而不管对应程序的Activity是否在运行,直到被调用stopService,或自身的stopSelf方法。当然如果系统资源不足,android系统也可能结束服务

cvte 2018 春季实习生招聘 Android 在线测评考点节选_第1张图片

被绑定的服务的生命周期:如果一个Service被某个Activity 调用

Context.bindService 方法绑定启动,不管调用

bindService 调用几次,onCreate方法都只会调用一次,同时onStart方法始终不会被调用。当连接建立之后,Service将会一直运行,除非调用Context.unbindService

断开连接或者之前调用bindService

Context 不存在了(如Activity被finish的时候),系统将会自动停止Service,对应onDestroy将被调用。

cvte 2018 春季实习生招聘 Android 在线测评考点节选_第2张图片

被启动又被绑定的服务的生命周期:如果一个Service又被启动又被绑定,则该Service将会一直在后台运行。并且不管如何调用,onCreate始终只会调用一次,对应startService调用多少次,Service的onStart便会调用多少次。调用unbindService将不会停止Service,而必须调用

stopService 或

Service的

stopSelf 来停止服务。

当服务被停止时清除服务:当一个Service被终止(1、调用stopService;2、调用stopSelf;3、不再有绑定的连接(没有被启动))时,onDestroy方法将会被调用,在这里你应当做一些清除工作,如停止在Service中创建并运行的线程。

特别注意:

你应当知道在调用

bindService 绑定到Service的时候,你就应当保证在某处调用 unbindService 解除绑定(尽管 Activity 被 finish 的时候绑定会自动解除,并且Service会自动停止);

你应当注意 使用

startService 启动服务之后,一定要使用 stopService停止服务,不管你是否使用bindService;

同时使用 startService 与 bindService 要注意到,Service 的终止,需要unbindService与stopService同时调用,才能终止 Service,不管 startService 与 bindService 的调用顺序,如果先调用 unbindService 此时服务不会自动终止,再调用 stopService 之后服务才会停止,如果先调用 stopService 此时服务也不会终止,而再调用 unbindService 或者 之前调用 bindService 的 Context 不存在了(如Activity 被 finish 的时候)之后服务才会自动停止;

当在旋转手机屏幕的时候,当手机屏幕在“横”“竖”变换时,此时如果你的

Activity 如果会自动旋转的话,旋转其实是 Activity 的重新创建,因此旋转之前的使用 bindService 建立的连接便会断开(Context 不存在了),对应服务的生命周期与上述相同。

在 sdk 2.0 及其以后的版本中,对应的 onStart 已经被否决变为了 onStartCommand,不过之前的 onStart 任然有效。这意味着,如果你开发的应用程序用的 sdk 为 2.0 及其以后的版本,那么你应当使用 onStartCommand 而不是 onStart。

生命周期方法说明

onStartCommand()当另一个组件(如 Activity)通过调用 startService() 请求启动服务时,系统将调用此方法。一旦执行此方法,服务即会启动并可在后台无限期运行。

如果您实现此方法,则在服务工作完成后,需要由您通过调用 stopSelf() 或 stopService() 来停止服务。(如果您只想提供绑定,则无需实现此方法。)

onBind()

当另一个组件想通过调用 bindService() 与服务绑定(例如执行 RPC)时,系统将调用此方法。在此方法的实现中,您必须通过返回 IBinder 提供一个接口,供客户端用来与服务进行通信。请务必实现此方法,但如果您并不希望允许绑定,则应返回 null。

onCreate()

首次创建服务时,系统将调用此方法来执行一次性设置程序(在调用 onStartCommand() 或 onBind() 之前)。如果服务已在运行,则不会调用此方法。

onDestroy()

当服务不再使用且将被销毁时,系统将调用此方法。服务应该实现此方法来清理所有资源,如线程、注册的侦听器、接收器等。

这是服务接收的最后一个调用。

2. Android子线程更新UI的方法( http://blog.csdn.net/silleyj/article/details/55006573 )

专业术语:

Message:消息,其中包含了消息ID,消息处理对象以及处理的数据等,由MessageQueue统一列队,终由Handler处理。 

Handler:处理者,负责Message的发送及处理。使用Handler时,需要实现handleMessage(Message msg)方法来对特定的Message进行处理,例如更新UI等。 

MessageQueue:消息队列,用来存放Handler发送过来的消息,并按照FIFO规则执行。当然,存放Message并非实际意义的保存,而是将Message以链表的方式串联起来的,等待Looper的抽取。 

Looper:消息泵,不断地从MessageQueue中抽取Message执行。因此,一个MessageQueue需要一个Looper。 

Thread:线程,负责调度整个消息循环,即消息循环的执行场所。

用Handler

主线程中定义Handler (handleMessage(Message msg))

子线程发消息,通知Handler完成UI更新 (Thread(new Runnable()))

用Activity对象的runOnUiThread方法更新 ,在子线程中通过runOnUiThread()方法更新UI

View.post(Runnabler)

3. Android Service和Thread的区别(https://www.cnblogs.com/carlo/p/4947342.html )

Thread:Thread 是程序执行的最小单元,可以用Thread 来执行一些异步的操作。Thread 的运行是独立的,也就是说当一个 Activity 被 finish 之后,如果没有主动停止 Thread 或者 Thread 里的 run 方法没有执行完毕的话,Thread 也会一直执行。因此这里会出现一个问题:当 Activity 被 finish 之后,不再持有该 Thread 的引用,也就是不能再控制该Thread。另一方面,没有办法在不同的 Activity 中对同一 Thread 进行控制。

Service:Service 是android的一种机制(既不是线程也不是进程),当它运行的时候如果是Local Service,那么对应的 Service 是运行在主进程的 main 线程上的。如果是Remote Service,那么对应的

Service 则是运行在独立进程的 main 线程上。使用Service来处理后台任务,Activity就可以放心地finish,完全不需要担心无法对后台任务进行控制的情况。

4. ConcurrentHashMap

(http://www.importnew.com/22007.html )

5. Volatitle 与 synchronized(https://www.cnblogs.com/hapjin/p/5492880.html )

cvte 2018 春季实习生招聘 Android 在线测评考点节选_第3张图片

从图中可以看出:

每个线程都有一个自己的本地内存空间--线程栈空间???线程执行时,先把变量从主内存读取到线程自己的本地内存空间,然后再对该变量进行操作

对该变量操作完后,在某个时间再把变量刷新回主内存

当多个线程之间需要根据某个条件确定哪个线程可以执行时,要确保这个条件在 线程 之间是可见的。因此,可以用volatile修饰。

volatile关键字的非原子性(所谓原子性,就是某系列的操作步骤要么全部执行,要么都不执行。)

volatile关键字修饰的变量不会被指令重排序优化

volatile轻量级,只能修饰变量。synchronized重量级,还可修饰方法

volatile只能保证数据的可见性,不能用来同步,因为多个线程并发访问volatile修饰的变量不会阻塞。

synchronized不仅保证可见性,而且还保证原子性,因为,只有获得了锁的线程才能进入临界区,从而保证临界区中的所有语句都全部执行。多个线程争抢synchronized锁对象时,会出现阻塞。

6. 重载与重写(http://blog.csdn.net/linzhaojie525/article/details/55213010 )

重写方法的规则:

参数列表必须完全与被重写的方法相同,否则不能称其为重写而是重载。

返回的类型必须一直与被重写的方法的返回类型相同,否则不能称其为重写而是重载。

访问修饰符的限制一定要大于被重写方法的访问修饰符(public>protected>default>private)

重写方法一定不能抛出新的检查异常或者比被重写方法申明更加宽泛的检查型异常。例如:父类的一个方法申明了一个检查异常IOException,在重写这个方法是就不能抛出Exception,只能抛出IOException的子类异常,可以抛出非检查异常。

而重载的规则:

必须具有不同的参数列表;

可以有不同的返回类型,只要参数列表不同就可以了;

可以有不同的访问修饰符;

可以抛出不同的异常;

7. 降低Java垃圾回收开销的方法(http://www.importnew.com/20656.html )

预测集合的容量

直接处理数据流

使用不可变对象

小心字符串的拼接

使用特定的原生类集合

8. Runnable 与 Callable(https://www.cnblogs.com/frinder6/p/5507082.html )

相同点:

两者都是接口;(废话)

两者都可用来编写多线程程序;

两者都需要调用Thread.start()启动线程;

不同点:

两者最大的不同点是:实现Callable接口的任务线程能返回执行结果;而实现Runnable接口的任务线程不能返回结果;

Callable接口的call()方法允许抛出异常;而Runnable接口的run()方法的异常只能在内部消化,不能继续上抛;

9. Java 内存溢出(java.lang.OutOfMemoryError)(http://outofmemory.cn/c/java-outOfMemoryError )

导致OutOfMemoryError异常的常见原因有以下几种:

内存中加载的数据量过于庞大,如一次从数据库取出过多数据;

集合类中有对对象的引用,使用完后未清空,使得JVM不能回收;

代码中存在死循环或循环产生过多重复的对象实体;

使用的第三方软件中的BUG;

启动参数内存值设定的过小;

此错误常见的错误提示:

tomcat:java.lang.OutOfMemoryError:

PermGen space

tomcat:java.lang.OutOfMemoryError:

Java heap space

weblogic:Root

cause of ServletException java.lang.OutOfMemoryError

resin:java.lang.OutOfMemoryError

java:java.lang.OutOfMemoryError

10. find grep组合使用\ (http://blog.csdn.net/cupidove/article/details/8767450)

查找所有".h"文件

find/PATH -name "*.h"

查找所有".h"文件中的含有"helloworld"字符串的文件

find /PATH-name "*.h" -exec grep -in "helloworld" {} \;

find /PATH -name "*.h" | xargs grep -in "helloworld"

查找所有".h"和".c"文件中的含有"helloworld"字符串的文件

find /PATH/( -name "*.h" -or -name "*.c" /) -exec grep -in

"helloworld" {} \;

11. shell 中$0,$1,$2的含义(http://blog.csdn.net/qq_30137611/article/details/77092524)

简单来说 $0 就是你写的shell脚本本身的名字,$1 是你给你写的shell脚本传的第一个参数,$2 是你给你写的shell脚本传的第二个参数

12. HashMap 与HashTable的区别(http://www.androidchina.net/1802.html )

HashMap是非synchronized,可以接受key与value值为空,HashTable不行

HashMap是非synchronized,HashTable是synchronized。HashTable是线程安全的,多个线程可以共享一个HashTable。而如果没有正确同步的话,多个线程是不能共享HashMap的。

HashMap的迭代器(Iterator)是fail-fast迭代器,而Hashtable的enumrator迭代器不是fail-fast。当线程改变了HashMap的结构时会抛出ConcurrentModificationException。但是迭代器本身remove()函数移除元素时不会抛出 异常。

HashTable是线程安全的也是synchronized,所以在单线程环境比HashMap要慢。如果,不需要同步,HashMap要好过HashTable。

HashMap不能保证随时间推移map元素次序不变。

13. AVL(平衡二叉树)

定义:AVL树是二叉树,其各个节点的左右子树的高度相差不超过1。

定义:数的高度可以看做是节点与最低的叶子节点的距离。跟节点的高度最大,而叶子节点的高度为0,一个不存在的节点的高度定义为-1。

14. TCP/IP协议端口

端口号的范围从0到65535,比如用于浏览网页服务的80端口,用于FTP服务的21端口等。由于物理端口和逻辑端口数量较多,为了对端口进行区分,将每个端口进行了编号,这就是端口号。

15. UDP分片

以太网的数据帧必须要在46-1500之间,所以1500字节被称为最大传输单元MTU。当UDP的数据报大于1500时发送方的IP就要分片,

你可能感兴趣的:(cvte 2018 春季实习生招聘 Android 在线测评考点节选)