Android面试主题整理合集(三)

3.MVVM通过数据驱动来自动完成的,数据变化后会自动更新UI,UI的改变也能自动反馈到数据层 Mvvm和Mvp比较相似,不同的是Mvvm中可以用DataBinding或者LiveData动态绑定数据,进一步降低耦合

  • Activity负责UI操作,ViewModel负责数据逻辑。两者通过LiveData进行关联。ViewModel返回LiveData实例和Activity绑定,ViewModel有变化时可以自动更新UI,Activity也可以通过ViewModel发起数据请求

  • 问题:

看起来MVVM很好地解决了MVC和MVP的不足,但是由于数据和视图的双向绑定,导致出现问题时不太好定位来源,有可能数据问题导致,也有可能业务逻辑中对视图属性的修改导致

Android面试主题整理合集(三)

Android面试主题整理合集(三)

以登录为例,登录时只需要拿着用户名和密码请求服务器即可

  • MVC中,需要先找到输入框,再从输入框中拿到用户名和密码,再进行登录操作

  • MVP中,通过Presenter拿到用户名和密码,进行登录。相当于通过引入了Presenter将M层和V层分离,降低耦合

  • MVVM中,用户在输入框输入完用户名和密码后,这种UI的变化直接同步到数据,直接登录

3.策略设计模式

========

适用场景: 某些业务中,某一个行为,会有多个实现类,并且当前业务只会选择一种实现类

4.Double Check Lock 实现单例

========================

public static TestInstance getInstance(){ //1

if (mInstance == null){ //2

synchronized (TestInstance.class){ //3

if (mInstance == null){ //4

mInstance = new TestInstance(); //5

}

}

}

return mInstance;

}

第一层判断主要是为了避免不必要的同步

第二层的判断则是为了在 null 的情况下创建实例。mInstance = new TestInstance(); 这个步骤,其实在jvm里面的执行分为三步:

1.在堆内存开辟内存空间;

2.初始化对象;

3.把对象指向堆内存空间;

由于在 JDK 1.5 以前 Java 编译器允许处理器乱序执行。不过在 JDK 1.5 之后,官方也发现了这个问题,故而具体化了 volatile ,即在 JDK 1.6 以后,只要定义为 private volatile static DaoManager3 sinstance ; 就可解决 DCL 失效问题

5.OkHttp中的责任链

=============

Android面试主题整理合集(三)

public interface Interceptor {

//每一层的拦截器接口,需要进行实现 Chain:串连拦截器的链

Response intercept(Chain chain) throws IOException;

//链主要有两个方法:拿到Request;通过Request拿到Response

interface Chain {

Request request();

Response proceed(Request request):Response throws IOException;//负责往下执行

}

}

public class RealInterceptorChain implements Interceptor.Chain {

final List interceptors;//节点的列表

final int index;//当前节点的index,通过index和interceptors就可以拿到所有节点

final Request request;//请求

public RealInterceptorChain(List interceptors, int index, Request request){

this.interceptors = interceptors;

this.index = index;

this.request = request;

}

@Override

public Request request() {

return request;

}

@Override

public Response proceed(Request request) throws IOException {

RealInterceptorChain next = new RealInterceptorChain(interceptors, index + 1, request);

//next传到当前节点,当前节点处理好request后就可以通过next执行proceed方法,将request传递到下一节点

Interceptor interceptor = interceptors.get(index);

Response response = interceptor.intercept(next);

return response;

}

}

拦截器

public class BridgeInterceptor implements Interceptor{

@Override

public Response intercept(Chain chain) throws IOException {

Log.e(“TAG”,“BridgeInterceptor”);

Request request = chain.request();

// 添加一些请求头

request.header(“Connection”,“keep-alive”);

// 做一些其他处理

if(request.requestBody()!=null){

RequestBody requestBody = request.requestBody();

request.header(“Content-Type”,requestBody.getContentType());

request.header(“Content-Length”,Long.toString(requestBody.getContentLength()));

}

Response response = chain.proceed(request);//这里的chain就是传进来的next,next的index已经加1

return response;

}

}

RealCall中excute()方法

protected void execute() {

final Request request = orignalRequest;

try {

List interceptors = new ArrayList<>();

interceptors.add(new BridgeInterceptor());

interceptors.add(new CacheInterceptor());

interceptors.add(new CallServerInterceptor());

Interceptor.Chain chain = new RealInterceptorChain(interceptors,0,orignalRequest);

Response response = chain.proceed(request);

callback.onResponse(RealCall.this,response);

} catch (IOException e) {

callback.onFailure(RealCall.this,e);

}

}


算法


1.反转单链表

=======

class Node{

private int data;

private Node next;

public Node(int data,Node next){

this.data=data;

this.next=next;

}

}

Node node4 = new Node(4, null);

Node node3 = new Node(3, node4);

Node node2 = new Node(2, node3);

Node node1 = new Node(1, node2);

Node pHead = node1;//头结点

这组链表从1到4排序,要求反转后4到1

public static Node reverseList(Node pHead) {

Node pReversedHead = null; //反转过后的单链表存储头结点

Node pNode = pHead; //当前节点

Node pPrev = null; //前一结点

while (pNode != null) {

//1.记录next,下一步:更新当前节点的上一节点和本身。最后移动一位

Node pNext = pNode.next;

if (pNext == null) {

//到了尾节点

pReversedHead = pNode;

}

pNode.next = pPrev;

pPrev = pNode;

pNode = pNext;

}

return pReversedHead;

}

//递归方式反转(node1->node2->node3->node4->node5)

public static ListNode reverseR(Node head){

//空链表和一个结点的链表无需反转

if(head == null || head.next == null){

return head;

}

//递归到node4(head)时回溯时,reverseR(node4.next)直接返回node5

Node res = reverseR(head.next);

//递归回溯时,此时head指向node4,将node4的next(node5)的next指向node4(head)

head.next.next = head;

//将node4.next指向null

head.next = null;

return res;

}

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助

因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
1715494132667)]

[外链图片转存中…(img-94ysUnKK-1715494132669)]

[外链图片转存中…(img-bqc2V1Nh-1715494132671)]

[外链图片转存中…(img-KmXYP1sm-1715494132672)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值