写点什么

成功获得字节跳动月薪 20+ 的 Android 岗 offer,看看面试都问了些什么?

用户头像
Android架构
关注
发布于: 9 小时前

2.自定义 Handler 时如何避免内存泄漏

一般非静态内部类持有外部类的引用的情况下,造成外部类在使用完成后不能被系统回收内存,从而造成内存泄漏。为了避免这个问题,我们可以自定义的 Handler 声明为静态内部类形式,然后通过弱引用的方式,让 Handler 持有外部类的引用,从而可避免内存泄漏问题。


以下是代码实现


private WeakReference<MainActivity> activityWeakReference;private MyHandler myHandler;


static class MyHandler extends Handler {private MainActivity activity;


MyHandler(WeakReference<MainActivity> ref) {this.activity = ref.get();}


@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);switch (msg.what) {case 1://需要做判空操作 if (activity != null) {activity.mTextView.setText("new Value");}break;default:Log.i(TAG, "handleMessage: default ");break;}


@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//在 onCreate 中初始化 activityWeakReference = new WeakReference<MainActivity>(this);myHandler = new MyHandler(activityWeakReference);


myHandler.sendEmptyMessage(1);mTextView = (TextView) findViewById(R.id.tv_test);}


参考博文:http://blog.csdn.net/ucxiii/article/details/50972747

3.Android IPC:Binder 原理

1.在 Activity 和 Service 进行通讯的时候,用到了 Binder。o1.当属于同个进程我们可以继承 Binder 然后在 Activity 中对 Service 进行操作 o2.当不属于同个进程,那么要用到 AIDL 让系统给我们创建一个 Binder,然后在 Activity 中对远端的 Service 进行操作。2.系统给我们生成的 Binder:o1.Stub 类中有:接口方法的 id,有该 Binder 的标识,有 asInterface(IBinder)(让我们在 Activity 中获取实现了 Binder 的接口,接口的实现在 Service 里,同进程时候返回 Stub 否则返回 Proxy),有 onTransact()这个方法是在不同进程的时候让 Proxy 在 Activity 进行远端调用实现 Activity 操作 Serviceo2.Proxy 类是代理,在 Activity 端,其中有:IBinder mRemote(这就是远端的 Binder),两个接口的实现方法不过是代理最终还是要在远端的 onTransact()中进行实际操作。3.哪一端的 Binder 是副本,该端就可以被另一端进行操作,因为 Binder 本体在定义的时候可以操作本端的东西。所以可以在 Activity 端传入本端的 Binder,让 Service 端对其进行操作称为 Listener,可以用 RemoteCallbackList 这个容器来装 Listener,防止 Listener 因为经历过序列化而产生的问题。4.当 Activity 端向远端进行调用的时候,当前线程会挂起,当方法处理完毕才会唤醒。5.如果一个 AIDL 就用一个 Service 太奢侈,所以可以使用 Binder 池的方式,建立一个 AIDL 其中的方法是返回 IBinder,然后根据方法中传入的参数返回具体的 AIDL。6.IPC 的方式有:Bundle(在 Intent 启动的时候传入,不过是一次性的),文件共享(对于 SharedPreference 是特例,因为其在内存中会有缓存),使用 Messenger(其底层用的也是 AIDL,同理要操作哪端,就在哪端定义 Messenger),AIDL,ContentProvider(在本进程中继承实现一个 ContentProvider,在增删改查方法中调用本进程的 SQLite,在其他进程中查询),Socket

4.描述一次跨进程通讯

1.client、proxy、serviceManager、BinderDriver、impl、service2.client 发起一个请求 service 信息的 Binder 请求到 BinderDriver 中,serviceManager 发现 BinderDiriver 中有自己的请求 然后将 clinet 请求的 service 的数据返回给 client 这样完成了一次 Binder 通讯 3.clinet 获取的 service 信息就是该 service 的 proxy,此时调用 proxy 的方法,proxy 将请求发送到 BinderDriver 中,此时 service 的 Binder 线程池循环发现有自己的请求,然后用 impl 就处理这个请求最后返回,这样完成了第二次 Binder 通讯 4.中间 client 可挂起,也可以不挂起,有一个关键字 oneway 可以解决这个

二、算法题

1.lc 里最长上升子序列的变形题。

2.实现输入英文单词联想的功能

3.矩阵旋转,要求空间复杂度 O(1)

4.无序的数组的中位数。要求时间复杂度尽可能的小

#三、计算机网络

1.tcp 怎么保证数据包有序

  1. 主机每次发送数据时,TCP 就给每个数据包分配一个序列号并且在一个特定的时间内等待接收主机对分配的这个序列号进行确认,

  2. 如果发送主机在一个特定时间内没有收到接收主机的确认,则发送主机会重传此数据包。

  3. 接收主机利用序列号对接收的数据进行确认,以便检测对方发送的数据是否有丢失或者乱序等,

  4. 接收主机一旦收到已经顺序化的数据,它就将这些数据按正确的顺序重组成数据流并传递到高层进行处理。

2.tcp 和 udp 的异同

TCP 是面向流的可靠数据传输连接 UDP 是面向数据包的不可靠无连接

3.tcp 怎么保证可靠性

差错检验机制,反馈机制,重传机制,引入序号,滑动窗口协议,选择重传

4.tcp 中 拥塞避免 和 流量控制 机制

拥塞避免和流量控制这两种机制很像,但是流量控制是由接收方的接受能力也就是接收窗口所决定的,如果接收窗口够大,以动态调整发送窗口的大小调整发送速度拥塞避免主要由网络情况所限制,网络情况良好,则加大发送速率,网络状态差(冗余 ACK 和丢包)则降低发送速率(慢启动,拥塞控制,快恢复,快重传)RENO,BBR

5.tcp 四次挥手的详细解释

tcp 四次挥手其实可以分为两个阶段第一:客户端至服务器的半双工连接关闭客户端向服务器发送 FIN 信号,进入 FIN_WAIT1 的状态,等待服务器的 ACK 信号?收到服务器的 ACK 后,进入 FIN_WAIT2 第二:服务器至客户端的半双工连接关闭客户端收到服务器发来的 FIN 后,发送 ACK,并进入 TIME_WAIT,等待 2msl,若无异常,则客户端认为连接成功关闭服务器收到客户端发来的 ACK 后,关闭连接


四次挥手之后为什么还要等待 2msl


MSL 是报文最大生存时间 1 是因为有可能客户端发往服务器的 ACK 丢失,服务器并不知道客户端已经确认关闭,这时候客户端的关闭会导致服务器端无法正常关闭 2 是为了保证连接中的报文都已经传递。假如短时间关闭又重新实现一个 TCP 还连到了同个端口上,旧连接中尚未消失的数据就会被认为是新连接的数据。


浏览器从输入网址到显示出网页的全过程


1.输入网址或者 ip。2.如果输入的是网址,首先要查找域名的 ip 地址第一步会在浏览器缓存中查找,如果没有,转至查询系统缓存,如果还是没有,发送请求给路由器,路由器首先会在自身的缓存中查找,如果还是没有,向 ips 发出请求,查询 ips 中的 dns 缓存,如果还是没有递归向上查询直至根服务器。.浏览器与 ip 机器之间建立 TCP 连接(三次握手)(HTTP)或者在 TCP 上


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


进一步建立 SSL/TLS 连接(HTTPS)接下来就是发送 HTTP 报文啥的了 GET,POST,DELETE,PUT。


滑动窗口机制的原理和理解


GBN 协议,回退 N 步协议,这是对停等协议的改进,因为停等协议的传输效率非常低下。每次可发送的数据为 N,基数为 base,小于 base 的数据已经发送并且确认,base 是最小的已发送未确认的报文序号。在接收端同样也有一个接收窗口,(解释)GBN 采用的是累计确认方式,这时候说一下选择重传机制。再说一下 TCP 中既不是 GBN 也不是 SR,而是 GBN 和 SR 的综合体。N 的大小必须报文序列编号的一半,否则接收端对报文的确认可能发生混淆


Https 原理和实现


cookie 和 session 的区别是什么


由于 HTTP 协议是无状态的协议,所以服务端需要记录用户的状态时,就需要用某种机制来识具体的用户 cookie 存在本地的上的 session 是存在服务器上的通俗讲,Cookie 是访问某些网站以后在本地存储的一些网站相关的信息,下次再访问的时候减少一些步骤。另外一个更准确的<u style="text-decoration: none; border-bottom: 1px dashed grey;">说法</u>是:Cookies 是服务器在本地机器上存储的小段文本并随每一个请求发送至同一个服务器,是一种在客户端保持状态的方案。Session 是存在服务器的一种用来存放用户数据的类 HashTable 结构。二者都用来保持用户的状态,cookie 可更改,对服务器来说并不安全,服务器常见做法有这两种 1.把 session 加密后放入浏览器的 cookie 中,浏览器重连后将加密的 session 发给服务器 2.cookie 中存储着 session 的 id,浏览器重连时只需要发送 session_id'即可

四、操作系统

进程和线程的区别


进程就是包换上下文切换的程序执行时间总和?=?CPU 加载上下文+CPU 执行+CPU 保存上下文


线程是什么呢?


进程的颗粒度太大,每次都要有上下的调入,保存,调出。如果我们把进程比喻为一个运行在电脑上的软件,那么一个软件的执行不可能是一条逻辑执行的,必定有多个分支和多个程序段,就好比要实现程序 A,实际分成 a,b,c 等多个块组合而成。那么这里具体的执行就可能变成:程序 A 得到 CPU =》CPU 加载上下文,开始执行程序 A 的 a 小段,然后执行 A 的 b 小段,然后再执行 A 的 c 小段,最后 CPU 保存 A 的上下文。这里 a,b,c 的执行是共享了 A 的上下文,CPU 在执行的时候没有进行上下文切换的。这**里的 a,b,c 就是线程,也就是说线程是共享了进程的上下文环境,的更为细小的 CPU 时间段。

五、设计模式

简述一个设计模式的概念,并简要谈谈 framework 层哪些地方用到了什么设计模式单例模式:单例模式是一种对象创建模式,它用于产生一个对象的具体实例,它可以确保系统中一个类只产生一个实例。


适配器模式:将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper)


装饰模式:动态地给一个对象增加一些额外的职责,就增加对象功能来说,装饰模式比生成子类实现更为灵活。装饰模式是一种对象结构型模式。


使用场景:


1.在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。2.当不能采用继承的方式对系统进行扩展或者采用继承不利于系统扩展和维护时可以使用装饰模式。


优点:


1.对于扩展一个对象的功能,装饰模式比继承更加灵活,不会导致类的个数急剧增加。2.可以通过一种动态地方式来扩展一个对象的功能。3.可以对一个对象进行多次装饰,通过使用不同的具体装饰类以及这些装饰类的排列组合。


实际运用:


Android 中 Context 类的实现


外观模式: 主要目的在于让外部减少与子系统内部多个模块的交互,从而让外部能够更简单得使用子系统。它负责把客户端的请求转发给子系统内部的各个模块进行处理。


使用场景:


1.当你要为一个复杂的子系统提供一个简单的接口时 2.客户程序与抽象类的实现部分之前存在着很大的依赖性 3.当你需要构建一个层次结构的子系统时


组合模式:将对象以树形结构组织起来,以达成”部分--整体”的层次结构,使得客户端对单个对象和组合对象的使用具有一致性。


使用场景:


1.需要表示一个对象整体或部分 层次 2.让客户端能够忽略不同对象层次的变化


优点:


1.高层模块调用简单 2.节点自由增加


模板模式:是通过一个算法骨架,而将算法中的步骤延迟到子类,这样子类就可以复写这些步骤的实现来实现特定的算法。它的使用场景:


1.多个子类有公有的方法,并且逻辑基本相同 2.重要、复杂的算法,可以把核心算法设计为模板方法 3.重构时,模板方法模式是一个经常使用的模式


观察者模式:定义对象之间一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。其使用场景:


1.一个抽象模型有两个方面,其中一个方面依赖于另一个方面 2.一个对象的改变将导致一个或多个其他对象也 发生改变 3.需要在 系统中创建一个 触发链


具体应用:


比如回调模式中,实现了抽象类/接口的实例实现了父类提供的抽象方法后,将该方法交还给父类来处理


Listview 中的 notifyDataSetChanged

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
成功获得字节跳动月薪20+的Android岗offer,看看面试都问了些什么?