小米安卓面经

小米安卓面经

jre和jdk区别

JDK是Java的开发工具,它不仅提供了Java程序运行所需的JRE,还提供了一系列的编译,运行等工具,如javac,java,javaw等。

JRE只是Java程序的运行环境,它最核心的内容就是JVM(Java虚拟机)及核心类库。

线程池核心参数

核心参数
corePoolSize(核心线程数)

(1)核心线程会一直存在,即使没有任务执行;
(2)当线程数小于核心线程数的时候,即使有空闲线程,也会一直创建线程直到达到核心线程数;
(3)设置allowCoreThreadTimeout=true(默认false)时,核心线程会超时关闭。

queueCapacity(任务队列容量)

也叫阻塞队列,当核心线程都在运行,此时再有任务进来,会进入任务队列,排队等待线程执行。

maxPoolSize(最大线程数)

(1)线程池里允许存在的最大线程数量;
(2)当任务队列已满,且线程数量大于等于核心线程数时,会创建新的线程执行任务;

keepAliveTime(线程空闲时间)

(1)当线程空闲时间达到keepAliveTime时,线程会退出(关闭),直到线程数等于核心线程数;
(2)如果设置了allowCoreThreadTimeout=true,则线程会退出直到线程数等于零。

allowCoreThreadTimeout(允许核心线程超时)
rejectedExecutionHandler(任务拒绝处理器)

(1)当线程数量达到最大线程数,且任务队列已满时,会拒绝任务;
(2)调用线程池shutdown()方法后,会等待执行完线程池的任务之后,再shutdown()。如果在调用了shutdown()方法和线程池真正shutdown()之间提交任务,会拒绝新任务。

线程池执行顺序
  • 当线程数小于核心线程数时,会一直创建线程直到线程数等于核心线程数;
  • 当线程数等于核心线程数时,新加入的任务会被放到任务队列等待执行;
  • 当任务队列已满,又有新的任务时,会创建线程直到线程数量等于最大线程数;
  • 当线程数等于最大线程数,且任务队列已满时,新加入任务会被拒绝。

==和equals 区别

=号在比较基本数据类型时比较的是值,而用=号比较两个对象时比较的是两个对象的地址

equals()方法底层依赖的是=号,那么,在所有没有重写equals()方法的类中,调用equals()方法其实和使用=号的效果一样,也是比较的地址值,然而,Java提供的所有类中,绝大多数类都重写了equals()方法,重写后的equals()方法一般都是比较两个对象的值

io流

根据处理数据类型的不同分为:字符流和字节流

根据数据流向不同分为:输入流和输出流

字符流和字节流

字符流的由来: 因为数据编码的不同,而有了对字符进行高效操作的流对象。本质其实就是基于字节流读取时,去查了指定的码表。字节流和字符流的区别:

(1)读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。

(2)处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。

(3)字节流在操作的时候本身是不会用到缓冲区的,是文件本身的直接操作的;而字符流在操作的时候下后是会用到缓冲区的,是通过缓冲区来操作文件,我们将在下面验证这一点。

结论:优先选用字节流。首先因为硬盘上的所有文件都是以字节的形式进行传输或者保存的,包括图片等内容。但是字符只是在内存中才会形成的,所以在开发中,字节流使用广泛。

输入流和输出流

对输入流只能进行读操作,对输出流只能进行写操作,程序中需要根据待传输数据的不同特性而使用不同的流。

抽象类和普通类的区别

  • 抽象类不能被实例化
  • 抽象类可以有抽象方法,抽象方法只需声明,无需实现
  • 含有抽象方法的类必须声明为抽象类
  • 抽象的子类必须实现抽象类中所有抽象方法,否则这个子类也是抽象类
  • 抽象方法不能被声明为静态
  • 抽象方法不能用private修饰
  • 抽象方法不能用final修饰

OOP(面向对象编程)三大特性你怎么理解

封装,继承,多态

封装是为了隐藏类的内部机制,在不影响使用的前提下可以修改内部细节,同时可以保护内部数据。

继承是为了复用父类的代码,让程序有逻辑上的上下关系。

多态是能够让对象根据不同的消息参数,作出不同的行为,只要分为运行时多态和编译时多态。

封装的意义在于保护或者防止代码(数据)被我们无意中破坏。在面向对象程序设计中数据被看作是一个中心的元素并且和使用它的函数结合的很密切,从而保护它不被其它的函数意外的修改。

  1. 保护数据成员,不让类以外的程序直接访问或修改,只能通过提供的公共的接口访问==>数据封装。
  2. 方法的细节对用户是隐藏的,只要接口不变,内容的修改不会影响到外部的调用者==>方法封装。
  3. 当对象含有完整的属性和与之对应的方法时称为封装。
  4. 从对象外面不能直接访问对象的属性,只能通过和该属性对应的方法访问。
  5. 对象的方法可以接收对象外面的消息。

继承主要实现重用代码,节省开发时间。

多态:同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。

多态的三个条件:

a. 继承的存在(继承是多态的基础,没有继承就没有多态).
b. 子类重写父类的方法(多态下调用子类重写的方法).
c. 父类引用变量指向子类对象(子类到父类的类型转换).

重载(overload)和重写(override)是实现多态的两种主要方式。

hashmap了解吗

https://blog.csdn.net/qq_41117896/article/details/110507748

arrylist 和linkedlist 区别

1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。 (LinkedList是双向链表,有next也有previous)
2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。
3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。

创建线程的三个方式

1)继承Thread类创建线程

2)实现Runnable接口创建线程

3)实现Callable接口

https://blog.csdn.net/qq_41117896/article/details/109441132

run和start的区别

start() 方法的作用是启动一个新线程,新线程会执行相应的run()方法,真正实现了多线程运行。

而run()方法则只是普通的方法调用,在调用线程中顺序运行而已。

重载与重写

重写重载
定义子类根据需要定义新特性,可对父类的方法进行扩展让类以统一的方式处理不同类型参数的一种手段,通过传递参数的个数和类型选择具体调用哪种方法
范围继承类同一类
区别方法名称、返回值、参数等均相同方法名称相同,参数列表不同(每个重载方法都有独一无二的参数列表)

方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。重载发生在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同或者二者都不同)则视为重载;重写发生在子类与父类之间,重写要求子类被重写方法与父类被重写方法有相同的参数列表,有兼容的返回类型,比父类被重写方法更好访问,不能比父类被重写方法声明更多的异常(里氏代换原则)。重载对返回类型没有特殊的要求,不能根据返回类型进行区分。

hashmap怎么解决哈希冲突的

拉链法和开放寻址法

https://blog.csdn.net/weixin_41163113/article/details/84974414

有哪些集合类

set,list,queue,map

https://blog.csdn.net/qq_41117896/article/details/110507294

list子类,区别

List:有序,可重复,有索引。
|–ArrayList:底层是数组数据结构。是线程不同步的。查询元素的速度很快。但是增删元素的效率稍低。
|–LinkedList:底层是链表数据结构,是线程不同步的。查询元素的速度稍慢,但是增删速度很快。
|–Vector:底层也是数组数据结构。是线程同步的。被ArrayList替代了。查询速度,和增删的速度非常慢。效率低。

map子类,区别

Map接口的常用子类有如下四个:HashMap、HashTable、TreeMap、ConcurrentHashMap

1、HashMap:
实现了Map接口,允许一个NULL键和多个NULL值,是非线程安全的,当出现多线程操作时就涉及到了数据的同步问题,可以通过使用Collections.synchronizedMap(Map<K,V> m)方法来从HashMap中获取线程安全的Map,但是这个synchronized会锁住整个HashMap,意味着会效率低,

2、HashTable:
也是实现了Map接口,但是不允许NULL键和NULL值,比HashMap慢,因为它是同步的。HashTable是一个线程安全的类,它使用synchronized来锁住整张Hash表来实现线程安全,即每次锁住整张表让线程独占。所以HashTable适合于单线程。

3、ConcurrentHashMap:
原理类似于HashTable,是线程安全的,也不允许NULL键和NULL值,但是ConcurrentHashMap允许多个修改操作并发进行,因为运用了锁分离技术,ConcurrentHashMap内部使用段(Segment)来表示这些不同的部分,每个段其实就是一个小的Hashtable,它们有自己的锁。只要多个修改操作发生在不同的段上,它们就可以并发进行。所以在涉及到线程的同步问题时,也可以用ConcurrentHashMap代替HashMap

4、TreeMap:
也是非线程安全的,允许一个NULL键和多个NULL值,但是TreeMap存储是有序的,是基于红黑树(Red-Black tree)的 NavigableMap 实现。该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法

treemap按值排序

TreeSet有两种排序方法:自然排序和定制排序。默认采用自然排序(按照Key的自然顺序)。

多线程实现同步的方法有哪些

同步方法

同步代码块

wait和notify

特殊域变量volatile

重入锁

sleep()和wait()区别

sleep 方法属于 Thread 类中方法,表示让一个线程进入睡眠状态,等待一定的时间之后,自动醒来进入到可运行状态,不会马上进入运行状态,因为线程调度机制恢复线程的运行也需要时间,一个线程对象调用了 sleep方法之后,并不会释放他所持有的所有对象锁,所以也就不会影响其他进程对象的运行。

wait 属于 Object 的成员方法,一旦一个对象调用了wait方法,必须要采用 notify() 和 notifyAll() 方法唤醒该进程;

如果线程拥有某个或某些对象的同步锁,那么在调用了 wait() 后,这个线程就会释放它持有的所有同步资源,而不限于这个被调用了 wait() 方法的对象。

值传递,指针传递和引用传递的区别

值传递

形参是实参的拷贝(会在栈内存中创建形参并拷贝实参的值),函数执行完毕后会自动清除栈内存。所以从被调用函数的角度来说,值传递是单向的,形参不能改变实参。当内部函数不需要改变实参则采用值传递。

指针传递

指针传递参数的本质是值传递,只不过它传递的是一个地址值,函数执行的时候在栈中创建并拷贝实参的地址值。函数可以根据地址,找到地址指向的内存单元。因而可以改变主函数实参指向的变量的值。
如果要数据对象是数组,则只能使用指针。因为值传递不能直接数组,引用的对象也不能是数组。

引用传递

&表示引用实参,即代表形参是实参的一个别名。操作引用变量就是操作实参变量。

TCP如何保证有序

  1. 主机每次发送数据时,TCP就给每个数据包分配一个序列号并且在一个特定的时间内等待接收主机对分配的这个序列号进行确认,

  2. 如果发送主机在一个特定时间内没有收到接收主机的确认,则发送主机会重传此数据包。

  3. 接收主机利用序列号对接收的数据进行确认,以便检测对方发送的数据是否有丢失或者乱序等,

  4. 接收主机一旦收到已经顺序化的数据,它就将这些数据按正确的顺序重组成数据流并传递到高层进行处理。

tcp拥塞控制的几个算法

慢开始,拥塞避免,快重传,快恢复

1.慢开始和拥塞避免

发送方维持一个叫做拥塞窗口cwnd,根据网络来进行动态的调整大小,网络拥塞的时候,路由器会丢弃报文,当发送方没有按时收到确认报文,那么就知道网络发生了拥堵。

乘法减小,加法增大

2.快重传和快恢复

快重传的核心:

当接收方收到了一个失序的报文,马上报告给发送方,我没收到,赶紧重传(天下武功唯快不破),加入M2收到了,M3没有收到,之后的M4,M5,M6又发送了,此时接收方一共连续给发送方反馈了4个M2确认报文。那么快重传规定,发送方只要连续收到3个重复确认,立即重传对方发来的M3

快恢复两个要点:

1.当发送方连续收到三个重复确认,执行乘法减小,ssthresh减半

2.由于发送方可能认为网络现在没有拥塞,因此与慢开始不同,把cwnd值设置为ssthresh减半之后的值,然后执行拥塞避免算法,线性增大cwnd

排序算法

https://blog.csdn.net/soullines/article/details/78093668

快排思路

选择一个元素(一般取array的第一个元素),然后作为目标元素,将array中比目标元素小的放在目标元素左边,比目标元素大的放在目标元素右边;
然后继续用相同方式排列左右两边的array;

如何避免快排的最坏情况

快排的最坏情况的发生与快速排序中主元素的选择是有重大的关系

  • 在分解时每次选取的主元素为最小元素
  • 在分解时每次选取的主元素为最大元素

避免方法:

1.主元素的选取随机化:这样就会导致每次分解一直找到的是最小元素最大元素作为主元素 的概率很小,但还是可能发生

2.求序列的中值,然后选取序列的中值作为主元素

3.一开始随机打乱(首先从所有元素中随机选取一个与第一个元素进行交换,然后在第二个之后选择一个元素与第二个交换,直到最后一个元素。)

线程与进程

https://blog.csdn.net/qq_41117896/article/details/115098776

线程状态

新建,可运行,运行,阻塞,死亡

handler机制及原理

https://blog.csdn.net/qq_41117896/article/details/115828642

子线程为什么不能更新UI

安卓不允许子线程更新UI是因为UI访问是没有加锁的,多个线程访问UI不是线程安全的

检测机制:ViewRootImpl的checkThread()检测当前线程是否是UI线程,否则抛异常

Activity生命周期,打开一个新的Activity以及返回,onPause执行时是否可见,onStop呢?onRestart调用时的生命周期。

https://blog.csdn.net/qq_41117896/article/details/115303174

Canvas的translate作用

方法translate(x,y):

平移,将画布的坐标原点向左右方向移动x,向上下方向移动y.canvas的默认位置是在(0,0).

两个build.gradle作用

Project中的gradle是声明的资源包括依赖项、第三方插件、maven仓库地址的,是用来加载gradle脚本自身需要使用的资源,而Module中的gradle是添加的使应用程序所需要的依赖包,也就是项目运行所需要的东西。

versionName与versionCode

versionCode:对消费者不可见的版本号,用于我们自己判断新旧版本,一般更新一次版本 versionCode 会增加。

versionName:展示给消费者的版本号,代表应用程序的版本信息。

Service的启动方式及区别

使用startService()方法启用服务,调用者与服务之间没有关联,即使调用者退出了,服务仍然运行。

使用bindService()方法启动服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止。

ANR了解吗,什么情况可以导致ANR?

1.Activity在5秒内没有响应输入的事件(例如,按键按下,屏幕触摸)
2.BroadcastReceiver在10秒内没有执行完毕

3.service是20

安卓架构

https://blog.csdn.net/qq_41117896/article/details/110878759

view的绘制过程

https://blog.csdn.net/sinat_27154507/article/details/79748010

滑动冲突

https://www.jianshu.com/p/8c635cb59fdf

接口和抽象类的区别

1、抽象类要被子类继承,接口要被类实现。
2、接口只能做方法声明,抽象类中可以作方法声明,也可以做方法实现。
3、接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。
4、接口是设计的结果,抽象类是重构的结果。
5、抽象类和接口都是用来抽象具体对象的,但是接口的抽象级别最高。
6、抽象类可以有具体的方法和属性,接口只能有抽象方法和不可变常量。
7、抽象类主要用来抽象类别,接口主要用来抽象功能。

内部类和静态内部类的区别

  1. 静态内部类是指被声明为static的内部类,可不依赖外部类实例化;而非静态内部类需要通过生成外部类来间接生成。
  2. 静态内部类只能访问外部类的静态成员变量和静态方法,而非静态内部类由于持有对外部类的引用,可以访问外部类的所用成员

string stringbuffer stringbuilder

https://blog.csdn.net/itchuxuezhe_yang/article/details/89966303

final、finally、finalize

https://www.cnblogs.com/ktao/p/8586966.html

jvm运行时内存结构

https://www.cnblogs.com/tisnk/articles/12509875.html

jvm一次编译,到处运行

https://www.cnblogs.com/tisnk/articles/12509875.html

gc的几种方法,为什么新生代用复制,年老代用整理

https://blog.csdn.net/qq_41117896/article/details/115249811

mvp mvvm mvc

https://blog.csdn.net/victoryzn/article/details/78392128

数据库事务

http://m.php.cn/article/418031.html

数据库查询优化

https://blog.csdn.net/weixin_42129286/article/details/82461980

双向链表是什么,优点

https://blog.csdn.net/qq_36553031/article/details/82885804

http和tcp关系

https://www.cnblogs.com/baizhanshi/p/8482612.html

java序列化

https://www.cnblogs.com/wxgblogs/p/5849951.html

mysql索引

https://www.cnblogs.com/whgk/p/6179612.html

用户态、内核态

https://www.cnblogs.com/maxigang/p/9041080.html

进程间的通信方式?

https://blog.csdn.net/qq_41117896/article/details/115098851

select与poll的区别?

https://www.cnblogs.com/Anker/p/3265058.html

静态方法与非静态方法可以互相访问么?

https://blog.csdn.net/yiye2017zhangmu/article/details/83240777

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值