Android题

一、指标:理解synchronized的含义、明确synchronized关键字修饰普通方法、静态方法和代码块时锁对象的差异。

Java synchronized关键字
问题:
有如下一个类A
class A {
    public synchronized void a() {}
    public synchronized void b() {}
}
然后创建两个对象
A a1 = new A();
A a2 = new A();
然后在两个线程中并发访问如下代码:
Thread1    Thread2
a1.a();        a2.a();

请问二者能否构成线程同步?

答:不能构成线程同步。

如果A的定义是下面这种呢?

class A {
    public static synchronized void a() {}
    public static synchronized void b() {}
}
答:会构成线程同步。

解析:
    Java的多线程中同步机制会对资源进行加锁,保证在同一时间只有一个线程可以操作对应资源,避免多线程同时访问相同资源而引发冲突。而Java中的Synchronized关键字就是用于实现同步机制的。
    Synchronized定义:Java关键字,用于给对象和方法或代码块进行加锁,加锁的对象和方法或代码块只能有一个线程进行访问(需要持有同一把锁才可以),其他线程如果想访问它需要等待这个线程释放锁后才可以访问。
    同步的原理:就是将部分操作功能数据的代码进行加锁。
同步的前提:
      1.必须要有两个或两个以上的线程。
      2.必须是多个线程使用同一个锁。
同步的好处与弊端:
      好处:解决了线程的安全问题。
      弊端:较为消耗资源,同步嵌套后容易死锁。

第一种情况是属于方法锁(也叫对象锁),类的实例对象可以有多个,每个实例对象都是一个锁,所以第一种的情况是互不干扰的,持有的锁不同也就不会构成线程的同步。就像是两个不同的锁,一个人在开一个锁,另一个人也可以去看另一把锁,他们是没有关联的。如果想要第一种情况构成线程的同步,就需要把这个定义为单例的。

第二种情况是属于类锁,每一个类只有一个class对象,所以它们在被静态修饰后持有的是同一把锁,也就构成了线程的同步,一个线程进去了,其他就需要进行等待,什么时候进去的线程释放了这个锁其他的线程才可以进去。就像现在只有一把锁,一个人在开锁,另一个人只能等着,不可能同时去开。

同步的方式有两种:
    1.同步块:需要自己指定锁(如:synchronized(this)或synchronized(xxx.class))
    2.同步方法:同步方法分为静态和非静态,静态的是同时使用static和synchronized进行修饰;非静态的是只有用synchronized修饰

为什么要有同步块的存在呢?
答:因为同步可能会在高并发时候造成系统的崩溃,而同步块可以降低崩溃的几率。同步块比直接在方法上同步要对效率影响更小,因为它的覆盖率比同步方法小,并且同步块我们可以指定一个对象当作锁,比方法的同步更灵活。

Static修饰符:用来修饰成员(成员变量和成员函数),静态是在对象之前存在的。
特点:
      1.可以实现对象中数据的共享
      2.可以使用 类名. 直接调用
      3.随着类的加载而加载,消失而消失。优于对象的存在
注意:
      1.被静态修饰的方法只能访问静态成员
      2.静态方法中不能使用this,super关键字
      3.对象特有的数据是不能被静态修饰的(如果被静态修饰了特有数据就变成共享数据了)

二、问题:清晰理解Service

    Service是Android四大组件之一,它主要用于在后台处理一些耗时的逻辑计算,或去执行某些需要长时间运行的任务。
    Service有两种方式启动,分别是startService和bindService。
(注:如果要执行耗时操作需要在服务中在单开一个线程来执行,Service是不提供用户界面的,也就是说我们是用眼睛看不到的)

第1问.Service的start和bind状态有什么区别?

答:
  start(启动状态):
      1.使用场景:主要用于执行后台计算或长期在后台运行,如:音乐播放。
      2.生命周期:onCreate()->onStartCommand()->onDestroy()。(多次调用start,会重复执行onStartCommand()方法)
      3.使用这个方式启动服务,调用者与服务直接没有关系,就是说启动它的那个Activity不能与这个服务进行交互,这个Activity就算销毁了服务仍然可以运行。
      4.启动方式:startService()。
      5.停止方式:外部调用Context.stopService(service)或自身调用stopSelf()(IntentService会自动调用stopSelf方法)。

  bind(绑定状态):
      1.使用场景:主要用于其他组件和Service进行交互,包括IPC(进程间通讯)。
      2.生命周期:onCreate()->onBind()->onUnbind()->onDestroy()(多次调用bind,只会执行一次一次onBind()方法)。
      3.使用这个方式启动服务,调用者与服务是相关联的,如果调用的Activity退出了,服务即被销毁,但这种绑定状态的启动可以和Activity进行交互。
      4.启动方式:bindService(service, conn, flags)。
      5.停止方式:Context.unbindService(conn)或启动它的Activity销毁。

(注:多个组件是可以绑定在一个Service上的,这种情况当所有组件解绑后,Service才会销毁。bindService(service, conn, flags)中第一个参数明确指定绑定的service的Intent;第二个参数是ServiceConnection对象;第三个参数是一个标志,它表明绑定中的操作,不想指定设为0即可。)

第2问.同一个Service,先startService在bindService,如何把它停止?

答:需要这两种启动方式的停止方式都进行调用,如果只是调用了stopService(),Service还在绑定状态。如果只是调用了unbindService(),会有一个与调用者没有关联的Service存在。如果想要彻底销毁只有既调用stopService(),也调用unbindService()。
(不管startService调用几次只需要调用一次stopService(stopSelf);如果不同组件调用n次bindService,必须调用n次unbindService方法)

第3问.你有注意到Service的onStartCommand方法的返回值吗?不同返回值有什么区别?

答:Service的onStartCommand方法的返回值主要有一下几种:
    1.START_STICKY = 1;
      系统在调用完onStartCommand()方法后,如果当前服务被kill。系统会重新创建这个服务并调用onStartCommand()方法,但它不会保留之前传递的Intent对象。如果此期间没有任何启动命令被传递到service,参数的Intent将为null。这个适用于不执行命令的媒体播放器(或类似的)。

    2.START_NOT_STICKY = 2;
      如果在执行完onStartCommand()后,服务被异常kill掉,系统不会自动重启该服务。只有在接受到新的Intent对象,这个服务才会被重新创建。这个可以用来避免在不需要的时候运行服务。

    3.START_REDELIVER_INTENT = 3;
      在执行onStartCommand()后,如果服务被kill,系统会自动重启该服务,并保留之前传递的Intent对象,可以在该服务被销毁前一直保留Intent对象数据。这个适用于需要立即恢复正在执行的工作服务,如:文件下载。

    4.START_STICKY_COMPATIBILITY = 0;
      这个是START_STICKY的兼容版本,在服务被kill掉后,服务虽然被重建,但没有重启。所以,这个不保证服务被终止后一定能重启。

(注:START_STICKY和START_REDELIVER_INTENT可以解决因内存资源不足而被杀死的问题,直接在onStartCommand()方法中返回)

第4问.Service的生命周期方法onCreate、onStart、onBind等运行在哪个线程?

答:
    它们都是运行在主线程的。所以,如果在服务中直接做耗时操作也会出现ANR异常,要新开一个线程来做耗时操作。
    当Service运行的是本地服务,那么对应的Service运行在主进程的main线程上。当Service运行的是远程服务,那么对应的Service运行在独立进程的main线程上。

三、话题:理解Activity的启动模式。

1、Activity的启动模式有哪几种,分别用于什么场景?

Activity的启动模式有四种:

1.standard(标准模式):它是系统默认的启动模式,使用这个模式每次启动都会创建一个新的实例,不管这个
实例是否存在,是否在栈顶。被创建的实例符合典型情况下Activity的生命周期。并且这种模式一个任务栈可以
有多个实例,每个实例也可以属于不同的任务栈,而且是谁启动了这个Activity,这个Activity就运行在启动
它的这个Activity所在的任务栈中。

使用场景:通常情况的Activity都是使用这个模式启动。

注1:一个任务栈中如果没有任何Activity时候,该任务栈就会被回收。使用ApplicationContext去启动standard模式下的Activity会报错。因为,这个模式下的Activity会默认进入启动它的Activity所属任务栈中。但非Activity类型的Context并没有任务栈,解决方法就是为待启动的Activity指定FLAG_ACTIVITY_NEW_TASK标记位(这个时候实际上是以singleTask模式启动)或直接使用singleTask模式。

注2:任务栈是一种“后进先出”的栈结构。

2.singleTop(栈顶复用模式或栈顶单例模式):
这个模式下,如果新的Activity已经位于栈顶,那么这个Activity就不会被创建,同时它的onNewIntent方法
会被调用,通过此方法的参数我们可以取出当前的请求信息(因为这里可以得到新的Intent)。如果新的
Activity实例已经存在但没有位于栈顶,那么仍会创建新的实例。如果栈顶不存在该Activity实例,则情况与
standard模式相同,创建新的实例。

使用场景:适用于接收通知启动的内容显示页面。
3.singleTask(栈内复用模式或栈内单例模式):
这种模式下,只要该Activity在一个栈中存在,启动时候就不会创建新的实例,并会调用onNewIntent函数。
如果该Activity不在栈顶就会导致它之上的所有Activity全部出栈(也就是都会移除栈)。如果不存在,就会创
建新的实例。

使用场景:程序的入口,也可以是程序的主页(如果返回主页的情况)。
4.singleInstance(单实例模式或全局唯一模式):
这个模式具有singleTask模式所有特性外,还有一点不同的就是这个模式下系统中只有一个该Activity实例,
也就是此模式的Activity只能单独位于一个任务栈中,所以就会单独占用一个任务栈,因为也是有栈内复用特性
所以不会重新创建实例。

使用场景:应用下载更新包,闹铃等。

2、清晰地描述下onNewIntent和onConfigurationChanged这两个生命周期方法的场景?

答:

onNewIntent生命周期方法的场景是Activity要提供多种方式调用启动,并且多个调用希望只有一个Activity
实例存在,就需要Activity的onNewIntent(Intent intent)函数。
只要Activity中加入自己的onNewIntent实现,在加上清单文件中对Activity设置
lanuchMode="singleTask"就可以使用。当调用onNewIntent时候需在里面使用setIntent(intent)赋值
给Activity的Intent。否则,后续的getIntent()就会获取以前的Intent。
onConfigurationChanged这个方法并不是只有屏幕方向改变时候才触发,在打开或隐藏键盘时候也会。
声明这个方法后在进行屏幕旋转或打开隐藏键盘时候就不会在走onCreate方法。否则,就会走onCreate方法。

四、话题:关于startActivityForResult

1、startActivityForResult的使用场景是什么?onActivityResult回调里面的resultCode和requestCode含义是什么?

答:

     startActivityForResult(intent,requestCode)的使用场景一般是两个Activity需要进行交互的时
候使用,如一个Activity需要用到它跳转到的Activity中所返回的数据。
     常用的场景就是做注册功能的时候,在注册界面用户需要选择他所在城市,用户在点击那个文本框后跳转到另
一个选择城市的界面,在选择好后把选择好的城市数据返回到之前的界面。然后,我得到返回的数据并把它显示到
TextView上。返回的数据我们可以通过在跳转的那个Activity里实现onActivityResult方法来得到。
     onActivityResult的resultCode参数含义是用来判断返回的数据来自哪个Activity,如果返回的数据不
同,我们可以根据这个来进行区分。requestCode的含义是用来识别请求来源的,可以用来区分哪个模块回传的数据。

注:如果要想得到返回的数据一定是使用setResult返回的,如果使用startActivity跳转回这个Activity是在onActivityResult中得不到数据的。

2、Activity A启动B的时候,在B中何时该执行setResult ?setResult可以位于Activity的finish方法之后吗?

答:

     在B中应在除onPause、onStop、onDestroy三个方法并在finish之前调用。
     根据查看finish的源码可以知道setResult不可以位于finish之后,因为Activity的result是在
finish后才被返回。不在onPause、onStop、onDestroy三个调用是因为这三个方法不一定是在finish之前的。
测试打印的log:
12-07 15:38:23.397 4514-4514/ E/SecondActivity.this: onPause
12-07 15:38:23.411 4514-4514/ E/FirstActivity.this: onActivityResult
12-07 15:38:23.414 4514-4514/ E/FirstActivity.this: onRestart
12-07 15:38:23.415 4514-4514/ E/FirstActivity.this: onStart
12-07 15:38:23.415 4514-4514/ E/FirstActivity.this: onResume
12-07 15:38:23.737 4514-4514/ E/SecondActivity.this: onStop
12-07 15:38:23.737 4514-4514/ E/SecondActivity.this: onDestroy
根据这个log可以确定onActivityResult方法是在你返回的那个界面onStop与onDestroy方法之前调用的,所以
setResult这个方法放在这两个方法里是没有意义的。我把setResult放到onPause里也是不可以的,得不到数据。

注:在用户按Back返回键返回的时候会自动调用Activity的finish,并设置resultCode为RESULT_CANCELED(也就是取消的意思),所以你也得不到数据。解决方法是在Activity重写onBackPressed方法在里面super.onBackPressed之前使用setResult()。

五、话题:关于View的知识

1、View的getWidth()和getMeasuredWidth()有什么区别吗?

答:


2、如何在onCreate()中拿到View的宽度和高度?

答:


六、话题:关于Gradle的知识

1、如何理解Gradle?Grade在Android的构建过程中有什么作用?

答:

2、实践如下问题

问题:我们都知道,Android中时常需要发布渠道包,需要将渠道信息附加到apk中,然后在程序启动的时候读取渠道信息。仍然拿VirtualAPK来举例,
链接:GitHub - didi/VirtualAPK: A powerful and lightweig...。 动态指定一个渠道号(比如1001),那么构建的apk中,请在它的AndroidManifest.xml文件里面的application节点下面添加如下meta-data,请写一段Gradle脚本来自动完成: <application android:allowBackup="false" android:supportsRtl="true"> <meta-data android:name=“channel" android:value=“1001" /> </application> 要求:当通过如下命令来构建渠道包的时候,将渠道号自动添加到apk的manifest中。 ./gradlew clean assembleRelease -P channel=1001
PS:禁止使用manifestPlaceholders
答:

七、话题:关于序列化的知识

1、Parcelable和Serializable有什么用,它们有什么差别?

答:

2、自定义一个类让其实现Parcelable,大致流程是什么?

答:

八、话题:Java基础知识学习

1、Java中有哪几种引用?它们的含义和区别是什么?

答:

2、请用Java实现一个线程安全且高效的单例模式。

答:

九、话题:Android中的ClassLoader

1、Android中有哪几种ClassLoader?它们的作用和区别是什么?

答:

2、简述ClassLoader的双亲委托模型

答:

3、简述双亲委托模型在热修复领域的应用

答:

十、话题:Binder

1、什么是Binder?简单描述下它的工作过程和使用场景

答:

十一、话题:Okhttp和Retrofit

1、介绍这两个框架的作用和联系

答:

十二、话题:从源码的角度描述下Activity的启动过程

答:

十三、话题:简单描述下jvm的垃圾回收策略,比如引用计数、标记清除等策略

答:

十四、话题:用过RxJava和RxAndroid吗?RxAndroid切换线程是怎么实现的呢?

答:

十五、话题:进程保活

答:

十六、话题:四大组件

Android四大组件中每个组件的作用是什么?它们都可以开启多进程吗?

答:

十七、话题:AIDL

Android中AIDL的作用是什么?它所支持的参数类型是?默认情况下AIDL的调用过程是同步还是异步?如何指定AIDL为异步调用?

答:

十八、话题:线程池

Android中的线程池有哪些?它们的区别是什么?为什么要使用线程池?

答:

十九、话题:网络协议

网络的五层划分是什么?TCP和UDP的区别是什么?简述TCP的三次握手过程。

答:

二十、话题:MVC、MVP和MVVM

画出这三种开发模式的设计图,并给出它们的适用场景和优缺点。

答:

二十一、话题:AndroidStudio build过程

AndroidStudio点击build按钮后,AndroidStudio就会编译整个项目并将apk安装到手机上,请详细描述下这个过程的背后到底发生了什么?

答:

二十二、话题:大尺寸图片加载问题 这是一个经典的面试题: 给定一个1000 x 20000(宽1000px,高20000px)的大图,如何正常加载显示且不发生OOM ?

答:

二十三、话题:设计模式

如何理解设计模式的几大基本原则(单一职责、开闭原则等),你平时在工作中都用过哪几种模式,可以举一个工作中的例子吗?它解决了你的什么问题?

答:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335

推荐阅读更多精彩内容