2022-04-06

这是,android初级,中级面试题大纲

  https://juejin.im/post/6844903792796303374#heading-27

  https://juejin.cn/post/6844903891625050119     

1 Jvm内存模型  黑马程序员JVM完整教程,全网超高评价,全程干货不拖沓  https://www.bilibili.com/video/BV1yE411Z7AP?p=25

                      深入理解Java虚拟机(JVM性能调优+内存模型+虚拟机原理) https://www.bilibili.com/video/BV1BW411R7QK?p=3&spm_id_from=pageDriver

                      程序计数器:选择里面的字节码去解释计算机识别的机器码,一条条的去取,然后出来一堆汇编语言的东西

2  GC Root      【java】10分钟,了解GC过程 https://www.bilibili.com/video/BV1dt411u7wi


3  HashMap    初步 HashMap集合介绍+面试题讲解  https://www.bilibili.com/video/BV1FE411t7M7?from=search&seid=7949726734994154435&spm_id_from=333.337.0.0

                                                                              https://www.bilibili.com/video/BV1kJ411C7hC?from=search&seid=7720528671226300856&spm_id_from=333.337.0.0

                      面试ConcurrentHashMap终结篇      https://www.bilibili.com/video/BV17i4y1x71z?from=search&seid=17060063590610714631&spm_id_from=333.337.0.0

5  多线程(Handler)        全面理解Java内存模型(JMM)及volatile关键字  https://blog.csdn.net/javazejian/article/details/72772461

                      多线程安全问题的条件:1、存在共享资源  2、多个线程同时访问共享资源

                      1、ThreadLocal的作用:使每个线程持有变量的私有副本,起到线程隔离的目的

                      2、其实是一种空间换时间的策略,避免了多线程访问不安全的问题

                      3、ThreadLocal从名字看是线程本地变量,从代码来看就是一个普通的类,它有个内部类ThreadLocalMap,以thread为key,可以得到每个线程自己的ThreadLocalMap,ThreadLocalMap里面维护了一个Entry弱引用数组,再通过ThreadLocalMap访问自己的变量

                      4、ThreadLocal容易造成内存泄漏,要注意做好资源释放


6  volatile和JMM Java高并发编程精髓Java内存模型JMM详解全集  https://www.bilibili.com/video/BV1Et411n7Ro?p=3

                          线程对volatile关键字修饰的资源访问的时候,总是保持最高的积极性去访问和同步该数据,而不是使用缓存。

                          1、可见性:强制CPU读取主内存  https://www.bilibili.com/video/BV1Et411n7Ro?p=3

                              volatile可见性的实现就是借助了CPU的lock指令,通过在写volatile的机器指令前加上lock前缀,使写volatile具有以下两个原则:

                              写volatile时处理器会将缓存写回到主内存。

                              一个处理器的缓存写回到内存会导致其他处理器的缓存失效。

                          2、有序性:禁止指令重排  https://www.csdn.net/tags/NtjaQgzsNTEyNTMtYmxvZwO0O0OO0O0O.html

                              volatile有序性的保证就是通过禁止指令重排序来实现的。

                          3、不能保证原子性

                              原子性指的是一个操作是不可中断的,即使是在多线程环境下,一个操作一旦开始就不会被其他线程影响。比如对于一个静态变量int x,

                              两条线程同时对他赋值,线程A赋值为1,而线程B赋值为2,不管线程如何运行,最终x的值要么是1,要么是2,

                              线程A和线程B间的操作是没有干扰的,这就是原子性操作,不可被中断的特点。

                    6.1 https://blog.csdn.net/qq_32625839/article/details/80909441

                        字节码文件(Java中是16进制文件)是经过编译器预处理过的一种文件,是Java的执行文件存在形式,它本身是二进制文件,但是不可以被系统直接执行,而是需要虚拟机解释执行。

                        全面理解Java内存模型(JMM)及volatile关键字  https://blog.csdn.net/javazejian/article/details/72772461


                    parcelable和serializable区别  Serializable是I/O操作,写到文件里面去的。    Parcelable是写到主存里去的。本质就不一样

7 自定义流view  式布局  https://www.cnblogs.com/lordjinsdream/p/14129412.html 

                          int selfWidth = MeasureSpec.getSize(widthMeasureSpec);  //父view给我的宽度

                          int selfHeight = MeasureSpec.getSize(heightMeasureSpec); //父view给我的高度

                          View childView = getChildAt(i);

                          // 获取子view的layoutParams,通过layoutParams可得到子view的宽高具体值或者MATCH_PARENT还是WRAP_CONTENT

                          LayoutParams childLP = childView.getLayoutParams();

                          int childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec, paddingLeft + paddingRight, childLP.width);

                          int childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec, paddingTop + paddingBottom, childLP.height);

                          // 通过子view的measureSpec度量子view

                          childView.measure(childWidthMeasureSpec, childHeightMeasureSpec);

                          //获取子view的度量宽高

                          int childMeasureWidth = childView.getMeasuredWidth();

                          int childMeasureHeight = childView.getMeasuredHeight();

                          int widthMode = MeasureSpec.getMode(widthMeasureSpec);

                        int heightMode = MeasureSpec.getMode(heightMeasureSpec);

                        // 如果父view的MeasureSpec的mode是EXACTLY表示宽度是确切的,则selfWidth为最终宽度,否则为

                        int flowLayoutWidth = (widthMode == MeasureSpec.EXACTLY) ? selfWidth : flowLayoutNeedWidth;

                        int flowLayoutHeight = (heightMode == MeasureSpec.EXACTLY) ? selfHeight : flowLayoutNeedHeight;

                        // 保存记录

                        setMeasuredDimension(flowLayoutWidth, flowLayoutHeight);

                        Android中View测量之MeasureSpec https://www.jianshu.com/p/2fffa71ac5ba   

                        UI不好,工作难保!自定义View是Android程序员的分水岭?https://www.bilibili.com/video/BV1Wh411f7ud?p=4 

                        Android事件分发机制详解:史上最全面、最易懂  https://www.jianshu.com/p/38015afcdb58


8 项目相关  难点 Android面试官敢问你项目难点?教你分分钟忽悠瘸他! https://www.bilibili.com/video/BV1AM4y1T7GW?spm_id_from=333.337.search-card.all.click

                Eventbus  深入解析面试必问 EventBus  https://www.bilibili.com/video/BV15e411s7jX?spm_id_from=333.999.0.0

                recyckerview 阿里P7岗面试关于RecyclerView的连环炮 https://www.bilibili.com/video/BV1Fi4y1x7p5?spm_id_from=333.337.search-card.all.click

                                      recycleview与listview  总览  https://www.jianshu.com/p/daaaab581c2d

                                      深入  https://blog.csdn.net/import_sadaharu/article/details/81323801 

                                      用法  https://www.jianshu.com/p/da23fe946ed1   


                  okhttp 【底层原理学习】|OkHttp原理详解(全) https://www.bilibili.com/video/BV12Q4y1d7uD?p=6


                  Glide 三级缓存 ( https://www.jianshu.com/p/171793326b94?ivk_sa=1024320u )

                          a)由此可见,通常情况下 Glide 是有两级缓存的,弱引用缓存和内存缓存,正在使用的图片保存在弱引用的 HashMap 中,使用过但现在不使用的图片保存在 LruCache 的 LinkedHashMap 中,两者之间存在交互的,

                              如果现在请求的图片存在于 LreCache 中,Glide 会将这张图片从 LruCache 中移除并保存在弱引用缓存 activeResources 中,如果正在使用的图片现在不使用了(图片的引用计数为0)

                              Glide 又会将这张图片从 activeResources 中移除并存入 LruCache 中。

                              Glide 获取一张图片时,首先会从弱引用缓存中获取,没有则从内存缓存 LruCache 中获取,如果有磁盘缓存,接着去磁盘中获取,最后才是通过网络获取。

                        b) 到此为此就介绍完了 Glide 的两种缓存的读取和写入原理,需要注意的是内存缓存不仅是 LruCache 还提供了一种弱引用缓存,用于缓存正在使用的图片资源,

                              由于是弱引用的缓存当系统发起 GC 时就会被回收掉,有效避免了内存较低时系统开启 GC 回收部分内存时可能发生的内存泄漏问题,以及由于图片过大导致内存不足时可能引发的内存溢出问题。

                              假设我们在一开始设置了 Glide 支持磁盘缓存,且原图和编码后(即压缩或转换)的图片都要缓存;

                              缓存读取顺序:

                              弱引用缓存 -> LruCache -> DiskLruCache

                              缓存写入顺序:

                              DiskLruCache 缓存原图 -> 弱引用缓存 -> LruCache -> DiskLruCache 缓存编码后的图片

                              注意:

                              弱引用缓存和 LruCache 之间存在缓存的转换关系,图片从正在使用状态转为不使用状态,Glide 将图片从弱引用缓存移除然后缓存到 LruCache 中,

                              假如 LruCache 中的某张图片现在需要使用,则图片从 LruCache 中移除缓存到弱引用缓存中,弱引用缓存中保存的是正在使用的图片。


                              Glide图片加载框架源码、生命周期分析、手写一个Glide图片加载  https://www.bilibili.com/video/BV1EA411371L?p=10

                              Android 【手撕Glide】--Glide是如何关联生命周期的?  https://www.jianshu.com/p/79dd4953ec25 

                              小结

                                    1、创建一个无UI的Fragment,具体来说是SupportRequestManagerFragment/RequestManagerFragment,并绑定到当前Activity,这样Fragment就可以感知Activity的生命周期;

                                    2、在创建Fragment时,初始化Lifecycle、LifecycleListener,并且在生命周期的onStart() 、onStop()、 onDestroy()中调用相关方法;

                                    3、在创建RequestManager时传入Lifecycle 对象,并且LifecycleListener实现了LifecycleListener接口;

                                    4、这样当生命周期变化的时候,就能通过接口回调去通知RequestManager处理请求。


                    socket传输不同的数据类型  https://blog.csdn.net/hongmofang10/article/details/90721800

                    大长图加载方案 https://www.jianshu.com/p/2b17fc020261  Bitmap的高效加载主要还是依赖于对:BitmapFactory.Options的属性设置,然后,就是配合解码器BitmapRegionDecoder可以分块加载图片,分块的区域是由Rect决定的。         

9  Android  手撕Framework系列 https://blog.csdn.net/shaoenxiao/article/details/87088982


                  加电自检—> Boot(ROM)芯片代码加载引导程序(Bootloader)—>引导程序(Bootloader)加载os—>

                  Linux内核启动(设置缓存,加载驱动,计划列表,被保护存储,守护进程)—>启动init进程(system/core/init/init.cpp main函数入口)

                  系统启动过程    https://www.bilibili.com/video/BV1cP4y1Y7sX?p=2

                  Android的开机启动流程概述 https://www.jianshu.com/p/45cf56172d22

                  Android系统启动流程 https://blog.csdn.net/shaoenxiao/article/details/87088982

                  Android源码学习之六——ActivityManager框架解析 https://blog.csdn.net/caowenbin/article/details/6036726

                  Java代理(Proxy)模式  https://www.jianshu.com/p/8ccdbe00ff06

                  安卓app应用启动流程简析 https://baijiahao.baidu.com/s?id=1728062966946873234&wfr=spider&for=pc

                  Android -APP启动流程  https://www.jianshu.com/p/8c2038cfb2ab               

                  Android——APP启动流程&&Android开机流程  https://blog.csdn.net/ly0724ok/article/details/117653431

                  https://blog.csdn.net/maxleng/article/details/5508372

                  https://www.cnblogs.com/bastard/archive/2012/08/28/2660389.html

                  https://blog.csdn.net/wangzaieee/article/details/84774298

                  UML类图  https://www.jianshu.com/p/57620b762160


10  Android性能优化总结  https://www.jianshu.com/p/8599a24bee85

你可能感兴趣的:(2022-04-06)