春招笔记(一)腾讯

1.synchronize用法

synchronized 方法:通过在方法声明中加入 synchronized关键字来声明 synchronized 方法。如:

public synchronized void accessVal(int newVal);

synchronized 方法控制对类成员变量的访问:每个类实例对应一把锁,每个 synchronized 方法都必须获得调用该方法的类实例的锁方能执行,否则所属线程阻塞,方法一旦执行,就独占该锁,直到从该方法返回时才将锁释放,此后被阻塞的线程方能获得该锁,重新进入可执行状态。这种机制确保了同一时刻对于每一个类实例,其所有声明为 synchronized 的成员函数中至多只有一个处于可执行状态(因为至多只有一个能够获得该类实例对应的锁),从而有效避免了类成员变量的访问冲突(只要所有可能访问类成员变量的方法均被声明为 synchronized)。

synchronized 块:通过 synchronized关键字来声明synchronized 块。语法如下:

synchronized(syncObject) {

//允许访问控制的代码

}

synchronized 块是这样一个代码块,其中的代码必须获得对象 syncObject (如前所述,可以是类实例或类)的锁方能执行,具体机制同前所述。由于可以针对任意代码块,且可任意指定上锁的对象,故灵活性较高。


2.volatile用法

volatile是Java提供的一种轻量级的同步机制,同synchronized相比,volatile更轻量级,在访问volatile变量时不会执行加锁操作,因此也就不会使执行的线程阻塞。

volatile缺点

volatile不能保证原子性,volatile可以配合synchronized保证原子性。

原子性:原子性是指一个操作是不可中断的,要么全部执行成功要么全部执行失败,有着“同生共死”的感觉。及时在多个线程一起执行的时候,一个操作一旦开始,就不会被其他线程所干扰。

https://www.jianshu.com/p/844aa1b8ab22

3.动态权限适配方案,权限组的概念

将权限分组,按组分配下去。一次性分配就分配一个权限组。权限组的意思就是一组权限的集合。

动态权限管理就是这样, 一方面让用户更加容易的控制自己的隐私, 一方面需要重新适配应用权限. 

Android系统包含默认的授权提示框, 但是我们仍需要设置自己的页面. 原因是系统提供的授权框, 会有不再提示的选项. 如果用户选择, 则无法触发授权提示. 使用自定义的提示页面, 可以给予用户手动修改授权的指导.

https://www.jianshu.com/p/dbe4d37731e6

权限分类:

正常权限:不会直接给用户隐私权带来风险。如果您的应用在其清单中列出了正常权限,系统将会自动授予该权限。

危险权限:会授予应用访问用户机密数据的权限。如果您的应用在其清单中列出了危险权限,则用户必须明确批准您的应用使用这些权限。

4.网络请求缓存处理,okhttp如何处理网络缓存的

目的:缓存经常访问的一些数据,减少数据传输,从而减少带宽,减少支付的流量费。

解决的方法就是把重复请求的数据缓存在本地,并设置超时时间,在规定时间内,客户端不再向远程请求数据,而是直接从本地缓存中取数据。这样一来提高了响应速度,二来节省了网络带宽。

1.okhttp用CacheControl进行缓存的控制。

2.okhttp用拦截器添加Cache-Control消息头进行缓存定制

https://blog.csdn.net/briblue/article/details/52920531


5.okhttp

OkHttp不仅具有高效的请求效率, 并且提供了很多开箱即用的网络疑难杂症解决方案.

支持HTTP/2, HTTP/2通过使用多路复用技术在一个单独的TCP连接上支持并发, 通过在一个连接上一次性发送多个请求来发送或接收数据

如果HTTP/2不可用, 连接池复用技术也可以极大减少延时

支持GZIP, 可以压缩下载体积

响应缓存可以直接避免重复请求

会从很多常用的连接问题中自动恢复

如果您的服务器配置了多个IP地址, 当第一个IP连接失败的时候, OkHttp会自动尝试下一个IP

OkHttp还处理了代理服务器问题和SSL握手失败问题

6.图片加载库相关,bitmap如何处理大图,如一张30M的大图,如何预防OOM

Android的虚拟机是基于寄存器的Dalvik,它的最大堆大小一般是16M,有的机器为24M。因此我们所能利用的内存空间是有限的。如果我们的内存占用超过了一定的水平就会出现OutOfMemory的错误。

1.BitmapFactory提供了几种解码方式.根据你的图片数据来源选择最合适的解码方式

2.尽量不要使用setImageBitmap或setImageResource或BitmapFactory.decodeResource直接使用图片路径来设置一张大图,因为这些函数在完成decode后,最终都是通过java层的createBitmap来完成的,需要消耗更多内存。改用先通过BitmapFactory.decodeStream方法,创建出一个bitmap,再调用上述方法将其设为ImageView的 source。decodeStream最大的秘密在于其直接调用JNI>>nativeDecodeAsset()来完成decode,无需再使用java层的createBitmap,从而节省了java层的空间。

3.使用图片缓存技术

预估一下加载整张图片所需占用的内存。

为了加载这一张图片你所愿意提供多少内存。

用于展示这张图片的控件的实际大小。

当前设备的屏幕尺寸和分辨率。

应该去分析程序内存的使用情况,然后制定出一个合适的缓存空间大小


7.Fresco,Glide,Picasso

他们都是将图片外链解析成图片在App里展示的库,这三个库有各自的好与坏,要对比起看。 在体积上:Fresco > Glide > Picasso

Glide 的 with 方法不光接受 Context,还接受 Activity 和 Fragment

Glide 加载显示非常快,可以加载 GIF 动态图,而 Picasso 不能。

Picasso 比 Glide 体积小很多且图像质量比 Glide 高。

Picasso 所能实现的功能 Glide 都能做到,但体积比Glide小,图片质量高.如果是视频类应用,首选 Glide。

Fresco 中设计有一个叫做 Drawees 模块,它会在图片加载完成前显示占位图,加载成功后自动替换为目标图片。当图片不再显示在屏幕上时,它会及时地释放内存和空间占用。最大限度节省空间和 CPU 时间。

Fresco 在图片较多的应用中更能凸显其价值。

8.greenDAO 

greenDAO 是一款开源的面向 Android 的轻便、快捷的 ORM 框架,将 Java 对象映射到 SQLite 数据库中,我们操作数据库的时候,不在需要编写复杂的 SQL语句, 在性能方面,greenDAO 针对 Android 进行了高度优化, 最小的内存开销 、依赖体积小 同时还是支持数据库加密。


春招笔记(一)腾讯_第1张图片

greendao在插入,更新,读取操作上性能很好。

GreenDao 是支持加密的,可以安全的保存用户数据。

GreenDao  核心库小于100k ,所以我们并不会担心添加 GreenDao  后 APK 大小会变的是否庞大。

GreenDao  支持 protocol buffer(protobuf) 协议数据的直接存储,如果你通过 protobuf 协议与服务器交互,将不需要任何的映射。

greenDAO 会根据配置信息自动生成核心管理类以及 DAO 对象

DaoMaster:

使用 greenDAO 的入口点。DaoMaster 负责管理数据库对象(SQLiteDatabase)和 DAO 类(对象),我们可以通过它内部类 OpenHelper 和 DevOpenHelper SQLiteOpenHelper 创建不同模式的 SQLite 数据库。

DaoSession :

管理指定模式下的所有 DAO 对象,DaoSession提供了一些通用的持久性方法比如插入、负载、更新、更新和删除实体。

XxxDAO :

每个实体类 greenDAO  多会生成一个与之对应DAO对象,如:User 实体,则会生成一个一个UserDao 类

Entities

可持久化对象。通常, 实体对象代表一个数据库行使用标准 Java 属性(如一个POJO 或 JavaBean )。

9.进程保活

Android 进程拉活包括两个层面:

提供进程优先级,降低进程被杀死的概率

在进程被杀死后,进行拉活

如何提升进程优先级?

利用 Activity 提升权限

方案设计思想:监控手机锁屏解锁事件,在屏幕锁屏时启动1个像素的 Activity,在用户解锁时将 Activity 销毁掉。注意该 Activity 需设计成用户无感知。

利用 Notification 提升权限

方案设计思想:Android 中 Service 的优先级为4,通过 setForeground 接口可以将后台 Service 设置为前台 Service,使进程的优先级由4提升为2,从而使进程的优先级仅仅低于用户当前正在交互的进程,与可见进程优先级一致,使进程被杀死的概率大大降低。

进程死后拉活的方案?

1.利用系统广播拉活

方案设计思想:在发生特定系统事件时,系统会发出响应的广播,通过在 AndroidManifest 中“静态”注册对应的广播监听器,即可在发生响应事件时拉活。

2.利用第三方应用广播拉活

方案设计思想:该方案总的设计思想与接收系统广播类似,不同的是该方案为接收第三方 Top 应用广播。

通过反编译第三方 Top 应用,如:手机QQ、微信、支付宝、UC浏览器等,以及友盟、信鸽、个推等 SDK,找出它们外发的广播,在应用中进行监听,这样当这些应用发出广播时,就会将我们的应用拉活。

3. 利用系统Service机制拉活

方案设计思想:将 Service 设置为 START_STICKY,利用系统机制在 Service 挂掉后自动拉活:

4.利用Native进程拉活

利用 Linux 中的 fork 机制创建 Native 进程,在 Native 进程中监控主进程的存活,当主进程挂掉后,在 Native 进程中立即对主进程进行拉活。

5.利用 JobScheduler 机制拉活

方案设计思想:Android5.0 以后系统对 Native 进程等加强了管理,Native 拉活方式失效。系统在 Android5.0 以上版本提供了 JobScheduler 接口,系统会定时调用该进程以使应用进行一些逻辑操作。

其他解决方案:

利用系统通知管理权限进行拉活

利用辅助功能拉活,将应用加入厂商或管理软件白名单。


10.进程优先级

进程的重要性,划分5级:

前台进程 (Foreground process)

可见进程 (Visible process)

服务进程 (Service process)

后台进程 (Background process)

空进程 (Empty process)

前台进程的重要性最高,依次递减,空进程的重要性最低

11.Android 进程回收策略

Android 中对于内存的回收,主要依靠 Lowmemorykiller 来完成,是一种根据 OOM_ADJ 阈值级别触发相应力度的内存回收的机制。

比较容易被杀死的 Android 进程(OOM_ADJ>=4)

Lowmemorykiller 回收内存时会根据进程的级别优先杀死 OOM_ADJ 比较大的进程,对于优先级相同的进程则进一步受到进程所占内存和进程存活时间的影响

12.listview图片加载错乱的原理和解决方案

用了findViewWithTag()方法之后,图片就不会再出现乱序情况了呢?其实原因很简单,由于ListView中的ImageView控件都是重用的,移出屏幕的控件很快会被进入屏幕的图片重新利用起来,那么getView()方法就会再次得到执行,而在getView()方法中会为这个ImageView控件设置新的Tag,这样老的Tag就会被覆盖掉,于是这时再调用findVIewWithTag()方法并传入老的Tag,就只能得到null了,而我们判断只有ImageView不等于null的时候才会设置图片,这样图片乱序的问题也就不存在了。

13. https相关,如何验证证书的合法性,https中哪里用了对称加密,哪里用了非对称加密,对加密算法(如RSA)等是否有了解

HTTPS其实是有两部分组成:HTTP + SSL / TLS,也就是在HTTP上又加了一层处理加密信息的模块。服务端和客户端的信息传输都会通过TLS进行加密,所以传输的数据都是加密后的数据。

HTTPS协议的服务器必须要有一套数字证书,可以自己制作,也可以向组织申请。区别就是自己颁发的证书需要客户端验证通过,才可以继续访问,而使用受信任的公司申请的证书则不会弹出提示页面。这套证书其实就是一对公钥和私钥

公钥私钥理解

如果对公钥和私钥不太理解,可以想象成一把钥匙和一个锁头,只是全世界只有你一个人有这把钥匙,你可以把锁头给别人,别人可以用这个锁把重要的东西锁起来,然后发给你,因为只有你一个人有这把钥匙,所以只有你才能看到被这把锁锁起来的东西。

如何验证证书的合法性

证书其实就是公钥,只是包含了很多信息,如证书的颁发机构,过期时间等等。检查公钥里的颁发机构。

颁发证书的机构是否合法,证书中包含的网站地址是否与正在访问的地址一致

客户端的TLS来完成的证书的解析与验证,首先会验证公钥是否有效,比如颁发机构,过期时间等等,如果发现异常,则会弹出一个警告框,提示证书存在问题。如果证书没有问题,那么就生成一个随即值。然后用证书对该随机值进行加密。就好像上面说的,把随机值用锁头锁起来,这样除非有钥匙,不然看不到被锁住的内容。

服务端用私钥解密后,得到了客户端传过来的随机值(私钥),然后把内容通过该值进行对称加密。所谓对称加密就是,将信息和私钥通过某种算法混合在一起,这样除非知道私钥,不然无法获取内容,而正好客户端和服务端都知道这个私钥,所以只要加密算法够彪悍,私钥够复杂,数据就够安全。

哪里用了对称加密,哪里用了非对称加密?

一般的HTTPS连接只在第一次握手时使用非对称加密,通过握手交换对称加密密钥,在之后的通信走对称加密。

原因在于寻找大素数、大数计算、数据分割需要耗费很多的CPU周期

对加密算法(如RSA)等是否有了解?

你可能感兴趣的:(春招笔记(一)腾讯)