JingBin's Home

一次面试题的简单整理

牛客网:https://www.nowcoder.com/9070733

选择题

1、广播的注册方式

1
2
3
4
5
6
<!--广播注册-->
<receiver android:name=".SmsBroadCastReceiver">
<intent-filter android:priority="20">
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>

2、android 关于service生命周期的onCreate()和onStart()说法正确的是?(AD)

  • A.当第一次启动的时候先后调用onCreate()和onStart()方法
  • B.当第一次启动的时候只会调用onCreate()方法
  • C.如果service已经启动,将先后调用onCreate()和onStart()方法
  • D.如果service已经启动,只会执行onStart()方法,不在执行onCreate()方法


3.在android中使用Menu时可能需要重写的方法有?(AC

  • A.onCreateOptionsMenu()
  • B.onCreateMenu()
  • C.onOptionsItemSelected()
  • D.onItemSelected()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public class MainActivity extends Activity {  
  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
    }  
  
    @Override  
    public boolean onCreateOptionsMenu(Menu menu) {  
        // Inflate the menu; this adds items to the action bar if it is present.  
        getMenuInflater().inflate(R.menu.activity_main, menu);  
        return true;  
    }  
  
    @Override  
    public boolean onOptionsItemSelected(MenuItem item) {  
        // TODO Auto-generated method stub  
        switch(item.getItemId()){  
           case R.id.menu_about:             
               Toast.makeText(MainActivity.this""+"关于", Toast.LENGTH_SHORT).show();  
               break;  
           case R.id.menu_settings:  
                 
               Toast.makeText(MainActivity.this""+"设置", Toast.LENGTH_SHORT).show();  
               break;  
           case R.id.menu_quit:  
                 
               Toast.makeText(MainActivity.this""+"退出", Toast.LENGTH_SHORT).show();  
               break;  
           default:  
               break;  
           }  
//         Toast.makeText(MainActivity.this, ""+item.getItemId(), Toast.LENGTH_SHORT).show();  
      
        return super.onOptionsItemSelected(item);  
    }

4.android中下列属于intent的作用是(C)

  • A.实现应用程序间的数据共享
  • B.是一段长的生命周期,没有用户界面的程序,可以保持应用在后台运行,而不会因为切换页面而消失
  • C.可以实现界面间的切换,可以包含动作和动作数据,连接四大组件的纽带
  • D.处理一个应用程序整体性的工作

不同activity间的数据共享


5.如果在Activity中对一些资源以及状态进行保存操作,最好是在生命周期的哪个函数中进行呢?(A)

  • A.onPause()
  • B.onCreat()
  • C.onResume()
  • D.onStart()

暂停的时候保存。在onPause()时候保存状态,才能保存用户最终的使用状态。


6.android 工程最后生成的工程文件是?

1
2
3
4
app\build\intermediates文件夹里是也
intermediates:是一个中间人,调节人的意思,
java源文件转为class文件后再转为dex文件,最后生成apk
这里面class文件夹就被存放在intermediates文件夹里面

填空题

1.android常用的五种布局FrameLayout(框架布局),LinearLayout(线性布局),RelativeLayout(相对布局),AbsoluteLayout(绝对布局),TableLayout(表格布局)


2.Android四大基本组件分别是Activity,Service服务,Content Provider内容提供者,BroadcastReceiver广播接收器。


3.android 中 service 的实现方法是: ___
start 和 bind


4.Android的系统体系结构分为四层,自顶向下分别是

  • 应用程序(Applications)
  • 应用程序框架(Application Frameworks)
  • 系统运行库与Android运行环境(Libraris & Android Runtime)
  • Linux内核(Linux Kernel)

5.AsyncTask是什么?AsyncTask的使用方法?
android的类AsyncTask对线程间通讯进行了包装,提供了简易的编程方式来使后台线程和UI线程进行通讯:后台线程执行异步任务,并把操作结果通知UI线程。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
class DownloadTask extends AsyncTask<Integer, Integer, String>{
//后面尖括号内分别是参数(例子里是线程休息时间),进度(publishProgress用到),返回值 类型
@Override
protected void onPreExecute() {
//第一个执行方法
super.onPreExecute();
}
@Override
protected String doInBackground(Integer... params) {
//第二个执行方法,onPreExecute()执行完后执行
for(int i=0;i<=100;i++){
pb.setProgress(i);
publishProgress(i);
try {
Thread.sleep(params[0]);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return "执行完毕";
}
@Override
protected void onProgressUpdate(Integer... progress) {
//这个函数在doInBackground调用publishProgress时触发,虽然调用时只有一个参数
//但是这里取到的是一个数组,所以要用progesss[0]来取值
//第n个参数就用progress[n]来取值
tv.setText(progress[0]+"%");
super.onProgressUpdate(progress);
}
@Override
protected void onPostExecute(String result) {
//doInBackground返回时触发,换句话说,就是doInBackground执行完后触发
//这里的result就是上面doInBackground执行后的返回值,所以这里是"执行完毕"
setTitle(result);
super.onPostExecute(result);
}
}

AsyncTask 的使用方法和工作原理


6.什么是AIDL?AIDL是如何工作的?

AIDL: Android Interface Definition Language

AIDL是一种IDL语言,用于生成可以在Android设备上两个进程之间进行进程间通信(interprocess communication, IPC)的代码。如果在一个进程中(例如Activity)要调用另一个进程中(例如Service)对象的操作,就可以使用AIDL生成可序列化的参数。

AIDL是一种接口定义语言,用于生成可在Android设备上两个进程之间进行进程间通信(IPC)的代码。
高度概括AIDL的用法,就是服务端里有一个Service,给与之绑定(bindService)的特定客户端进程提供Binder对象。客户端通过AIDL接口的静态方法asInterface 将Binder对象转化成AIDL接口的代理对象,通过这个代理对象就可以发起远程调用请求了。

引:https://blog.csdn.net/tellh/article/details/55100167


7.Android中如何避免OOM异常?

Java.lang.OutOfMemoryError : bitmap size exceeds VM budget。

OOM 内存溢出,想要避免OOM 异常首先我们要知道什么情况下会导致OOM 异常。
1、图片过大导致OOM
2、界面切换导致OOM
3、在页面切换时尽可能少地重复使用一些代码
3、查询数据库没有关闭游标
4、构造Adapter 时,没有使用缓存的convertView
5、Bitmap 对象不再使用时调用recycle()释放内存
6、其他
Android 应用程序中最典型的需要注意释放资源的情况是在Activity 的生命周期中,在onPause()、onStop()、onDestroy()方法中需要适当的释放资源的情况。使用广播没有注销也会产生OOM。

https://blog.csdn.net/jiayi_yao/article/details/51107960


8.什么是ANR 如何避免它?

ANR:Application Not Responding

不同的组件发生ANR的时间不一样,Activity是5秒,BroadCastReceiver是10秒,Service是20秒。
解决方案:
1、将所有耗时操作,比如访问网络,Socket 通信,查询大量SQL 语句,复杂逻辑计算等都放在子线程中去,然后通过handler.sendMessage、runonUITread、AsyncTask 等方式更新UI,以确保用户界面操作的流畅度。
2、如果耗时操作需要让用户等待,那么可以在界面上显示进度条。

https://blog.csdn.net/m_xiaoer/article/details/62438802



9.NDK 与 JNI 是什么?

JNI: Java Native Interface,即 Java本地接口
NDK: Native Development Kit,是 Android的一个工具开发包

JNI介绍
定义:Java Native Interface,即 Java本地接口
作用: 使得Java 与 本地其他类型语言(如C、C++)交互
即在 Java代码 里调用 C、C++等语言的代码 或 C、C++代码调用 Java 代码

特别注意:
JNI是 Java 调用 Native 语言的一种特性
JNI 是属于 Java 的,与 Android 无直接关系

实现步骤:
1.在Java中声明Native方法(即需要调用的本地方法)
2.编译上述 Java源文件javac(得到 .class文件)
3.通过 javah 命令导出JNI的头文件(.h文件)
使用 Java需要交互的本地代码 实现在 Java中声明的Native方法
如 Java 需要与 C++ 交互,那么就用C++实现 Java的Native方法
4.编译.so库文件
5.通过Java命令执行 Java程序,最终实现Java调用本地代码

NDK介绍
定义:Native Development Kit,是 Android的一个工具开发包
NDK是属于 Android 的,与Java并无直接关系

作用:快速开发C、 C++的动态库,并自动将so和应用一起打包成 APK
即可通过 NDK在 Android中 使用 JNI与本地代码(如C、C++)交互

https://blog.csdn.net/carson_ho/article/details/73250163


10.Android Fragment 生命周期图

Fragment生命周期图.png

fragments的大部分状态都和activitie很相似,但fragment有一些新的状态。

onAttached() —— 当fragment被加入到activity时调用(在这个方法中可以获得所在的activity)。
onCreateView() —— 当activity要得到fragment的layout时,调用此方法,fragment在其中创建自己的layout(界面)。
onActivityCreated() —— 当activity的onCreated()方法返回后调用此方法
onDestroyView() —— 当fragment中的视图被移除的时候,调用这个方法。
onDetach() —— 当fragment和activity分离的时候,调用这个方法。

一旦activity进入resumed状态(也就是running状态),你就可以自由地添加和删除fragment了。因此,只有当activity在resumed状态时,fragment的生命周期才能独立的运转,其它时候是依赖于activity的生命周期变化的。

http://www.cnblogs.com/purediy/p/3276545.html


11.Android5.0和6.0之后有哪些新控件?
Android5.0和6.0之后新增的控件,在项目中使用的时候,可分为三大类:

  • 1、第一类是内核提供的控件,位于SDK的android.jar中。
    这个与系统版本有关,每个版本的android.jar是固定的,有在该内核中定义的控件才能正常调用,没在内核中定义的控件在运行时会扔出类找不到的异常。比如水波图形RippleDrawable和矢量图形VectorDrawable,这两个控件在Android5.0之后的系统内核中提供,所以只有系统版本不低于5.0的手机才能使用它们,运行4.*系统的手机是无法正常调用这两个控件的。

  • 2、第二类是v4兼容库提供的控件,位于SDK的android-support-v4.jar中。
    v4库默认会被编译进App的安装包,所以它不需要系统内核支持,可直接运行在4.0之后的所有系统上,并且App工程无需手工导入v4库。使用v4控件唯一需要注意的地方,是布局文件中要引用完整路径的控件名称,如抽屉布局android.support.v4.widget.DrawerLayout、下拉刷新布局android.support.v4.widget.SwipeRefreshLayout等等。

  • 3、第三类是v7兼容库和design库,它们有各自的库工程,开发者要在App工程中手工导入用到的兼容库。
    v7与design库导入App工程后,编译出来的App即可兼容4.*的系统。使用v7与design库的控件,类似于使用自定义控件,不但要在布局文件中引用完整路径的控件名称,还要在根布局声明命名空间(即添加属性xmlns:app=http://schemas.android.com/apk/res-auto),然后方可使用这些控件的自定义属性。这部分控件数量最多,实现的界面特效最丰富,而且互相之间存在依赖关系,如design库依赖于appcompat-v7库,部分design控件如NavigationView还依赖于recyclerview-v7库,所以若要正确使用design库的控件,往往得同时导入好几个相关的兼容库。

https://blog.csdn.net/aqi00/article/details/59108336

编程题

1.写一个自己的Handler,对消息进行处理


2.写一个冒泡排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class bubbleSort {
public bubbleSort(){
int a[]={49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15,35,25,53,51};
int temp=0;
for(int i=0;i<a.length-1;i++){
for(int j=0;j<a.length-1-i;j++){
if(a[j]>a[j+1]){
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
for(int i=0;i<a.length;i++)
System.out.println(a[i]);
}
}


3.快速排序
基本思想:选择一个基准元素,通常选择第一个元素或者最后一个元素,通过一趟扫描,将待排序列分成两部分,一部分比基准元素小,一部分大于等于基准元素,此时基准元素在其排好序后的正确位置,然后再用同样的方法递归地排序划分的两部分。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public class quickSort {
inta[]={49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15,35,25,53,51};
public quickSort(){
quick(a);
for(int i=0;i<a.length;i++)
System.out.println(a[i]);
}
public int getMiddle(int[] list, int low, int high) {
int tmp = list[low]; //数组的第一个作为中轴
while (low < high) {
while (low < high && list[high] >= tmp) {
high--;
}
list[low] = list[high]; //比中轴小的记录移到低端
while (low < high && list[low] <= tmp) {
low++;
}
list[high] = list[low]; //比中轴大的记录移到高端
}
list[low] = tmp; //中轴记录到尾
return low; //返回中轴的位置
}
public void _quickSort(int[] list, int low, int high) {
if (low < high) {
int middle = getMiddle(list, low, high); //将list数组进行一分为二
_quickSort(list, low, middle - 1); //对低字表进行递归排序
_quickSort(list, middle + 1, high); //对高字表进行递归排序
}
}
public void quick(int[] a2) {
if (a2.length > 0) { //查看数组是否为空
_quickSort(a2, 0, a2.length - 1);
}
}
}

https://blog.csdn.net/pzhtpf/article/details/7560294

kotlin了解一下

kotlin中国
kotlin.jpg