Android面试知识点(一)*

2021-02-19  本文已影响0人  书虫大王X
1、操作系统的内存分级

早期的内存使用机制:

内存分段:

内存分页:

2、newInstance与new的区别:
3、反射:
interface fruit{  
    public abstract void eat();  
}  
    
class Apple implements fruit{  
    public void eat(){  
        System.out.println("Apple");  
    }  
}  
    
class Orange implements fruit{  
    public void eat(){  
        System.out.println("Orange");  
    }  
}  
    
// 构造工厂类:以后我们在添加其他的实例的时候修改工厂类就行了  
class Factory{  
    public static fruit getInstance(String fruitName){  
        fruit f=null;  
        if("Apple".equals(fruitName)){  
            f=new Apple();  
        }  
        if("Orange".equals(fruitName)){  
            f=new Orange();  
        }  
        return f;  
    }  
}  
class hello{  
    public static void main(String[] a){  
        fruit f=Factory.getInstance("Orange");  
        f.eat();  
    }  
}  
interface fruit{  
    public abstract void eat();  
}  
   
class Apple implements fruit{  
    public void eat(){  
        System.out.println("Apple");  
    }  
}  
   
class Orange implements fruit{  
    public void eat(){  
        System.out.println("Orange");  
    }  
}  
   
class Factory{  
    public static fruit getInstance(String ClassName){  
        fruit f=null;  
        try{  
            f=(fruit)Class.forName(ClassName).newInstance();  
        }catch (Exception e) {  
            e.printStackTrace();  
        }  
        return f;  
    }  
}  
class hello{  
    public static void main(String[] a){  
        fruit f=Factory.getInstance("Reflect.Apple");  
        if(f!=null){  
            f.eat();  
        }  
    }  
}  
4、Android的系统、APP启动过程
5、push机制:
8、数据的位数:

9、atomic的实现机制

5、kotlin相对于Java有什么优缺点:

1、在Kotlin语言中,类终于不再是一等公民。Kotlin语言开始支持面向过程编程,Kotlin语言中可以声明全局函数、内联函数等,还支持函数嵌套,使用函数作为方法参数等操作。对于一些简单的操作,新建一个类去处理,的确有时候是一个让人头疼的问题,Kotlin语言让我们摆脱了这一尴尬的现状。
2、数据类:我们常常要不断写一些Model类,不断地使用开发工具生成set/get方法。Data Class就是为简化这个操作而生的,数据类会自动生成set/get方法,而不用显式生成set/get方法
3、Kotlin和Java语言可以实现完全地互同调用,Kotlin最终也会编译成Java字节码。
4、完全兼容Java
5、Null safe(空指针安全)
6、支持lambda表达式(比Java8更好)
7、支持扩展
8、体验一致的开发工具链
9、相对于java更简洁
10、对比Java,Kotlin的优点和缺点

6、面向对象六大原则:

单一职责原则——SRP
开闭原则——OCP
里式替换原则——LSP
依赖倒置原则——DIP
接口隔离原则——ISP
迪米特原则——LOD

8、组合(引用)跟继承的使用场景区别:

支持扩展,通过继承父类实现,但会使系统结构较复杂
易于修改被复用的代码

代码白盒复用,父类的实现细节暴露给子类,破坏了封装性
当父类的实现代码修改时,可能使得子类也不得不修改,增加维护难度。
子类缺乏独立性,依赖于父类,耦合度较高
不支持动态拓展,在编译期就决定了父类

代码黑盒复用,被包括的对象内部实现细节对外不可见,封装性好。
整体类与局部类之间松耦合,相互独立。

支持扩展
每个类只专注于一项任务
支持动态扩展,可在运行时根据具体对象选择不同类型的组合对象(扩展性比继承好)

创建整体类对象时,需要创建所有局部类对象。导致系统对象很多。

从前面的分析看,组合的优点明显多于继承,再加上java中仅支持单继承,所以:
除非两个类之间是is-a的关系,否则尽量使用组合。

9、线程池的优点:

重用线程池中的线程,避免因为线程的创建和销毁带来性能开销。
能有效控制线程池的最大并发数,避免大量的线程之间因互相抢占系统资源而导致的阻塞现象。
能够对线程进行管理,并提供定时执行以及定间隔循环执行等功能。

10、tcp三次握手的目的:

三次握手的目的是连接服务器指定端口,建立TCP连接,并同步连接双方的序列号和确认号,交换 TCP 窗口大小信息。当仅仅是两次握手时,服务器端不能知道自己发送给客户端的消息是否被客户端收到。

为什么不是两次:

存在这种情况:第一次连接请求报文由于网络节点长时间滞留了,导致延误到连接释放后的某个时间才到达 Server。这时 Server 会再次给 Client 发送确认报文(第二次握手),但是 Client 进程程序并不会理睬确认报文,因为 Client 没有发送连接请求。现在假如没有第三次握手就会建立连接,那么这次滞后的连接请求报文就会导致 TCP 误建立连接,而 Client 却不知已经建立连接,并不会发送数据给 Server,这样 Server 就会一直处于等待状态,这样就白白浪费了 Server 的很多资源。但有了第三次握手就会避免这种问题的发生,虽然延迟的连接请求发送到了 Server,但 Client 不会处理 Server 的确认报文,也不会再次发送确认请求报文,这样 Server 就知道了 Client 并没有真正想建立连接。所以不能是两次握手。

11、java泛型:
13、Unix下IO模型:

14、防止死锁的方法:

  • 尽量缩小锁的范围
  • 给锁添加顺序
  • 使用定时锁
  • 死锁检查(一种依靠算法机制来实现的死锁预防机制)
  • 银行家算法

解除死锁的方法:

1、资源剥夺方法
2、撤销进程
3、进程回退法

常见的网络状态码:

Android程序去手机相册获取图片:

1、跳转到相机,选择一张图片后返回,然后回到onActivityResult方法中
1、定义一个资源标识符接收onActivityResult方法传递回来的数据
2、然后用contentResolver和uri创建一个数据流
3、用BitmapFactory的解析这个输入流
4、最后将解析过后的输入流设置到图片上去

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        when (requestCode) {
            // 相册
            IMAGE_CODE -> {
                if (resultCode != Activity.RESULT_CANCELED) {
                    val uri: Uri? = data?.data 
                    uri?.let {
                        contentResolver.openInputStream(uri).use {
                            BitmapFactory.decodeStream(it).apply {
                                // 显示图片
                                ykImage.setImageBitmap(this)
                                // 缓存图片: 创建保存图片的文件
                                var file = File(filesDir, "header.jpg")
                                FileOutputStream(file).also { yk2 ->
                                    // 将图片保存到对应的路径中
                                    compress(Bitmap.CompressFormat.JPEG, 50, yk2)
                                }
                            }
                        }
                    }
                }
            }
        // 获取头像图片(下一次进入程序时,去获取图片)
        File(filesDir, "header.jpg").also {
            if (it.exists()) {
                BitmapFactory.decodeFile(it.path).also { yk ->
                    ykImage.setImageBitmap(yk)
                }
            }
        }
    }

11、变量的分类:

12、静态变量与局部变量的区别:

14、static关键字:

14、final关键字:

15、 String为什么不可变
上一篇 下一篇

猜你喜欢

热点阅读