Android阿里面试Java基础锦集

发表于:2017-2-28 09:58

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:何时夕    来源:51Testing软件测试网采编

  接着上一篇 android阿里面试锦集 今天给大家带来一篇 android阿里面试java基础锦集。很多知识都是Thinking in Java上面的,所以如果要深入大家可以看看这本书。
  1.重载函数的签名(区别是否是重载函数)
  方法名+参数类型+参数顺序(返回值不是)
  2.finalize的工作原理
  一旦垃圾收集器准备好释放对象占用的存储空间,它首先调用finalize(),而且只有在下一次垃圾收集过程中,才会真正回收对象的内存.所以如果使用finalize(),就可以在垃圾收集期间进行一些重要的清除或清扫工作。此外系统进行垃圾回收时并不保证一定会调用它,所以可以说它和对象被回收没有必然关系。
  3.一个对象的创建过程
  例如有一个Dog类:
  1.即使没有static,构造器其实也是静态方法,所以当首次创建Dog时或者Dog的静态域或者静态方法被访问的时候,Dog的class对象会被加载。
  2.在加载Dog的class的时候可能会发现其有基类,此时先暂停Dog的加载,转而去加载其基类。所以基类的static域比子类先初始化。
  3.载入class文件之后,会创建一个该该类的class对象,所有关于静态初始化的动作会被执行,所以静态初始化只在Class对象首次加载时进行一次。
  4.当使用new的时候,首先为Dog对象在堆上分配足够内存空间。这块内存控件会被清零,所有实例都被初始化成了默认值,包括基类。
  5.执行所有字段定义处的初始化,从基类开始。
  6.执行构造器。(在第一行会执行基类的构造器)
  4.对象的销毁是按照创建的逆序来进行的。
  5.final的方法和类都不允许覆盖和继承。private默认实现了final。
  6.简述内部类的特点
  1.内部类只能在与其外围类的对象关联的情况下才能被创建(非static)
  2.内部类在创建的时候,捕获了一个外围类的对象,所以能访问外围类的private对象。(非static)
  3.如果其他类对内部类有访问权限的话(如public),那么可以通过 外围类对象.new内部类(),这样的方式创建内部对象,注意如果没有外围类的对象,内部类是不允许创建的。(非static)
  4.多层嵌套的内部类能够透明的访问所有外围类的所有成员。
  5.内部类不能被覆盖
  6.内部类让java模拟了多继承,让外围类继承一个类,然后内部类继承一个类,又要有内部类对象必须有对应的外围类对象。
  7.static的内部类,和普通的类基本相同。
  7.形式参数可被视为local variable,也就是说形式参数相当于在方法中定义了一个局部变量a,当传入c时,只是将c指向的对象给a
  8.finally 语句块是在 try 或者 catch 中的 return 语句之前执行的
  9.简述jvm中默认的classLoader与功能
  1.Bootstrap ClassLoader:负责加载java基础类,主要是 %JRE_HOME/lib/ 目录下的rt.jar、resources.jar、charsets.jar和class等
  2.Extension ClassLoader:负责加载java扩展类,主要是 %JRE_HOME/lib/ext 目录下的jar和class
  3.App ClassLoader:负责加载当前java应用的classpath中的所有类。
  4.classloader 加载类用的是全盘负责委托机制。 所谓全盘负责,即是当一个classloader加载一个Class的时候,这个Class所依赖的和引用的所有 Class也由这个classloader负责载入,除非是显式的使用另外一个classloader载入。所以,当我们自定义的classloader加载成功了 com.company.MyClass以后,MyClass里所有依赖的class都由这个classLoader来加载完成。
  10.switch语句后的控制表达式只能是short、char、int、long整数类型和枚举类型,不能是float,double和boolean类型。String类型是java7开始支持
  11.重写的特性
  1.方法名相同,参数类型和顺序相同
  2.子类返回类型小于等于父类方法返回类型。
  3.子类抛出异常小于等于父类方法抛出异常。
  -4.子类访问权限大于等于父类方法访问权限。
  12.!=和==,当用于基本类型时候,是比较值是否相同;当用于引用类型的时候,是比较对象是否相同,比较内存地址
  13.null可以被强制类型转换成任意类型的对象,于是通过它来执行静态方法
  14.如何终止一个线程
  1.如果线程中是循环或者线程已经sleep(),可以通过Excutor产生一个中断。
  2.如果线程处于io之中,那么可以通过关闭io来使线程结束。
  15.静态属性和静态方法是否可以被继承
  非静态属性、静态属性、静态方法 都可以被子类继承,但是不会被覆盖,转为哪个类,调用的就是那个类的东西。也就是说这几个东西不具有多态。
  16.列出各种List,Set,Map,Queue并说出他们的同与不同。
  1.List:ArrayList、LinkedList、Vector、CopyOnWriteArrayList
  1.ArrayList:常用的List,非线程安全、内部使用数组来实现、对于随机访问get和set,ArrayList优于LinkedList
  2.LinkedList:线程非安全、内部用链表来实现、对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。
  3.Vector:Vector的方法都是同步的、是线程安全的、当Vector或ArrayList中的元素超过它的初始大小时,Vector会将它的容量翻倍,而ArrayList只增加50%的大小,这样,ArrayList就有利于节约内存空间。
  4.CopyOnWriteArrayList:ArrayList 的一个线程安全的变体,其中所有可变操作(add、set 等等)都是通过对底层数组进行一次新的复制来实现的,在CopyOnWriteArrayList中,写入将导致创建整个底层数组的副本,而源数组将保留在原地,使得复制的数组在被修改时,读取操作可以安全的执行。当修改完成时,一个原子性的操作将把新的数组换入,使得新的读取操作可以看到这个新的修改。这对于读操作远远多于写操作的应用非常适合
  2.Set:HashSet、TreeSet、LinkedHashSet、CopyOnWriteArraySet、EnumSet
  1.HashSet:非线程安全、放入的元素需要重写equals()和hashCode()方法,才能避免放入元素重复,并且难以被发现。
  2.TreeSet:非线程安全、其内部使用红黑树储存元素、TreeSet储存的类型必须实现comparable接口。
  3.LinkedHashSet:非线程安全、以元素插入的顺序来维护集合的链接表,其他地方和HashMap类似。
  CopyOnWriteArraySet:线程安全、CopyOnWriteArraySet基于CopyOnWriteArrayList实现。
  EnumSet是一个专门为枚举类设计的集合类,EnumSet中所有元素都必须是指定枚举类型的枚举值,该枚举类型在创建EnumSet时显式、或隐式地指定。EnumSet的集合元素也是有序的,它们以枚举值在Enum类内的定义顺序来决定集合元素的顺序。
  3.Map:HashMap、TreeMap、LinkedHashMap、HashTable、ConcurrentHashMap、WeakHashMap、EnumMap
  1.HashMap:非线程安全、其内部使用链表法解决哈希冲突、key需要重写equals()和hashCode()方法,其内部在获取元素的时候先通过hashCode()获取到某条链表,再通过equals()方法在这条链表中找到该元素。
  2.TreeMap:非线程安全、TreeMap的实现是红黑树算法的实现,key必须实现comparable接口。
  3.LinkedHashMap:非线程安全、这个map是按插入顺序遍历该map,以散列插入。还可以在构造函数中设置参数,使其以LRU算法排序。其获取的Set能体现出排序的方式。
  4.HashTable:线程安全、所有的的方法都是同步的、key和value不能为null。
  5.ConcurrentHashMap:线程安全、ConcurrentHashMap融合了hashtable和hashmap二者的优势、实现了细粒度的锁,也就是不是所有地方都上锁,性能比HashTable好。
  6.WeakHashMap与HashMap的用法基本相似。区别在于,HashMap的key保留了对实际对象的"强引用",这意味着只要该HashMap对象不被销毁,该HashMap所引用的对象就不会被垃圾回收。但WeakHashMap的key只保留了对实际对象的弱引用,这意味着如果WeakHashMap对象的key所引用的对象没有被其他强引用变量所引用,则这些key所引用的对象可能被垃圾回收,当垃圾回收了该key所对应的实际对象之后,WeakHashMap会自动删除这些key所对应的key-value对
  7.EnumMap:EnumMap是一个与枚举类一起使用的Map实现,EnumMap中的所有key都必须是单个枚举类的枚举值。创建EnumMap时必须显式或隐式指定它对应的枚举类。EnumMap根据key的自然顺序(即枚举值在枚举类中的定义顺序)。
  4.Queue:ArrayBlockingQueue、LinkedBlockingQueue、DelayQueue、PriorityBlockingQueue、PriorityQueue。
  1.ArrayBlockingQueue:线程安全、基于数组的阻塞队列实现,在ArrayBlockingQueue内部,维护了一个定长数组,以便缓存队列中的数据对象。同一时间只能有一个线程进行操作。
  2.LinkedBlockingQueue:基于链表的阻塞队列,同ArrayListBlockingQueue类似,其内部也维持着一个数据缓冲队列,当生产者往队列中放入一个数据时,队列会从生产者手中获取数据,并缓存在队列内部,而生产者立即返回、只有当队列缓冲区达到最大值缓存容量时(LinkedBlockingQueue可以通过构造函数指定该值),才会阻塞生产者队列,直到消费者从队列中消费掉一份数据,生产者线程会被唤醒。可以有多个线程进行同时操作。
  3.DelayQueue: DelayQueue里面放的是实现了Delayed的接口,Delayed接口需要实现两个方法:getDelay(TimeUnit unit)是为了返回该任务锁需延长的时间,compareTo(Delayed o)是为了比较到底那个任务需要排在前面,当使用queue.take()的时候延时开始,此时本线程挂起,直到延时结束开始运行run()中的任务。
  4.PriorityBlockingQueue: 基于优先级的阻塞队列(优先级的判断通过构造函数传入的Compator对象来决定),但需要注意的是PriorityBlockingQueue并不会阻塞数据生产者,而只会在没有可消费的数据时,阻塞数据的消费者。因此使用的时候要特别注意,生产者生产数据的速度绝对不能快于消费者消费数据的速度,否则时间一长,会最终耗尽所有的可用堆内存空间。
  5.PriorityQueue:非线程安全的优先队列。
  17.列出几种线程池
  1.ThreadPoolExecutor:通过Executors可以构造单线程池、固定数目线程池、不固定数目线程池。
  2.ScheduledThreadPoolExecutor:可以延时调用线程或者延时重复调度线程。
  18.解释一下java内存模型
  1.每个线程有自己的共享变量副本(实例域、静态域、数组元素)
  2.Java线程之间的通讯由java内存模型控制(JMM),JMM决定了一个线程对共享变量的写入在什么时候对另一个线程可见。
  3.当一个A线程改变了一个共享变量,此时只是改变了自己本地共享变量的副本,所以线程之间要实现通讯需要先将A线程的本地副本,刷入到主存之中,然后线程B去主存中读取线程A刷入的改变的变量。
  19.解释一下java代码的原子性
  1.除了long和double,其他基本类型的简单操作都是原子性操作:读取、写入数字。
  2.java1.5之后使用volatile关键字能够让long和double像其他基本类型一样。
  3.不能因为有原子性,就放弃同步。
  20.解释一下volatile字段
  1.在了解了java内存模型之后,我们知道volatile关键字保证了,某个共享变量改变之后,另一个线程中本地共享变量的副本也会立即刷新。
  2.当某个域的值依赖于它之前的值,如计数递增那么volatile就会失效。
  3.使用volatile而不使用synchronized的唯一情况就是类中只有一个可变域,其他时候都应该使用synchronized。
  21.解释一下synchronized字段
  1.synchronized可以用于修饰方法,在某线程从某个用synchronized修饰的方法返回之前,其他所有要调用这个对象中任意使用synchronized修饰的方法的线程都会被阻塞。即同一时刻某个对象中只能有一个synchronized修饰的方法被调用。
  2.对于某个对象,其所有synchronized方法共享一把锁,也就是说一个对象中含有一把锁(也叫监视器)。
  3.一个线程可以多次获取某个对象的锁,比如一个synchronized方法中调用了该对象中另一个synchronized方法。那么这个锁的计数就会变成2,每从一个synchronized方法离开都会使计数减一,每进入一个synchronized方法都会使计数加一。
  4.每个类也有一把锁(属于类的Class的一部分),所以synchronized static可以防止类范围内对于static数据的并发访问。
  22.Lock的使用
  1.在lock()和unlock()之间我们可以创建一个临界资源,同时一时刻只能有一个线程访问这个资源。。
  2.我们可以对临界区域进行异常捕捉,注意return必须在try里面,防止过早释放临界资源。
  3.使用Lock的好处就在于我们能处理某些异常,而使用synchronized我们无法对异常进行清理工作。
  23.wait()和sleep()区别
  1.该方法在Object中,可以将当前线程挂起,需要在synchronized控制的块中,因为wait需要获取需要挂起的线程所要处理对象的锁,否则会报错。在wait()中锁是被释放的。
  2.该方法是属于Thread类中、sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,线程不会释放对象锁。
  24.死锁产生的条件
  1.至少有一个资源是不能被共享的
  2.至少有一个任务持有一个资源并且在等待另一个资源
  3.资源不能被抢占
  4.必须有循环等待
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号