Android面试题整理

1.arouter原理

ARouter的原理就是所有的moudle都引用ARouter,然后再moudle中去生成一个映射表,然后再把这个映射表传到ARouter中。

1. 映射表生成
@Route(path = xxx/xxx)
public class xxx{
    ......
}

这个会在编译时生成一个文件,在build/intermediates/javac/....../classes/com/alibaba/....../routes/下,会看到一堆生成的.class文件

1.通过注解标记Activity

2.通过反射,找到注解标记的类名和包名,并保存。

3.通过APT技术,根据保存的类名和包名,生成对应的Java代码,这段Java代码的功能就是把activity.class存入路由表,也就是HashMap。

4.不同业务module需要跳转到对应的Activity时,直接从HashMap中取出对应的activity.class,就可以实现跳转。

注解:是一种接口,程序可以反射来获取指定元素的对象,通过注解对象获取注解里面源数据
编译:将java文件编译成.class文件过程
运行时:java虚拟机执行.class文件过程

什么是反射  --》内存(方法区+堆)
在运行状态中,对任意一个类,都能知道这个类的所有属性和方法。对任意一个对象都能调用他的任意一个方法和属性
方法区:存放了类信息,静态变量,全局变量
堆区:存储对象实例

结合例子说明:
join:等待线程运行结束  线程同步

Kotlin
高阶函数:可以传入其他的函数作为入参

fun <T> maxCustom(array:Array<T>,greater:(T:T) ->Boolean):T?{

    var max : T? = null
    for (item in array){
       if(max == null || greater(item,max) ){
        max = item
        }
    }
    return  max
}

var string_array:Array<String> = arrayOf("How", "do", "you", "do", "I'm ", "Fine")
maxCustom(string_array,
//比较值的大小
{
a,b -> a>b
});

var string_array:Array<String> = arrayOf("How", "do", "you", "do", "I'm ", "Fine")
maxCustom(string_array,
//比较长度的大小
{
a,b -> a.length>b.length
});


扩展函数:扩展函数就是可以在类的外部声明额外的类的函数,并且可以扩展系统函数,让使用更方便,代码更简洁

// 扩展函数
    var method14 : String.() ->Unit={
}
首先通过 Android Studio 自带的工具查看字节码
原理: Kotlin 的扩展函数并没有修改原有的 String 类,而是在自己的类中生成了一个静态的方法,当我们在 Kotlin 中调用扩展函数时,编译器将会调用自动生成的函数并且把当前的对象(String)传入。

// 扩展函数 你对谁扩展 this== 谁本身
fun <T> T.derry()=    Log.d("zhang", "-扩展函数--$this")
123.derry()

    // T==万能类型
    // T.myDerry:让所有地方所有类型都可以用
    // mm 一个lambda的名字
    // T.():我们的lambda体会持有 this == 万能类型本身T
    // mm()调用lambda
    fun<T> T.myDerry(mm : T.() -> Boolean) = mm()
        123.myDerry {
            Log.d("zhang", "-扩展函数--$this")
            true
        }

高阶函数:参数是函数,或者返回值是函数即为高阶函数

    fun<R> sum(n1:Int,n2:Int,n3:Int,mm:(Int,Int,Int)->R?) = mm(n1,n2,n3)
        var sum=sum(1,2,3){v1,v2,v3->
            v1+v2+v3
        }
        Log.d("zhang", "-sum扩展函数--$this-------$sum")

this 和 it 参数

stringVariable?.run {
      println("The length of this String is $length") // 在实际编程中, 通过this关键字的调用通常可以不写this..
}
// Similarly.
stringVariable?.let {
      println("The length of this String is ${it.length}")

==和===   ==和equal一样 ===是否指向内存堆上同一对象

标准函数
let将接收者作为参数传入代码块,并返回其结果。即只能使用 it 调用自身
apply执行传入的代码块,并且获取函数接收者本身(也就是this,即这里的T),最后返回this。

七.kotlin中with、run、apply、let函数的区别?一般用于什么场景?
基本介绍:
with:不是T的扩展函数,需要传入对象进去,不能判空,最后一行是返回值。
run:是T的扩展函数,内部使用this,最后一行是返回值。
apply:是T的扩展函数,内部使用this,最后一行返回的是自身。
let:是T的扩展函数,内部使用it,当然可以自定义名称(通过修改lambda表达式参数),最后一行是返回值。
also:是T的扩展函数,和let一样内部使用it,最后一行是返回自身。

retrofit+协程请求网络
class XieChenTest {
    //实体类
    data class User(
        val `data`: List<Data>,
        val errorCode: Int,
        val errorMsg: String
    )

    data class Data(
        val category: String,
        val icon: String,
        val id: Int,
        val link: String,
        val name: String,
        val order: Int,
        val visible: Int
    )

    //Retrofit网络请求
    val userServiceApi: UserServiceApi by lazy {
        val retrofit = Retrofit.Builder()
            .client(OkHttpClient.Builder().addInterceptor {
                it.proceed(
                    it.request()
                ).apply {
                    Log.d("zhang", "request:${code}")
                }
            }.build()).baseUrl("https://hb.yxg12.cn/").addConverterFactory(
                MoshiConverterFactory.create())
            .build()
        retrofit.create(UserServiceApi::class.java)
    }

    interface UserServiceApi {
        @GET("json")
        //挂起
        suspend fun User() :User

        @GET("webapp.php?page=1&size=2")
        suspend fun getPersonInfo(): PersonInfo

    }

    fun test(){
        GlobalScope.launch(Dispatchers.Main) {
            try {
                //任务调度器    子线程
                val user = withContext(Dispatchers.IO) {
                    userServiceApi.getPersonInfo()
                }
                Log.d("zhang", "address-----" + user.toString())
            }catch (e: Exception){
            Log.d("zhang", "------失败------$e")
            }
        }
    }
}

【带着问题学】协程到底是什么?
1.kotlin协程本质上对线程池的封装
2.kotlin协程可以用同步方式写异步代码,自动实现对线程切换的管理

一、什么是协程
协程:实现协作式多任务,可以在程序执行内部中断,转而执行其他协程。

Kotlin相比于Java的优势
语法更加简洁,对于同样的功能,使用Kotlin开发的代码量可能会比使用Java开发的减少50%甚至更多。
语法更加高级,相比于Java比较老旧的语法,Kotlin增加了很多现代高级语言的语法特性,使得开发效率大大提升。比如扩展函数
语言更加安全,Kotlin几乎杜绝了空指针这个全球崩溃率最高的异常。

线程和协程的区别 面试
资源消耗:
线程是操作系统的资源,创建、切换、停止线程都会消耗大量系统资源。相比之下,协程的创建不需要涉及操作系统功能,编程语言自身就能完成,因此协程也被称为用户态线程,协程比线程轻量得多。
并行性:
线程在多核环境下可以实现真正的并行执行,每个线程可以在不同的核上同时执行任务。而协程是为了实现并发而产生的,通常在单线程内切换执行,不涉及真正的多核并行。
协作性质:
一个具有多个线程的程序可以同时运行多个线程,线程之间可以相对独立地执行任务。相反,协程通常需要协同合作,彼此协作执行,可能会在不同协程之间进行切换。
同步和异步:
线程通常使用同步机制来实现多线程间的协作和数据共享。协程更倾向于使用异步编程模型,通过异步任务和非阻塞调用来实现高效的并发。
抢占性:
线程是抢占式的,操作系统可以主动剥夺一个线程的执行权&#

  • 11
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值