面试题整理

万物云

1、多进程访问static变量

所以,父进程和子进程中的变量是不可以被共享的,在程序员和进程的角度来看,每个进程的内存空间都是属于它自己的。

2、子线程弹出toast

Looper.prepare();
Toast.makeText(getBaseContext(), "text", Toast.LENGTH_LONG).show();
Looper.loop();

runOnUiThread()

3、handler.postDelayed函数延时执行计时是否准确

当上一个消息存在耗时任务的时候,会占用延时任务执行的时机,此时是不准确的。那么如何准确执行延时任务呢,可以开启一个HandlerThread为一个专门的唯一的延时消息服务。(或许你会说成本很大,但是我没想到啥好办法,有好办法可以留言

4、进程与线程的区别:

(1)调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位
(2)并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可并发执行
(3)拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源.
(4)系统开销:在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销。

一个进程至少需要有一个线程,不能没有线程

5、堆和栈的区别

1、存储在堆中的对象是全局可以被访问的,然而栈内存不能被其他线程所访问;
2、栈内存是生命周期很短的,然而堆内存的生命周期从程序的运行开始到运行结束;3、和堆内存比,栈内存要小的多,因为明确使用了内存分配规则,和堆内存相比栈内存非常快。”

道通科技

1、fragment比activity多了几个生命周期

onCreate 和 onDestory的区别
fragment的onCreate 包含 onAttch onCreate onCreateView onActivityCreated
onDestory包含 onDestoryView onDestory onDetch

2、介绍四大组件,怎么使用

3、Android分层

1)、Linux Kernel:负责硬件的驱动程序、网络、电源、系统安全以及内存管理等功能。

2)、 Libraries和Android Runtime:Libraries:即C/C++函数库部分,大多数都是开放源代码的函数库,例如WebKit,该函数库负责Android网页浏览器的运行,例如标准的C函数库Libc、OpenSSL、SQLite等,当然也包括支持游戏开发2D SGL和3D OpenGL | ES,在多媒体方面有MediaFramework框架来支持各种影音和图形文件的播放与显示,例如MPEG4、H.264、MP3、AAC、AMR、JPG和PNG等众多的多媒体文件格式。Android的Runtime负责解释和执行生成的Dalvik格式的字节码。

3)、Application Framework:(应用软件架构),Java应用程序开发人员主要是使用该层封装好的API进行快速开发。

4)、Applications:该层是Java的应用程序层,

4、jni的原理,jni怎么使用

Jvm封装了各种操作系统实际的差异性的同时,提供了jni技术,使得开发者可以通过java程序(代码)调用到操作系统相关的技术实现的库函数,从而与其他技术和系统交互,使用其他技术实现的系统的功能;同时其他技术和系统也可以通过jni提供的相应原生接口开调用java应用系统内部实现的功能。

JNI是JAVA标准平台中的一个重要功能,它弥补了JAVA的与平台无关这一重大优点的不足,在JAVA实现跨平台的同时,也能与其它语言(如C、C++)的动态库进行交互,给其它语言发挥优势的机会。

Jni对于应用本身来说,可以看做一个代理模式。对于开发者来说,需要使用c/c++来实现一个代理程序(jni程序)来实际操作目标原生函数,java程序中则是jvm通过加载并调用此jni程序来间接地调用目标原生函数。

5、出现anr怎么定位

<1> 日志定位anr的具体位置
log中搜索关键字 "ANR in" ,快速定位出现anr的应用,查看 "Reason"定位anr原因,分析 "CPU usage"信息,查看是否哪个进程占用cpu过高

<2> 分析trace文件
系统在出现anr时,会向文件data/trace/trace.txt写入关键信息,如上述步骤一种app:com.xxx.launcher3所示,trace.txt中会记录该app的相关信息:
查询关键字“com.xxx.launcher3” ,均是关于GC的相关信息,并且tid<线程>总计43个,其中13个在waiting,内存吃不消不断的gc,占用率都在99%,free memery只有5m,经过这样分析,结合app开发,发现app的图片框架和网络框架的线程池初始化是根据4核配置,但是平台是双核,需要进行缩减,优化后出现anr的概率大大下降。

如何避免ANR
1.合理使用 UI 主线程,耗时操作放入其他线程工作;
2.合理使用 Handler 异步消息处理机制来处理其他线程请求。
3.合理使用并遵循 Android 生命周期, 避免在 onCreate() and onResume()做过多的事情;
4.使用一些架构形成规范来避免内存等问题,例如:MVP、RxJava;
5.经常使用工具来检查内存问题,例如:MAT、TraceView、AS 自带等工具;
6.避免加载大图片引起内存不足导致 ANR;
7.避免内存泄露;

中软外包华为手机终端

1、事件分发机制

1、点击事件达到顶级 View(一般是一个 ViewGroup),会调用 ViewGroup 的 dispatchTouchEvent 方法,如果顶级 ViewGroup 拦截事件即 onInterceptTouchEvent 返回 true,则事件由 ViewGroup 处理,
2、这时如果 ViewGroup 的 mOnTouchListener 被设置,则 onTouch 会被调用,否则 onTouchEvent 会被调用。也就是说如果都提供的话,onTouch 会 屏蔽掉 onTouchEvent。
在 onTouchEvent 中,如果设置了 mOnClickListenser,则 onClick 会 被调用。
3、如果顶级 ViewGroup 不拦截事件,则事件会传递给它所在的点击事件链上的子 View,这时子 View 的 dispatchTouchEvent 会被调用。如此循环。

2、jetpack使用

万物云 第二轮

1、http协议

请求报文
POST /lotto/android/v1.0/order-group/queryOrderGroupPersonInfo HTTP/1.1
cache-control: no-cache
Postman-Token: 800ec750-6ee8-4b2b-a879-f5d854115862
Content-Type: application/json
User-Agent: PostmanRuntime/3.0.11-hotfix.2
Accept: /
Host: sitapp.2ncai.com
accept-encoding: gzip, deflate
content-length: 38
Connection: close

{seeType:1,source:1,userId:30}

image.png

响应报文

HTTP/1.1 200
Date: Sat, 11 Aug 2018 04:24:25 GMT
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Connection: close
X-Application-Context: application:test:8160
Server: my_server

{code:200,data:success}

image.png

2、自定义控件

onMeasure,layout,Ondraw

3、喜欢看什么博客

科卫机器人

1、保活方案

1、双进程守护方案(基于onStartCommand() return START_STICKY)
2、监听锁屏广播打开1像素Activity(基于onStartCommand() return START_STICKY)
3、故意在后台播放无声的音乐(基于onStartCommand() return START_STICKY)
4、使用JobScheduler唤醒Service(基于onStartCommand() return START_STICKY)
5、混合使用的效果,并且在通知栏弹出通知

2、jetpack

3、自定义控件

中软面试

1、activity启动模式,哪种可以实现只是启动一个activity

standard
默认模式,可以不用写配置。在这个模式下,都会默认创建一个新的实例。因此,在这种模式下,可以有多个相同的实例,也允许多个相同Activity叠加。
singleTop
可以有多个实例,但是不允许多个相同Activity叠加。即,如果Activity在栈顶的时候,启动相同的Activity,不会创建新的实例,而会调用其onNewIntent方法。
若我意图打开的顺序为B1->B2->B2,则实际打开的顺序为B1->B2(后一次意图打开B2,实际只调用了前一个的onNewIntent方法)

若我意图打开的顺序为B1->B2->B1->B2,则实际打开的顺序与意图的一致,为B1->B2->B1->B2。
singleTask
只有一个实例。在同一个应用程序中启动他的时候,若Activity不存在,则会在当前task创建一个新的实例,若存在,则会把task中在其之上的其它Activity destory掉并调用它的onNewIntent方法。
如果是在别的应用程序中启动它,则会新建一个task,并在该task中启动这个Activity,singleTask允许别的Activity与其在一个task中共存,也就是说,如果我在这个singleTask的实例中再打开新的Activity,这个新的Activity还是会在singleTask的实例的task中。

例如:

若我的应用程序中有三个Activity,C1,C2,C3,三个Activity可互相启动,其中C2为singleTask模式,那么,无论我在这个程序中如何点击启动,如:C1->C2->C3->C2->C3->C1-C2,C1,C3可能存在多个实例,但是C2只会存在一个,并且这三个Activity都在同一个task里面。

但是C1->C2->C3->C2->C3->C1-C2,这样的操作过程实际应该是如下这样的,因为singleTask会把task中在其之上的其它Activity destory掉。

操作:C1->C2 C1->C2->C3 C1->C2->C3->C2 C1->C2->C3->C2->C3->C1 C1->C2->C3->C2->C3->C1-C2

实际:C1->C2 C1->C2->C3 C1->C2 C1->C2->C3->C1 C1->C2

若是别的应用程序打开C2,则会新启一个task。

如别的应用Other中有一个activity,taskId为200,从它打开C2,则C2的taskIdI不会为200,例如C2的taskId为201,那么再从C2打开C1、C3,则C2、C3的taskId仍为201。

注意:如果此时你点击home,然后再打开Other,发现这时显示的肯定会是Other应用中的内容,而不会是我们应用中的C1 C2 C3中的其中一个。

singleInstance

只有一个实例,并且这个实例独立运行在一个task中,这个task只有这个实例,不允许有别的Activity存在。

例如:

程序有三个ActivityD1,D2,D3,三个Activity可互相启动,其中D2为singleInstance模式。那么程序从D1开始运行,假设D1的taskId为200,那么从D1启动D2时,D2会新启动一个task,即D2与D1不在一个task中运行。假设D2的taskId为201,再从D2启动D3时,D3的taskId为200,也就是说它被压到了D1启动的任务栈中。

若是在别的应用程序打开D2,假设Other的taskId为200,打开D2,D2会新建一个task运行,假设它的taskId为201,那么如果这时再从D2启动D1或者D3,则又会再创建一个task,因此,若操作步骤为other->D2->D1,这过程就涉及到了3个task了。

2、事件分发机制,onTouchListen onClickListen

1、点击事件达到顶级 View(一般是一个 ViewGroup),会调用 ViewGroup 的 dispatchTouchEvent 方法,如果顶级 ViewGroup 拦截事件即 onInterceptTouchEvent 返回 true,则事件由 ViewGroup 处理,
2、这时如果 ViewGroup 的 mOnTouchListener 被设置,则 onTouch 会被调用,否则 onTouchEvent 会被调用。也就是说如果都提供的话,onTouch 会 屏蔽掉 onTouchEvent。
在 onTouchEvent 中,如果设置了 mOnClickListenser,则 onClick 会 被调用。
3、如果顶级 ViewGroup 不拦截事件,则事件会传递给它所在的点击事件链上的子 View,这时子 View 的 dispatchTouchEvent 会被调用。如此循环。

3、反射的原理

1、Java 虚拟机可以通过称为运行时类型信息(RTTI, Run Time Type Information)的技术在运行时检查任何类,这是通过一种称为 Class 对象的特殊对象完成的,该对象包含有关类的信息。
2、虚拟机为每个类管理一个独一无二的 Class 对象。也就是说,每个类都有一个 Class 对象实例。在运行程序的时候,JVM 首先需要会去检测所需加载的类的 Class 是否已经完成加载。如果没有加载在 JVM 中,那么 JVM 回去寻找对应类名的 .class 文件,完成对 Class 对象的加载。通过 Class 对象,我们可以实例化对应的 Class 类对象,调用其构造器(Constructor)、调用类的成员方法(Method)、访问或者修改类的成员属性(Field)。通过 AccessibleObject#setAccessible(boolean flag) 可以访问到类的非 public 权限的其他成员,在上文提到通过 AccessibleObject#setAccessible(boolean flag) 可以在程序运行时修改类成员的访问限制。实际上,AccessibleObject#setAccessible(boolean flag) 关闭了权限的访问检查,使得通过 Class#invoke() 可以访问到任意权限的类成员

4、Android几种动画

Frame Animation 帧动画,通过顺序播放一系列图像从而产生动画效果,。图片过多时容易造成OOM(Out Of Memory内存用完)异常。
Tween Animation 补间动画(又叫view动画),是通过对场景里的对象不断做图像变换(透明度、缩放、平移、旋转)从而产生动画效果,是一种渐进式动画,并且View动画支持自定义。
Accribute Animation 属性动画,这也是在android3.0之后引进的动画,在手机的版本上是android4.0就可以使用这个动 画,通过动态的改变对象的属性从而达到动画效果。

补间动画和属性动画的区别
补间动画只是改变了View的显示效果而已,并不会真正的改变View的属性。而属性动画可以改变View的显示效果和属性。举个例子:例如屏幕左上角有一个Button按钮,使用补间动画将其移动到右下角,此刻你去点击右下角的Button,它是绝对不会响应点击事件的,因此其作用区域依然还在左上角。只不过是补间动画将其绘制在右下角而已,而属性动画则不会。

//逐帧动画,需资源文件frame_animation.xml
ImageView img = (ImageView)findViewById(R.id.wheel_image);
img.setBackgroundResource(R.drawable.frame_animation);
AnimationDrawable frameAnimation = (AnimationDrawable) img.getBackground();
frameAnimation.start();

//补间动画,需资源文件tween_animation.xml
ImageView img = (ImageView)findViewById(R.id.wheel_image);
Animation tweenAnimation = AnimationUtils.loadAnimation(this, R.anim.tween_animation);
img.startAnimation(tweenAnimation);

// 属性动画,不需资源文件
ObjectAnimator anim = ObjectAnimator.ofFloat(targetObject, "alpha", 0f, 1f);
anim.setDuration(1000);
anim.start();

恒大高科技

1、jni使用线程
javaVM 代表的是Java虚拟机,所有的工作都是从JavaVM开始
可以通过JavaVM获取到每个线程关联的JNIEnv

一、概述

  JNI编程和Linux上的C/C++编程还是挺相似的,每次java调用JNI中的函数时都会传入有关JVM的一些参数(如JNIEnv,jobject),每次JNI回调java中的方法时都要通过JVM的有关参数来实现,当在JNI中涉及到多线程的话还是有一些不一样的地方,就是要在子线程函数里使用AttachCurrentThread()和DetachCurrentThread()这两个函数,在这两个函数之间加入回调java方法所需要的代码。

include

include

include

include

include

include

define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "native-activity", VA_ARGS))

define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "native-activity", VA_ARGS))

define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "native-activity", VA_ARGS))

//线程数

define NUMTHREADS 5

//全局变量
JavaVM *g_jvm = NULL;
jobject g_obj = NULL;

void thread_fun(void arg)
{
JNIEnv *env;
jclass cls;
jmethodID mid;

//Attach主线程
if((*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL) != JNI_OK)
{
    LOGE("%s: AttachCurrentThread() failed", __FUNCTION__);
    return NULL;
}
//找到对应的类
cls = (*env)->GetObjectClass(env,g_obj);
if(cls == NULL)
{
    LOGE("FindClass() Error.....");
    goto error;
}
//再获得类中的方法
mid = (*env)->GetStaticMethodID(env, cls, "fromJNI", "(I)V");
if (mid == NULL)
{
    LOGE("GetMethodID() Error.....");
    goto error; 
}
//最后调用java中的静态方法
    (*env)->CallStaticVoidMethod(env, cls, mid ,(int)arg);

error:
//Detach主线程
if((*g_jvm)->DetachCurrentThread(g_jvm) != JNI_OK)
{
LOGE("%s: DetachCurrentThread() failed", FUNCTION);
}

pthread_exit(0);

}

//由java调用以创建子线程
JNIEXPORT void Java_com_nan_thread_MyThreadActivity_mainThread( JNIEnv* env, jobject obj)
{
int i;
pthread_t pt[NUMTHREADS];

for (i = 0; i < NUMTHREADS; i++)
    //创建子线程
    pthread_create(&pt[i], NULL, &thread_fun, (void *)i);

}

//由java调用来建立JNI环境
JNIEXPORT void Java_com_nan_thread_MyThreadActivity_setJNIEnv( JNIEnv* env, jobject obj)
{
//保存全局JVM以便在子线程中使用
(env)->GetJavaVM(env,&g_jvm);
//不能直接赋值(g_obj = obj)
g_obj = (
env)->NewGlobalRef(env,obj);
}

//当动态库被加载时这个函数被系统调用
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void reserved)
{
JNIEnv
env = NULL;
jint result = -1;

//获取JNI版本
if ((*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_4) != JNI_OK)
{
    LOGE("GetEnv failed!");
        return result;
}

return JNI_VERSION_1_4;

}

2、CountDownLatch使用
CountDownLatch的用法
CountDownLatch典型用法1:某一线程在开始运行前等待n个线程执行完毕。将CountDownLatch的计数器初始化为n new CountDownLatch(n) ,每当一个任务线程执行完毕,就将计数器减1 countdownlatch.countDown(),当计数器的值变为0时,在CountDownLatch上 await() 的线程就会被唤醒。一个典型应用场景就是启动一个服务时,主线程需要等待多个组件加载完毕,之后再继续执行。

CountDownLatch典型用法2:实现多个线程开始执行任务的最大并行性。注意是并行性,不是并发,强调的是多个线程在某一时刻同时开始执行。类似于赛跑,将多个线程放到起点,等待发令枪响,然后同时开跑。做法是初始化一个共享的CountDownLatch(1),将其计数器初始化为1,多个线程在开始执行任务前首先 coundownlatch.await(),当主线程调用 countDown() 时,计数器变为0,多个线程同时被唤醒。

3、音视频同步 mediacodec
行车记录仪以声音数据为准,其它以声音数据为准

封装音频编码器
封装视频编码器
使用新封装的视频编码器改造示例2
使用Camera进行视频录制(YUV420SP)并保存为视频流(H.264)
使用AudioRecord进行音频录制(PCM)并保存为音频流(AAC)
使用MediaMuxer混合器合并视频和音频为一路流(H.264)(待完成)

image.png

4、性能优化
一、Android性能优化的方面

针对Android的性能优化,主要有以下几个有效的优化方法:

1.布局优化

2.绘制优化

3.内存泄漏优化

4.响应速度优化

5.ListView/RecycleView及Bitmap优化

6.线程优化

7.其他性能优化的建议

美的Iot

1、推送集成

Android推送集成方案总结

刚做完推送集成方案,记录下坑。
这里记录的特性和使用时针对写blog时采用的sdk的,具体使用流程和限制还请参考官方给出的sdk.

1、推送规则

小米手机用小米推送;
华为手机用华为推送;
其他手机用友盟推送。

2、总体流程

这里写图片描述

2、https的ssl怎么进行加密

在安全的拿到服务器的公钥之后,客户端会随机生成一个对称秘钥,使用服务器公钥加密,传输给服务端,此后,相关的 Application Data 就通过这个随机生成的对称秘钥进行加密/解密,服务器也通过该对称秘钥进行解密/加密:

实现HTTPS加密过程与方式

3、http题目

okhttp有多少线程

Dispatcher内部实现了懒加载的无边界限制的线程池。

// Dispatcher.java
maxRequests = 64 // 最大并发请求数为64
maxRequestsPerHost = 5 //每个主机最大请求数为5
ExecutorService executorService //消费者池(也就是线程池)
Deque readyAsyncCalls: // 异步的缓存,正在准备被消费的(用数组实现,可自动扩容,无大小限制)
Deque runningAsyncCalls //正在运行的 异步的任务集合,仅仅是用来引用正在运行的任务以判断并发量,注意它并不是消费者缓存
Deque runningSyncCalls //正在运行的,同步的任务集合。仅仅是用来引用

道通智能

1、消息分发机制,详细

2、自定义View View优化

3、线程的消息队列

4、tcp和udp的区别

5、单元测试

中软面试

1、哪些设计模式

2、Rxjava使用

3、kotlin使用

4、github阅读代码

软通面试

1、内存,性能怎么优化

2、事件分发机制

3、在工作中遇到难点,怎么解决

4、AIDL怎么使用

5、java集合

海信

蓝牙关于profile协议

jetpack重点了解下

史上最全Android面试题集锦
https://blog.csdn.net/xiangzhihong8/java/article/details/96280254

你可能感兴趣的:(面试题整理)