android最新面试题汇总

在已有win10系统下安装Ubuntu,最后出现执行‘grub-install/dev/nvme0n1p5‘失败的致命错误的解决方案 本人电脑型号戴尔灵越,两个SSD512G固态硬盘,c盘为系统盘. Ubuntu版本为20.04LTS,在官网下载https://ubuntu.com/download/desktop/thank-you?version=20.04.3&architecture=amd64 系统盘制作工具为Rufus-3.15http://rufus.ie/zh/ 安装过程网上很多,在这里就不赘述了. 其他安装过程都很顺利,直至安装最后出现这个 本来安装了到最后还以为成了,结果又不行...... 后. 阅读详情

不知不觉金三银四已过去,随后看到很多朋友在博客,简书等发布自己的面试总结,其中有很多知识点都是模糊的,因为项目中很少用到,或者是用到了没有深入去研究。其实在过去,我常常有这种心理,觉得项目中不常用或者几乎不用普及的大可不必去研究。完全是为了开发而开发。久而久之我发现我所做的项目或多或少会出现一些bug,而这些bug有时候会困扰我几个小时,甚至大半天。后面当我去研究那些我认为项目中很少用,或者几乎用不到的知识点后,才发现自己所犯的错,而且你会很清楚的明白错误原由,以及解决办法。我之所以说这些就想说明要多去研究知识点,不要为了开发而开发。对一些不理解的api要学会看源码。学会读源码。好了,言归正算。下面我就汇总下我们平常面试中常见的问题(我认为)及自己的答题。

(一)关于四大组件的一些知识:

1.正常情况activity生命周期是什么?

onCreate()-onStart-onResume-onPause-onStop-onDestory

2.两个activity分别是AB,在A中启动B,然后返回A,请问各自的生命周期?

当A中启动B时:A:onPause()进入暂停状态,当启动B时:onCreate()-onStart-onResume后B可见,A再执行onStop()停止

返回A时B的生命周期:先onPause()进入暂停状态,当返回A时:A生命周期:onReStart()-onStart()-onResume()后A重新可见。B再执行onStop()-onDestory()销毁界面

总结:当从一个activity到另一个acitvity的时候,第一个activity会先进入一个暂停状态,只有当另外一个activity可见(调用onResume())的时候第一个acitvity才会停止或者销毁

3.activity启动模式有几种并简单说明下各自的应用场景

(1)standard:默认模式,即正常启动activity情况下

(2)singleTop:栈顶模式,即当activity处于栈顶的时候不重新创建

(3)singleTask:栈中模式,即当activity处于栈中并重新回到栈顶的时候不重新创建

(4)singleInstance:这种模式下的acitvity会单独创建一个栈来存放acitvityq切其他activity不会存放到此栈

4.service的启动方式且各自的生命周期?
(1)startservice:这种启动方式与启动者的生命周期无关,onCreate()-onStartcommand()-onDestory()

(2)bindservice:这种启动方式会将service生命周期与启动者的生命周期绑定到一起,onCreate()-onBind()-onUnBind()-onDestory()

提示:如果我们的service继承的时intentservice,一般这种情况就是我们要在service中做耗时操作,然而intentservice在

onHandleIntent()中创建一个工作线程。然后在onDestory()中会自动关闭线程

5.BroadCastReceiver有几种分类及注册方式?

分类:(1)有序广播(2)标准广播

注册方式:(1)动态注册:就是代码注册广播(2)静态注册:在注册文件中注册

6.activity,window,decorView三者之间的关系?

对于这个问题如果有开发经验的就算猜估计也能猜出七七八八,一个acitvity就是一个界面,而window就是个虚拟概念并且附属在activtiy上的窗口,它唯一的实现类就是PhoneWindow,而一个PhoneWindow对应一个DecorView,其实就是一个FrameLayout。对于这个问题我们可以看看acitvity源码,找到window和decorview大概就明白了

7.activtiy,fragment数据传递

一般来说都可以用bundle传递,还有就是eventbus跨线程通讯进行传递。

(二)Fragment

在Fragment这个知识点上我首先想说明一下,如果你被问到Fragment生命周期,你可能会回答:

onAttach()-onCreate-onCreateView()-onActivityCreated()-onStart()-onResume(0-onPause-onStop-onDestoryView()-onDestory()-onDetach()。可能HR想问的也是这种情况,但是我认为这不是最全面的回答,举个例子:当我们在使用导航栏及Tablayout+ViewPager或者BottonNavigationView+ViewPager的时候,Fragment首先执行的不是onAttach()而是onUserVisiableHint()。至于原因我想用过这个控件的都清楚viewpager会默认缓存当前可见Fragment相邻两个Fragment,所以即便Fragment不可见也有可能执行其生命周期

1.Fragment的生命周期?

见上文

2.Fragemnt栈管理方式?

答:show(),hide()或add(),remove()

3.Fragment中出现内存泄露并导致闪退,请举例说出一种场景?

回答这个问题,我们首先需要知道什么是内存泄露,什么会导致内存泄露。

内存泄露:在android中不再使用的对象,Gc垃圾回收机制无法对其回收就会产生内存泄漏注:过多的内存泄漏会导致内存溢出OOM

什么情况会导致内存泄露?

(1)在单例模式中引用acitvity或其context:我们知道单例模式其生命周期跟应用程序一样,如果传入activtiy引用,当我们退出activity的时候,需要回收acitvity但是此时单例模式中单例对象持有acitvity引用导致GC无法回收acitvity,从而导致内存泄漏

(2)handle机制导致内存泄漏,我们都知道Handler创建在主线程而此时作为acitvity内部类的handler持有acitvity引用,当我们在子线程中sendMessage时创建message对象,而message持有handler引用,从而我们可以理解为message持有activity引用,当我们退出activity的时候,而这时候消息队列中还有消息未发出,又因为message持有activity引用,导致GC无法回收acitvity从而导致内存泄露

(3)匿名内部类/非静态内部类导致内存泄漏:由于非静态内部类持有外部类的引用,如果我们在内部类做了耗时操作,当退出当前activity的时候,GC无法回收activity,导致内存泄漏

(4)在退出界面的时候,未取消注册,释放资源会导致内存泄漏

好了说了这么多,回到正题,fragment中出现内存泄露并闪退说明内存泄露频繁导致oom.

(1)在销毁界面的时候未取消注册

(2)另外就是上面说的内存泄漏第三种情况,匿名内部类/非静态内部类导致内存泄漏。这种情况一般都是我们在进行网络请求的时候销毁页面,而请求在非静态内部类实现,导致gc无法回收activity,从而导致内存泄漏(在MVP模式中)

(三)内存优化

1.说下对内存优化的理解?

这个问题就不是三言两语了,内存优化是个比较广的知识面,他包括内存泄漏,布局优化,资源优化,内存溢出等知识点

我这里就总结内存优化的几点吧:
(1)减少内存泄漏,因为过多的内存泄露会导致内存溢出(具体流程见上文)

(2)适当的减少内存消耗,比如正常使用单例模式,对一些资源图片进行压缩处理

(3)布局优化。布局优化主要是减少嵌套层次,减少内存消耗,对于布局优化可能很多朋友比较模糊,其实布局优化也能提高app性能的。

(四)事件分发机制

事件分发机制主要涉及到三种情况:activtiy,viewgroup,view的事件分发机制

首先说明:事件分发机制涉及到三个函数,OnInterceptTouchEvent(),DispatchTouchEvent(),OnTouchEvent()

(1)activity事件分发机制

在activtiy的事件分发机制中没有OnInterceptTouchEvent()函数,这个很好理解,activity本来就是一个界面对于事件拦截不拦截都没有意义,因此activity事件分发DispatchTouchEvent()-OntouchEvent()

一般情况DispatchTouchEvent()都是返回Super.DispatchTouchEvent(),意思是本次事件交给ViewGroup下的DispatchTouchEvent()方法处理,如果DispatchTouchEvent()返回true,表示activity消费此次事件,并不向下传递,如果返回false,表示acitvity不消费此次事件交给上层view处理,而由于是activity中所以此次事件系统消费了。所以一般情况我们都是不重写DispatchTouchEvent()。

(2)ViewGroup事件分发
DispatchTouchEvent()-OnInterceptTouchEvent()-OnTouchEvent(),当事件传递到viewgroup时首先调用DispatchTouchEvent(),如果此方法返回Super.DispatchTouchEvent(),表示此次事件交给OnInterceptTouchEvent()处理,如果返回true,表示消费事件并不向下传递了,如果返回false表示不消费事件,并把事件交给上层view处理,

OnInterceptTouchEvent()如果返回super.OnInterceptTouchEvent()表示此次事件交给onTouchEvent()处理,如果返回true,表示对此次事件进行拦截了,不会传递给子View,自身消费此次事件并交给OnTouchEvent()处理,如果返回false表示不拦截此次事件,向下传递给子view,

OnTouchEvent():如果返回super.OnTouchevent(),表示不消费此次事件交给上层view处理直到某个view的OnTouchEvent返回true如果返回到activty还没有消费事件就由activtiy的onTouchEvent处理,如果返回true表示消费事件并终止传递,返回false跟super.OnTouchevent()一样

(3)view的事件分发

view的事件分发跟acitvity一样,没有OnInterceptTouchEvent()函数

 当事件分发到View的时候首先调用DispatchTouchEvent(),如果返回super.DispatchTouchEvent()表示交给OnTouchEvent()处理,如果返回true就消费,返回false就不消费事件,将事件交给上次view处理。

onTouchEvent()如果返回的是super.onTouchView()表示事件可以向下传递,如果返回true,表示消费事件,false跟super.onTouchView()一样

有朋友可能有疑问为什么view中onTouchView()事件还可以向下传递呐?我们知道每个事件都是由  down-move-up这三个action组成,其中down,up是必要事件,我们再看看view事件传递顺序onTouch()-onTouchEvent()-onClick()也就是说如果onTouch()返回true那么就不会执行后面两个方法,也就是说消费事件了,如果返回false,就先执行onTouchEvent(),如果onTouchEvent()返回true就不会执行onClick().如果返回false就执行onClick()

特别注意:返回super.onTouchEvent()源码中可以看到他会自动实现onclick,有朋友可以会想那么是不是返回super.onTouchEvent()会自动调用onClick()方法,其实不是,我们认真看源码,其实在actino在UP的时候要满足很多条件才会执行onClick().当然onTouchEvent()中有一个方法PerformClick()它内部会调用onClick()方法。因此也可以满足我们需求

(五)RxJava

1.说说你对RxJava的理解及使用场景?

简单来说rxjava就是一种响应式编程,也可以说链式编程(观察者模式),他配合retrofit使用及一些列操作符可以很优雅而简单的实现一些复杂的网络请求,他也可以实现轮询,定时器的一些线程切换的功能实现

2.rxbinding

我就说下rxview吧,其他接触很少,rxview就是防止连续操作控件而规定控制多少时间才能响应。比较常用的就是防抖

3.rxlifecycle

这个框架结合rxjava使用,主要防止网络请求产生的内存泄漏,他可以根据生命周期来取消订阅,

因为RXjava其原理及内部实现比较难理解所以就简单阐述下几个知识点(附上一个rxjava实现app版本更新的demo,有兴趣的可以看下https://blog.youkuaiyun.com/ZyClient/article/details/83176208)

(六)设计模式

1.单例模式

2.Builder模式

3.观察者模式

4.工程模式

5.mvp设计模式

此处我说下MVP模式,既然是设计模式那么写法肯定不是固定的,因此每个人对其理解都不一样,我就在此说下我对mvp模式的理解吧。

MVP是MVC的升级版,其中M-Model数据模型,V-View就是我们的视图,P-Presenter控制层,他控制M,V逻辑,使M,V完全解耦。一般来说我们在M层定义一个接口和一个实现类,实现类中获取网络数据或者进行一些数据操作,P层中获取到,M,V层引用,把M层返回的结果交给V层,最后在V层做处理(更新ui一些操作)。

(七)自定义view

自定义view涉及到的知识点比较全面,也是个难点,一般来说自定义view就是去实现一些我们系统控件实现不了的效果,其具体流程就是onMeasure()-onLayout-onDraw()其中onMeasue()就是测量,这个一般在组合控件中比较常见,onLayout()就是控制view的显示位置,onDraw()就是绘制view,绘制view涉及到canvas与paint一个画布一个画笔

(八)string,stringbuffer,stringbuilder区别

这个问题是很常见也问的很多的问题,一般来说我们从三个方面回答

(1)可变性:string为常量不可变因此每次拼接字符串都要重新创建对象,stringbuffer,stringbuilder为变量直接调用相应api操作

(2)安全性:string由于为常量因此是线性安全的,而stringbuffer内部实现了双重锁因此也是线性安全的,而stringbuilder则线性不安全

(3)效率:如果少量拼接string比较合适,如果单线程大量操作stringbuilder比较合适,如果多线程大量操作stringbuffer比较合适

(九)RecyclerView

1.关于scollview嵌套recyclerview嵌套卡顿或者显示问题

这个问题网上很多人说在布局中各种操作,其实我认为最好的解决办法不是这样,在MD中有个NewtedScollView完全可见解决这个问题

2.关于rv的优点

三点:一是rv复用性,二是:rv缓存级别高,三是:rv可以局部刷新

(十)ConsTraintLayout

谈谈对ConsTraintLayout约束布局优缺点的理解?

从as2.2后就支持constraintlayout也就是约束布局,这个布局非常强大,他可以完全替换以前的linearlayout,framelayout等布局

优点:

1.可以轻松实现复杂的布局

2.减少布局嵌套,优化内存作用

3.增加一些特殊属性

缺点:

由于布局我是手动写的,我觉得唯一的缺点就是每个控件无论需要赋值与否都要设置相应的id,来约束其他控件位置。(附上一个constraintlayout的一个demo有兴趣的可以看下https://blog.youkuaiyun.com/ZyClient/article/details/82218540)

(十一)跨进程通讯

说说跨进程通讯?

跨进程通讯即IPC,但是跨进行通讯也很常见

1.打开系统进程(一般在activity中启动系统进程比较常见)

2.contentProvide

3.BroadCastReceiver广播

4.Service(messenger)

此处说下service中跨进程通讯:

上面也提到service跨进程通讯用到messenger,客户端启动bindservice,我们在服务得创建service时创建一个handler来接受客户端发送过来得消息,并且创建一个Messenger对象传入handler,由于启动方式是bindservice就实现了onbind,onunbind方法,在onbind方法中我们通过messenger返回一个ibinder对象,最后在清单文件中定义该service

在客户端创建一个serviceconection类,重写onServiceConnected与onServiceDisconnected方法,在onServiceConnected中我们通过服务端创建得ibinder创建messenger对象,然后客户端就可以通过bindservice启动服务了,当我们需要发送消息给服务端就调用messenger.send(传入message)

public class MessengerService extends Service {
    public final static String TAG = MessengerService.class.getSimpleName();
    public final static int MSG_SAY_HELLO = 1;

    public MessengerService() {
    }

    @Override
    public void onCreate() {
        Log.d(TAG, "onCreate");
        super.onCreate();
    }

    @Override
    public void onDestroy() {
        Log.d(TAG, "onDestroy");
        super.onDestroy();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "onStartCommand");
        return super.onStartCommand(intent, flags, startId);
    }

    /**
     * 1. 定义一个Handler,用于处理客户端发来的请求
     */
    class ProcessHandler extends Handler{

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                case MSG_SAY_HELLO:
                    Log.d(TAG, "service receiver from client: say hello");
                    break;

                default:
                        super.handleMessage(msg);
            }

        }
    }

    /**
     * 2. 创建一个Messenger并传入Handler实例对象
     */
    final Messenger mMessager = new Messenger(new ProcessHandler());

    @Override
    public IBinder onBind(Intent intent) {
        Log.d(TAG, "onBind");
        // 3.通过onBinder返回Messenger的Binder对象
        return mMessager.getBinder();
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.d(TAG, "onUnbind");
        return super.onUnbind(intent);
    }
}
 <service
            android:name=".MessengerService"
            android:enabled="true"
            android:exported="true"
            android:process=":messengerSer"/>
/**
     * 与服务端交互的Messender
     */
    Messenger mService = null;
    boolean mBound = false;
    /**
     * ServiceConnection代表与服务的连接,
     */
    ServiceConnection cnn2 = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            Log.d("###", "onServiceConnected");
            /**
             * 3. 通过服务端传递的IBinder对象,创建相应的Messenger
             * 然后通过Messenger对象与服务端进行交互
             */
            mService = new Messenger(iBinder);
            mBound = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            Log.d("###", "onServiceDisconnected");
            mService = null;
            mBound = false;
        }
    };
// 绑定服务
Intent intent = new Intent(this, MessengerService.class);
bindService(intent, cnn2, BIND_AUTO_CREATE);
// 解绑服务
unbindService(cnn2);
mBound = false;
// 发送消息
Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO);
try {
    // 4. 通过Messenger发送消息
    mService.send(msg);
} catch (RemoteException e) {
    e.printStackTrace();
}

(十二)ANR

我想对于android开发者来说对于ANR这个词并不陌生,那么ANR是什么?什么情况会ANR?怎么避免?

(1)ANR:application not response应用程序无响应

(2)ANR产生主要有以下几点引起:1.在主线程做过多耗时操作2.在activity事件操作5s无响应(跟第一点差不多)3.braodcastrecevier事件操作10s无响应4.service事件操作20s无响应

(3)避免ANR:主线程中只做ui处理,耗时操作开启新线程,线程切换利用rxjava或静态内部类handler机制处理

(十三)Android中数据存储

(1)说下常用得数据存储方式?

1.文件存储 2.网络存储 3.ContentProvider数据存储 4.SharePreferences数据存储 5.本地数据库存储

提示:一般数据量小用sp,数据量大数据库

(2)sp线性安全吗?apply()与commit()方法区别?

1.首先sp是利用单例模式实现得,从源码可以看到有synchronized因此是线程安全得,

2.commit()是同步得并返回提交结果,apply()是异步操作不会返回结果.此外从效率上说apply()比commit()效率高,如果不关心返回结果建议使用apply()进行提交

(十四)gc机制

所谓gc机制就是垃圾处理器一共需要两部:检测和回收垃圾

(1)检测垃圾算法

1.引用计数法:一个对象引用一次计数+1,引用失效-1

2.根搜索法:以根集对象为起始点进行搜索,如果有对象不可达的话,即为垃圾对象。这里的根集一般包括:java栈中的引用对象、本地方法栈中JNI的引用对象、方法区中运行常量池中的引用对象、方法区中静态属性引用的对象、运行中的线程、由引导类加载器加载的对象、GC控制的对象。总之,JVM在做垃圾回收的时候,会检查堆中的所有对象是否被这些根集中的对象所引用,不能够被引用的对象就会被垃圾回收器回收。

(2)回收算法

1.标记-清除:将所有需要回收的对象进行标记,然后统一清除

2.复制算法:将内存分两个区域,只使用其中一个区域存储对象,垃圾回收时遍历使用区域的所有对象并将使用对象复制到另外一个区域。

3.标记-整理:此算法为前两个算法的结合体,分两个阶段,第一部将所有被使用的对象标记,第二部遍历堆中所有对象将未被标记的对象进行回收并整理存活对象

4.分代收集算法:年轻代:复制算法,老年代:标记-整理

(十五)HashMap,ArrayList

1.对于HaspMap原理我也是才通过一些资料研究了一下,我先根据我的理解说说HashMap原理及结构

(1)HaspMap结构在jdk1.8以前:数组+链表也就是散列表形式,在jdk1.8加了一个红黑树其结构:数组+链表+红黑树

至于其意义接下来请看HashMap原理

(2)HashMap原理:首先我们通过源码看HashMap他默认的数组大小16,每次扩容为其2倍,且数组大小为2的N次方。

数据由Entry实体类以键值对形式存储,而每个实体类对应一个HashCode.在java中每个对象都有一个hashcode()方法,它是一个由32位整数组成的,而在HashMap中我们只需要9位Int整数型,当我们put一个键值对的时候,会首先判断key是否位null,(为null默认返回第一个)然后根据K找到获取HashCode值然后对其进行hash运算获取到hash值,接着循环table根据其hash值及key判断是否相同如果相同就替换,如果不相同就添加一个Entry

另外特别注意:有可能hash冲突,也就是说我们随机参数的int整数型重复了,这时候我们就通过拉链表的方式进行处理,让每个Entry以单向链表形式存在,当链表长度达到8就会采用红黑树提高性能,当链表长度小于8就重新由转换成单向链表

总结:HashMap默认数组大小为16,每个键值对都是以Entry实体类存储的,然后每个K会对应一个HashCode也就是Hash值,当我们put一个数据的时候,首先会根据这个K获取到对应的hashcode通过hashcode获取到hash值,然后循环散列表也就是循环table判断k,hash值是否相等,如果相等就表示是更新数据,如果有一个不相等就表示添加数据(包括hash冲突,上面已经说到)。最后我们也可以通过不同构造函数设置数组默认大小,负载因子。

2.ArrayList结构及原理?

ArrayList结构及原理就比较简单了,其实他就是List接口的实现类,他内部结构就是数组切大小可变

ArrayList:是一个大小可变可重复切有序的数组,每次添加一个元素数组大小都会+1

(十六)动画

写在前面:说到android动画我们脑海里就会想起自定义,平移,旋转等一些特效。其实android动画也是个知识面比较广的。

1.android动画分几类,说说他们的区别与特点?

(1)帧动画(frame):通过顺序的播放排列好的图片来实现

(2)补间动画(tween):包括移动、渐变、伸缩、旋转,一般是定义在res-anim这个资源文件夹下,然后res-style中定义这个动画

(3)属性动画(Property ):属性动画可以定义在res-animator的资源文件中,它是用来在特定的时间修改对象的属性,例如背景颜色和alpha等等,常用的Java类有:ValueAnimator 、ObjectAnimator和AnimatorSet

总结:帧动画与补间动画归为:视图动画。属性动画为另一类,此外我推荐另外两个动画,共享动画和过渡动画,有兴趣的朋友可以研究下

(十七)android屏幕适配

虽然现在有constraintlayout对屏幕适配又多了一些技巧,但是我们真正了解sp,dp,dpi嘛?为什么我们字体要用sp,控件用dp?

首先:字体用sp设置大小可以跟随系统字体大小改变而改变,控件用dp至少对不同分辨率适配了

接下来我们了解下sp,dp,dpi这几个单位:

sp:字体的单位,和dp差不多,区别是如果字体使用的sp为单位,那如果你手机字体调大了,那你app的字体会随之变大,如果用dp则不会变化。

dp:最常用的长、宽、margin、padding等的单位

dpi:像素密度

px:像素

其中height,width为长宽像素密度,size对角线长度

px=dp*(dpi/160)

特别注意:假设现在我有两部手机分辨率不一样,但是手机尺寸大小一样,假如第一部手机的像素密度及dpi=320,第二部手机的像素密度及dpi=160,我设置了一个2dp的宽的控件根据px=dp*(dpi/160)公式可得像素密度为160的px=dp及1px1dp,像素密度320的px=2*dp及1dp=2px.我们可以想象像素密度越大那么说明像素之间很紧密,反之就稀疏。那么当我在160dpi手机上设置宽为2dp的时候此时2dp=2px,在320dpi手机上设置宽的为2dp的时候此时2dp=4px.上面说到像素密度越大像素之间就紧密,那么此时在手机尺寸大小一样的情况下。此时2px与4px宽度相差不大的。你可以把一个像素想象成一个点,像素密度(dpi)越大每个点的距离就越小,反正就越大。这就是为什么设置宽高要用dp了,因为它适配了不同分辨率。

(十八)线程池

线程池的作用及原理?

首先我们看下使用线程池的原因:在我们开发中我们有时候需要频繁创建工作线程,然后这些工作线程及有可能导致线程阻塞,而且频繁创建线程也会降低性能

那么线程池的作用是什么呐?

根据上诉我们知道:线程池就是用来管理一个个线程的,它不会频繁创建线程,而且对其进行复用这样就不会频繁调用gc,提高了效率及性能。

那么线程池的原理是什么?

要知道线程池原理首先我们看下其构造函数:

ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory)

corePoolSize:核心线程最大数量

maximumPoolSize:最大线程数量

keepAliveTime:非核心线程的保活时间,就是说当非核心线程在空闲状态在保活时间,这样当工作任务时间短,可以避免频繁创建线程。提高效率及性能

unit:上面时间属性的单位

workQueue:任务队列

threadFactory:线程工厂,可用于设置线程名字等等

通过构造函数我们就不难推出线程池的原理了:

1.当有新的任务进入的时候(execute一个线程之后)会首先判断当前核心线程是否达到最大,如果没有就直接创建一个核心线程开执行任务

2.当有新任务进入的时候(execute一个线程之后)如果核心线程达到最大但是任务队列未满,那么次任务就会进入任务队列等待

3.当有新的任务进入的时候(execute一个线程之后)如果核心线程达到最大并且任务队列已经满了,但是线程数量未超过非核心线程最大数量,就创建一个新非核心线程执行任务

4.当有新任务进入的时候(execute一个线程之后)如果线程池中的线程数已经超过非核心线程数,则拒绝执行该任务,采取饱和策略,并抛出RejectedExecutionException异常

(十九)面向对象基本原则

之前我看别人面试有被问到过这个问题,于是就在网上查阅了一番,总体来说面向对象一共有六大基本原则:

1.单一职责原则

2.开闭原则

3.里氏替换原则

4.依赖倒置原则

5.迪米特原则

6.接口隔离原则

(二十)关于String a=new String("a")创建几个对象问题的正确答案

我们知道String是个不可变的常理,每次赋值都会创建一个对象,但是今天遇到个问题,String a=new String("a")创建了几个对象?

首先我举个列子来复习下String;

String  s="Hellow";

s="android";

String str="android";

String  s=new String("a");

在jvm的工作过程中,会创建一片的内存空间专门存入string对象。我们把这片内存空间叫做string池。  

我们先来看下String s="Hellow",定义了一个String s的变量,“Hellow”为String 对象,当JVM检查到“Hellow”的时候。如果string池中有“Hellow”对象,就直接把其引用给s不会重新创建string对象,如果没有就创建string对象,并将其引用给s。这里没有就创建string对象

再来看下s="android";同样当JVM检查到“android”的时候。如果string池中有“android”对象,就直接把其引用给s不会重新创建string对象,如果没有就创建string对象,并将其引用给s。这样也没有就创建string对象.

所以

String  s="Hellow";

s="android";就创建了两个对象。

String str="android";再来看下,我们定义了一个str的字符串。并将“"android"”对象引用给他,上面提到JVM检查到”android“,就将其引用给str,由于上面s="android"已经创建了"android"string对象,所以这里就直接将"android"对象引用给str,并且str==s.因为两个字符串引用相同。

最后String  s=new String("a");

"a",JVM检查没有就创建,有就引用,

new String这里又手动创建了一个string对象.

因此String a=new String("a")一共创建了两个对象
 

(二十一)Java集合中List,Set以及Map等集合体系详解(史上最全)

概述:

  • List , Set, Map都是接口,前两个继承至Collection接口,Map为独立接口
  • Set下有HashSet,LinkedHashSet,TreeSet
  • List下有ArrayList,Vector,LinkedList
  • Map下有Hashtable,LinkedHashMap,HashMap,TreeMap
  • Collection接口下还有个Queue接口,有PriorityQueue类

这里写图片描述

注意:

  • Queue接口与List、Set同一级别,都是继承了Collection接口。
    看图你会发现,LinkedList既可以实现Queue接口,也可以实现List接口.只不过呢, LinkedList实现了Queue接口。Queue接口窄化了对LinkedList的方法的访问权限(即在方法中的参数类型如果是Queue时,就完全只能访问Queue接口所定义的方法 了,而不能直接访问 LinkedList的非Queue的方法),以使得只有恰当的方法才可以使用。

  • SortedSet是个接口,它里面的(只有TreeSet这一个实现可用)中的元素一定是有序的。

总结:

Connection接口:

— List 有序,可重复

  • ArrayList
    优点: 底层数据结构是数组,查询快,增删慢。
    缺点: 线程不安全,效率高
  • Vector
    优点: 底层数据结构是数组,查询快,增删慢。
    缺点: 线程安全,效率低
  • LinkedList
    优点: 底层数据结构是链表,查询慢,增删快。
    缺点: 线程不安全,效率高

—Set 无序,唯一

  • HashSet
    底层数据结构是哈希表。(无序,唯一)
    如何来保证元素唯一性?
    1.依赖两个方法:hashCode()和equals()

  • LinkedHashSet
    底层数据结构是链表和哈希表。(FIFO插入有序,唯一)
    1.由链表保证元素有序
    2.由哈希表保证元素唯一

  • TreeSet
    底层数据结构是红黑树。(唯一,有序)
    1. 如何保证元素排序的呢?
    自然排序
    比较器排序
    2.如何保证元素唯一性的呢?
    根据比较的返回值是否是0来决定

针对Collection集合我们到底使用谁呢?(掌握)

唯一吗?

是:Set

排序吗?

是:TreeSet或LinkedHashSet
否:HashSet
如果你知道是Set,但是不知道是哪个Set,就用HashSet。

否:List

要安全吗?

是:Vector
否:ArrayList或者LinkedList

查询多:ArrayList
增删多:LinkedList
如果你知道是List,但是不知道是哪个List,就用ArrayList。

如果你知道是Collection集合,但是不知道使用谁,就用ArrayList。
如果你知道用集合,就用ArrayList。

说完了Collection,来简单说一下Map.

Map接口:

上图:
这里写图片描述

Map接口有三个比较重要的实现类,分别是HashMap、TreeMap和HashTable。

  • TreeMap是有序的,HashMap和HashTable是无序的。
  • Hashtable的方法是同步的,HashMap的方法不是同步的。这是两者最主要的区别。

这就意味着:

  • Hashtable是线程安全的,HashMap不是线程安全的。
  • HashMap效率较高,Hashtable效率较低。
    如果对同步性或与遗留代码的兼容性没有任何要求,建议使用HashMap。 查看Hashtable的源代码就可以发现,除构造函数外,Hashtable的所有 public 方法声明中都有 synchronized关键字,而HashMap的源码中则没有。
  • Hashtable不允许null值,HashMap允许null值(key和value都允许)
  • 父类不同:Hashtable的父类是Dictionary,HashMap的父类是AbstractMap

重点问题重点分析:

(一).TreeSet, LinkedHashSet and HashSet 的区别

1. 介绍

  • TreeSet, LinkedHashSet and HashSet 在java中都是实现Set的数据结构
  • TreeSet的主要功能用于排序
  • LinkedHashSet的主要功能用于保证FIFO即有序的集合(先进先出)
  • HashSet只是通用的存储数据的集合

2. 相同点

  • Duplicates elements: 因为三者都实现Set interface,所以三者都不包含duplicate elements
  • Thread safety: 三者都不是线程安全的,如果要使用线程安全可以Collections.synchronizedSet()

3. 不同点

  • Performance and Speed: HashSet插入数据最快,其次LinkHashSet,最慢的是TreeSet因为内部实现排序
  • Ordering: HashSet不保证有序,LinkHashSet保证FIFO即按插入顺序排序,TreeSet安装内部实现排序,也可以自定义排序规则
  • null:HashSet和LinkHashSet允许存在null数据,但是TreeSet中插入null数据时会报NullPointerException

(二).TreeSet的两种排序方式比较

由于TreeSet可以实现对元素按照某种规则进行排序,例如下面的例子

public class MyClass {

    public static void main(String[] args) {
        // 创建集合对象
        // 自然顺序进行排序
        TreeSet<Integer> ts = new TreeSet<Integer>();

        // 创建元素并添加
        // 20,18,23,22,17,24,19,18,24
        ts.add(20);
        ts.add(18);
        ts.add(23);
        ts.add(22);
        ts.add(17);
        ts.add(24);
        ts.add(19);
        ts.add(18);
        ts.add(24);

        // 遍历
        for (Integer i : ts) {
            System.out.println(i);
        }
    }
}
运行结果:
17
18
19
20
22
23
24
————————————————

(1).自然排序

自然排序要进行一下操作:
1.Student类中实现 Comparable接口
2.重写Comparable接口中的Compareto方法

(2).比较器排序

比较器排序步骤:
1.单独创建一个比较类,这里以MyComparator为例,并且要让其继承Comparator接口
2.重写Comparator接口中的Compare方法

(二十二)热更新,热插件原理

1.热插件:hook,热更新:底层替换,类加载器

重点说下类加载器实现热更新吧:

首先我们知道热更新需要实现对应插件得sdk(比如thinker),然后打包补丁,去自动下载更新,

那么怎么实现更新得呐,首先我们知道android得虚拟机时Dalvik,java虚拟机时jvm,我们得应用程序最终会编译成,dex文件,它包含多个.class文件,这样.dex文件比之前会小很多,性能,效率提高了,那么我们知道了android程序最终会编译成.dex文件,我们来看看类加载器,系统自带的dexelements列表里面包含多个.dex文件,每个.dex文件都在dexelemenets里面有相应的位置,位置靠前的就优先加载,如果dexlements里面有,dex文件就会直接返回加载,因此我们要实现热更新就是在系统默认的dexelements列表里面把我们的,dex文件放到前面,这里可以优先加载了,由于是系统默认的基本上都是private修饰,所以需要用到反射机制,当我们更改后,我们自己的dex文件就会放到dexelements前面,优先加载与系统默认的dexelements。从而实现热更新了

另外我这里提到过Dalvik与jvm虚拟机,那么这两个虚拟机有什么不同呐?

dalvik虚拟机时基于寄存器,jvm是基于栈堆的,dalvik比jvm性能,效率高。

(二十三)volatile和synchronized,sleep与wait

1.volite与synchronized区别:

(1)volite不会导致线程阻塞,synchronized可能会

(2)volite不能保证原子性,只有可见性,synchronized保证可见性,原子性

  (3)volite只能修饰变量,synchronized可以修饰方法

java并发编程三大特性:原子性,可见性,有序性

 

被synchronized修饰的代码只能被被当前线程占用,避免由于其他线程的执行导致的无序行。

volatile关键字包含了禁止指令重排序的语义,使其具有有序性。

synchronized 关键值,开始时会从内存中读取,结束时,会将变化刷新到内存中,所以是可见的。

volatile关键值,通过添加lock指令,也是可见的。

2.sleep与wait方法

1.sleep是thread方法,wait是object的方法

2.sleep不释放对象锁,wait放弃对象锁

3.sleep线程进入暂停,处于监控状态结束后自动恢复

4.wait后只有对此对象进行对象锁后才能进入运行状态

 

(二十三)http,tcp,udp,socket

1.http是超文本传输协议,客户端通过http协议向服务端发送请求,服务端收到请求后响应信息给客户端

2.tcp:传输协议,有连接,三次握手,四次挥手

3.udp:传输协议,无连接,知道ip及端口号就发送数据,不管发送成功

4.socket:是一种不同计算机,实时连接,比如说传送文件,即时通讯

Ok问到tcp,udp,http,socket区别差不多就知道这些,更多得就不知道了

(二十四)NDK

说到NDK,我们先来看到jni,我们都知道java是跨平台语言编程的,它与本地交互能力较弱,因此就诞生出jni了,jni是java的特性,它主要用于java与c/c++交互。

那么我们为什么要用NDK呐?首先java与c/c++交互,c/c++编译成.so文件,在android中我们通过NDK将c/c++编译成的.so文件快速打包到apk里面,这样我们就快速,高效解决了交互问题。附上一个详细的链接有兴趣的朋友可以看下:https://blog.youkuaiyun.com/ZyClient/article/details/103029932

(二十五)图片加载

图片加载分多种情况:

1.图片大小适应:直接用第三方框架加载

2.图片稍大:用bitmapfactory工厂模式对图片进行尺寸压缩后加载

3.图片超大:一般来说图片过大了,就会导致一屏显示不全,这时候我们就要用到局部加载或者说区域加载

android中为我们提供BitmapRegionDecoder这个类来解决局部加载图片问题

(二十六)listview,Recyclerview滑动卡顿的原因

滑动卡顿一般由以下几个因素产生:

1.item布局加载了大量资源包括大图

2.item布局多次绘制导致与Ui刷新机制冲突,视觉上ui绘制很慢

3.嵌套问题,有时候会根据项目需求列表嵌套列表导致滑动卡顿

(二十七)koltin,java区别

这个面试经常问到,我总结以下几点吧:

1.kotlin非空判断安全性

2.koltin中支持协程

3.koltin变量没有get,set方法

4.koltin中集合许多函数

5.koltin中变量申明,方法申明,接口实现,类继承等不同

6.koltin导入布局后可直接引用id

7.kotlin中不支持三目运算等其他语句与java有所不同

特别注意:kotlin,java可以100%互通,也就是说完全可以混合开发

(二十八)java中基本类型与包装类型区别

在java中每个基本类型都有对应的包装类型,比如说 int 的包装类型为 Integer,double 的包装类型为 Double,基本类型和包装类型的区别:

1.包装类型可以为null,基本类型不可以

2.包装类型存储在堆中,而基本类型存储在栈中,从效率上说基本类型比包装类型好

3.包装类型可以用于泛型而基本类型不行

4.自动装箱与自动拆箱

自动装箱:把基本类型转成包装类型。自动拆箱:把包装类型转成基本类型。自动装箱是通过 Integer.valueOf() 完成的;自动拆箱是通过 Integer.intValue() 完成的。我们来看看下面几个题:

(1)Integer a= new Integer(10);
Integer b = new Integer(10);

System.out.println(a== b); // false
System.out.println(a.equals(b)); // true

分析:Integer为包装类 ==比较引用因此是false,而equals比较值所以true


(2) int a = 100;

Integer b = 100;

System.out.println(a == b);true

分析:基本类型与包装类型比较==,这时候包装类型会进行自动拆箱,int c=b.intValue()因此true

(3)Integer c = 100;

Integer d = 100;

System.out.println(c == d);

分析:两个包装类型比较==,我想大多数第一次接触的多半会认为是false,其实正确答案是true。

之前我们已经知道了,自动装箱是通过 Integer.valueOf() 完成的,那我们就来看看这个方法的源码吧。

public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

难不成是 IntegerCache 在作怪?你猜对了!

private static class IntegerCache {
    static final int low = -128;
    static final int high;
    static final Integer cache[];

    static {
        // high value may be configured by property
        int h = 127;
        int i = parseInt(integerCacheHighPropValue);
        i = Math.max(i, 127);
        h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
        high = h;

        cache = new Integer[(high - low) + 1];
        int j = low;
        for(int k = 0; k < cache.length; k++)
            cache[k] = new Integer(j++);

        // range [-128, 127] must be interned (JLS7 5.1.7)
        assert IntegerCache.high >= 127;
    }
}

大致瞟一下这段代码你就全明白了。-128 到 127 之间的数会从 IntegerCache 中取,然后比较,所以第二段代码(100 在这个范围之内)的结果是 true,而第三段代码(200 不在这个范围之内,所以 new 出来了两个 Integer 对象)的结果是 false。

看完上面的分析之后,我希望大家记住一点:当需要进行自动装箱时,如果数字在 -128 至 127 之间时,会直接使用缓存中的对象,而不是重新创建一个对象。

(4)
c = 200;

d = 200;

System.out.println(c == d);

分析:通过第三题我们知道了,c=200,d=200自动装箱的时候会重新创建对象,所以这里是false

(二十九)线程与进程

1.进程:进程是系统进行资源分配的基本单元

.有一段程序供其执行
.拥有专用的系统堆栈空间
·在内存中有对应的进程控制块
·拥有独立的用户存储空间
·进程之间不能进行自由的信息交互

2.线程:是程序执行的最小单位,是CUP调度的基本单元

.一个进程必须拥有至少一个线程

.线程是进程的一个实体,是cpu调度与分配的基本单位,它是比进程更小能独立运行的单位

.线程比进程更小,基本上不拥有系统资源,故对它的调度所用资源小,能更高效的提高系统内多个程序间并发执行的

(三十)requestLayout()、invalidate()与postInvalidate()有什么区别?

requestLayout : 当当前布局的宽高发生改变的时候, 此时需要重新调用父view的onMeaure和onLayout, 来给子view重新排版布局
invalidate : 让页面刷新, 重新调用onDraw方法,
postInvalidate : 在子线程来让页面来进行刷新的方法

1.RequsestLayout和invalidate有什么区别

仅仅从三大方法的角度来说

requestLayout  方法触发===》onMeasure + onLayout

invalidate 方法触发  ===》onDraw

 

2.invalidate 和 postInvalidate有什么区别

都是视图重绘

前者在ui线程调用,后者可以再其他线程调用
 

今天就汇总到这里吧,这篇博客后续会继续更新,欢迎大家留言,另外可以加QQ群:290611780交流

 

 

 

 

 

 

 

【数字IC刷题】华为海思数字IC笔试题(3)详细解析版 阅读详情

相关推荐

远程桌面项目

远程桌面项目

weixin_41560737的博客 1933

Android开发技术-笔试面试题分析一

课程搜集整理了国内,国外各大计算机,互联网等公司的笔试面试新题型,通过深入的分析来讲解Android开发的技术,使学习者对知识有更深入的理解,为自己笔试面试Android技术积累知识和经验。

LM358实战:手把手教你搭建电流检测电路(附电阻选型计算)

本文详细解析了使用LM358运算放大器搭建电流检测电路的全过程,包括基础原理、采样电阻选型、放大电路设计及PCB布局技巧。通过实战案例和精确计算,帮助工程师快速掌握低成本、高精度的电流检测方案,适用于电源管理、电机控制等多种应用场景。

weixin_30872157的博客 447

Android面试题(持续更新中)

Android面试题

Bearin的博客 1万+

深入了解 Google Gemini:主要功能是什么以及我们为什么要使用它?

Google Gemini开启AI新纪元,以其独特的多模式功能重塑技术未来。

KompasAI的博客 4065

开发板的使用

一、开发板使用学习大纲。 1、开发板组成、核心板资源,底板资源。 2、开发板连接、调试工具、串口参数配置。 3、开发板启动过程。 4、文件传输 1)使用串口传输。 上传/下载 2)使用网口传输。 上传/下载 5、临时/永久配置开发板IP地址。 6、开发板启动脚本。 二、开发板的组成。 核心板: CPU处理器: 芯片:S5P6818(三星) 内核: ARM cortex-A53 -> 八核处理器 运行内存:512MB*2=1G nandflash:4G 底板: 电源线:5V 串口...

qq_45633736的博客 2658

Android面试题大全(2024年最新)

声明:有人说, 有些面试题很变态,个人认为其实是因为我们基础不扎实或者没有深入。本篇文章来自一位很资深的前辈对于最近Android面试题目所做的总结归纳,有1600+道题目 ,知识面很广 ,而且这位前辈对于每个题都自己测试给出了答案 ,如果你对某个题有疑问或者不明白,可以电脑端登录把题目复制下来然后发表评论,大家一起探讨,也可以电脑端登录后关注我给我发私信,我们一起进步!

Androiddddd的博客 3万+

麻辣香锅病毒分析

Spicy Hot Pot浏览器劫持病毒(麻辣香锅病毒)从2020年初被安全公司监测到,因其病毒模块带有MLXG_KM被安全行业代称麻辣香锅病毒。目前通过各种激活工具传播, 包括暴风激活、小马激活和KMS激活等诸多工具,疑似与下载站进行合作推广此类激活工具。Spicy Hot Pot 是一个浏览器劫持 Rootkit,它会将用户的主页更改为指向恶意软件操作员控制的页面,此外还会将内存转储从机器上传到预定义的服务器,并结合本地更新功能以确保其保持更新。通常浏览器劫持者会通过更改用户主页的恶意可执行文件或注册表

不忘初心,护天下安全! 4788

常见Android面试题及答案(详细整理)

对于Android的学习,很多⼈可能学了之后,不知道⾃⼰处于哪个阶段,也不到究竟要学到哪个程度,验证⾃⼰学得如何最好的⾯试,就是尝试去⾯试,⽽⾯试⽆⾮就是问你⼀些⾯试题。所以呢,小编整理了这些 Android ⾯试题,从 Java 基础,并发,虚拟机到Android Framework,开源框架,性能优化,并且附带了详细的答案,⽆论是想⾯试还是想看看⾃⼰学得如何,那么这份⾯试题,都值得你去学习。答: 如下图所示。

Android 开发架构 1万+

ThingsBoard教程(七):模拟设备遥测

前言 各位读者好,截止目前,ThingsBoard系列文章已经做了六篇,分别是 ThingsBoard教程(一):ThingBoard介绍及安装 ThingsBoard教程(二):租户,租户配置,部件组模块的使用 ThingsBoard教程(三):系统设置模块的使用 ThingsBoard教程(四):规则链简介与操作 ThingsBoard教程(五):客户,资产管理 ThingsBoard教程(六):设备管理 上一篇我们讲解了如何使用设备管理来对设备进行增删改查,和设备配置的一些基本概念,本篇文章就带大

知无涯 4577

QCC304x系列开发教程(基础篇)之2.1-QCC3040之开发环境搭建

一、安装MDE 1.解压qualcomm_mde.win.2.4_installer_2.4.1.4压缩包,安装MDE_WIN_2.4.1.4_x64.exe,路径自定义 点击NEXT, 安装完成后,点击Finish. 完成安装后,桌面生成快捷方式

心跳包的博客 6077

被面试官问的Android基础题难倒了?这里有31道面试题 ,牢固你的基础!

目录 1.如何对 Android 应用进行性能分析 2.什么情况下会导致内存泄露 3.如何避免 OOM 异常 4.Android 中如何捕获未捕获的异常 5.ANR 是什么?怎样避免和解决 ANR(重要) 6.Android 线程间通信有哪几种方式 7.Devik 进程,linux 进程,线程的区别 8.描述一下 an...

chuhe1989的博客 5271

Google Earth Engine(GEE)——将sentinel - 2影像所有波段重采样到10m分辨率 (resample 和 projection的使用)

影像重投影是将一个影像从一个坐标系投影到另一个坐标系的过程。这通常涉及到将像素从一个平面坐标系变换到另一个平面坐标系。这可以用于许多应用中,例如建立数字高程模型(DEM)和地图制图。影像重投影通常需要进行数学计算,包括转换矩阵和插值算法,以确保像素值的准确性和精度。这次我们将对哨兵2好数据中20m分辨率的波段,重采样到10m分辨率中,然后同一参与计算。

此星光明博客 3107

【必看】《2024最新Android中高级面试题汇总》它来了~_安卓 中高级

都说三年是程序员的一个坎,能否晋升或者提高自己的核心竞争力,这几年就十分关键。技术发展的这么快,从哪些方面开始学习,才能达到高级工程师水平,最后进阶到Android架构师/技术专家?我总结了这 5大块;我搜集整理过这几年阿里,以及腾讯,字节跳动,华为,小米等公司的面试题,把面试的要求和技术点梳理成一份大而全的“ Android架构师”面试 Xmind(实际上比预期多花了不少精力),包含知识脉络 + 分支细节。

2401_84544363的博客 1078

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

移动开发最新安卓第八趴(1),2024年最新大厂android高级面试题汇总解答问题

对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。整理的这些架构技术希望对Android开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。下面是部分资料截图,诚意满满:特别适合有开发经验的Android程序员们学习。不论遇到什么困难,都不应该成为我们放弃的理由!如果你看到了这里,觉得文章写得不错就给个赞呗?

2401_84537826的博客 844

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

2024年安卓最新腾讯、阿里Android高级面试真题汇总,专题解析,最新精心整理Android面试题

最后对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们!这里附上上述的技术体系图相关的几十套腾讯、头条、阿里、美团等公司2021年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。

2401_84563561的博客 665

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Android面试题汇总(1),2024最新安卓大厂面试题来袭

面试是一个不断学习、不断自我提升的过程,有机会还是出去面面,至少能想到查漏补缺效果,而且有些知识点,可能你自以为知道,但让你说,并不一定能说得很好。有些东西有压力才有动力,而学到的知识点,都是钱(因为技术人员大部分情况是根据你的能力来定级、来发薪水的),技多不压身。附上我的面试各大专题整理: 面试指南,满满的都是干货,希望对大家有帮助!网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

2401_84102759的博客 396

2024年最新Android全面解析之Handler机制:常见问题汇总,安卓framework面试题

答: 当MessageQueue为空或者目前没有需要执行的Message时会回调的接口对象。IdleHandler看起来好像是个Handler,但他其实只是一个有单方法的接口,也称为函数型接口:在MessageQueue中有一个List存储了IdleHandler对象,当MessageQueue没有需要被执行的Message时就会遍历回调所有的IdleHandler。所以IdleHandler主要用于在消息队列空闲的时候处理一些轻量级的工作。

2401_84544914的博客 786

2024年Android最新android NDK 知识汇总,安卓app开发面试题

这份体系学习笔记,适应人群:**第一,**学习知识比较碎片化,没有合理的学习路线与进阶方向。,到了合适的年纪,后续不知道该如何发展,转型管理,还是加强技术研究。如果大家觉得自己在网上找的资料非常杂乱、不成体系的话,我也分享一套给大家,比较系统,我平常自己也会经常研读。在当下这个碎片化信息环境的时代,很多资源都可以在网络上找到,只取决于你愿不愿意找或是找的方法对不对了。很多朋友不是没有资料,大多都是有几十上百个G,但是杂乱无章,不知道怎么看从哪看起,甚至是看后就忘。ndk示例 ndk入门。

2301_82244182的博客 504

2024年安卓最新2024大厂Android面试题汇总(一)(含答案)_安卓大厂面试题,面试必背

这里笔者分享一份自己收录整理上述技术体系图相关的几十套腾讯、头条、阿里、美团等公司2021年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。很多人在刚接触这个行业的时候或者是在遇到瓶颈期的时候,总会遇到一些问题,比如学了一段时间感觉没有方向感,不知道该从那里入手去学习,对此我整理了一些资料,需要的可以免费分享给大家。希望本篇文章能为你带来帮助,如果有问题,请在评论区留言。

2401_84544531的博客 989

2019年安卓最新面试题汇总

转载请注明出处:https://blog.youkuaiyun.com/qq_30875213/article/details/89529597 以下是安卓面试经常会碰到的面试题,现在我把它整理下来,也算对知识点的一个梳理,也希望能帮到其他的安卓从业者。 安全部分 1.对称加密和非对称加密有什么区别 对称加密:客户端和服务端用的是相同的密匙。 非对称加密:客户端用公匙加密,服务端用私钥解密,使...

qq_30875213的博客 528

2024年安卓最新android面试题2024,面试要掌握这几个关键点!大厂面试题汇总(1),蚂蚁金服前端面试题

总而言之,成功是留给准备好的人的。无论是参加什么面试,都要做好充足的准备,注意好面试的礼仪和穿着,向面试官表现出自己的热忱与真诚就好。即使最后没有过关,也要做好经验的总结,为下一次面试做好充足准备。这里我为大家准备了一些我在面试后整理的面试专题资料,除了面试题,还总结出了互联网公司Android程序员面试涉及到的绝大部分面试题及答案,并整理做成了文档,以及系统的进阶学习视频资料分享给大家,希望能帮助到你面试前的复习,且找到一个好的工作,也节省大家在网上搜索资料的时间来学习。

2301_82243733的博客 807

2024年安卓最新Android Http请求方法汇总(1),h5常见面试题

如果你看到了这里,觉得文章写得不错就给个赞呗?如果你觉得那里值得改进的,请给我留言。一定会认真查询,修正不足。最后针对Android程序员,我这边给大家整理了一些资料,包括不限于高级UI、性能优化、移动架构师、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter等全方面的Android进阶实践技术;希望能帮助到大家,也节省大家在网上搜索资料的时间来学习,也可以分享动态给身边好友一起学习!

2401_84563320的博客 749

2024最新Android开发重要面试题汇总

Intent是Android中用于组件间通信的一种机制,它可以传递数据和请求操作。Intent Filter则用于定义BroadcastReceiver、Activity或Service可以接收的Intent,当发送的Intent匹配某个组件的Intent Filter时,系统会调用该组件。SQLite是一个轻量级的数据库,被广泛用于Android应用中进行数据持久化。开发者可以通过SQL语句创建、查询、更新和删除数据库中的数据。自定义View是开发者根据需求自定义的View组件。

m0_64365896的博客 929

【必看】《2023最新Android中高级面试题汇总》它来了~_安卓 中高级(1)

改变人生,没有什么捷径可言,这条路需要自己亲自去走一走,只有深入思考,不断反思总结,保持学习的热情,一步一步构建自己完整的知识体系,才是最终的制胜之道,也是程序员应该承担的使命。你不踏出去一步,永远不知道自己潜力有多大,千万别被这个社会套在我们身上的枷锁给捆住了,30岁我不怕,35岁我一样不怕,去做自己想做的事,为自己拼一把吧!不试试怎么知道你不行呢?

2301_82243733的博客 68

【2023最新Android中高级面试题汇总】备战2023金三银四,跳槽专属,一起进大厂!

2023已经来临,一年一度的“金三银四”也即将到来,想要跳槽的程序员们跃跃欲试。如果想要跳槽成功,就必须做好充分的准备,做好安排打算。也许有的人已经万事俱备,只欠东风,而有的人还在临时抱佛脚,忙忙碌碌。那么重要的来了,怎么去准备面试呢?为了帮助更多朋友们跳槽,找到满意的工作,小编在这里免费分享一份《2023最新Android中高级面试题汇总Android面试大致可以分为Java、Android、计算机网络、算法和数据结构等板块。

Android_XG的博客 640
上一篇: android自定义控件跟随手指移动及view事件分发机制
下一篇: Android studio v4 v7 包冲突 解决方案
ZyClient
博客等级 码龄10年 29粉丝 60原创
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值