【Java】Java回顾之路(二)

【1】请你简单描述一下String、StringBuffer、StringBuilder?

String:不可变的字符序列,底层使用char[]存储
StringBuffer:可变的字符序列,线程安全的,效率低,底层使用char[]存储
StringBuilder:可变的字符序列,线程不安全的,效率高,底层使用char[]存储

StringBuffer和StringBuilder默认构造器会初始化一个长度为16的char[],数据不断append后,如果出现char[]容量不够的情况,会进行扩容,默认情况下,扩容为原来容量的2倍+2,同时将原有char[]中的元素复制到新数组中

建议:在大概知道append次数和字符串长度时,创建时应该调用StringBuffer(int capacity) 或 StringBuilder(int capacity) 方法指定初始化时的char[]长度,防止多次扩容,提高效率

【2】JDK1.8中的新增的时间API是什么?举例说明一下

localDateTime、LocalDate、LocalTime
localDateTime相较于LocalDate、LocalTime,使用频率更高

public static void main(String[] args) {
        // now():获取当前的日期、时间、日期+时间
        LocalDate localDate = LocalDate.now();
        LocalTime localTime = LocalTime.now();
        LocalDateTime localDateTime = LocalDateTime.now();
        System.out.println(localDate);//2020-05-17
        System.out.println(localTime);//14:44:08.682
        System.out.println(localDateTime);//2020-05-17T14:44:08.682

        LocalDate localDate1 = LocalDate.of(2020, 5, 17);
        LocalTime localTime1 = LocalTime.of(14,49,20);
        LocalDateTime localDateTime1 = LocalDateTime.of(2020, 5, 17, 10, 20, 30);
        System.out.println(localDate1);//2020-05-17
        System.out.println(localTime1);//14:49:20
        System.out.println(localDateTime1);//2020-05-17T10:20:30

        System.out.println(localDateTime.getDayOfMonth());//17
        System.out.println(localDateTime.getDayOfWeek());//SUNDAY
        System.out.println(localDateTime.getDayOfYear());//138
        System.out.println(localDateTime.getMonthValue());//5

        LocalDate localDate2 = localDate1.withDayOfMonth(22);
        System.out.println(localDate1);//2020-05-17
        System.out.println(localDate2);//2020-05-22

        LocalDate localDate3 = localDate2.plusDays(7);
        System.out.println(localDate3);//2020-05-29

        LocalDate localDate4 = localDate3.minusDays(6);
        System.out.println(localDate4);//2020-05-23
    }

【3】请说明List、Map、Set三个接口存取元素时,各有什么特点?

List以特定索引来存取元素,可以有重复元素
Set不能存放重复元素(用对象的equals()方法来区分元素是否重复)
Map保存键值对(key-value pair)映射,映射关系可以是一对一或多对一

【4】请判断List、Set、Map是否继承自Collection接口?

List、Set 是,Map 不是
Map是键值对映射容器,与List和Set有明显的区别,而Set存储的零散的元素且不允许有重复元素,List是线性结构的容器,适用于按数值索引访问元素的情形

【5】请说明Collection 和 Collections的区别

Collection是集合类的上级接口,继承与他的接口主要有Set 和List
Collections是针对集合类的一个工具类,它提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作

【6】请简要说明ArrayList,Vector,LinkedList的存储性能和特性是什么?

ArrayList底层由数组存储数据,是线程不安全的,因此速度相较快,存储数据是有序的,因此顺序存储和查询效率高,但随机插入元素效率低
Vector底层由数组存储数据,是线程安全的,因此速度相较慢,
LinkedList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,擅长随机插入和随机删除数据

【7】请你说明HashMap和Hashtable的区别?

HashMap是线程不安全的,因此效率高,允许Key和Value为null
Hashtable是线程安全的,因此效率低,不允许Key和Value为null

【8】请解释一下TreeMap?

TreeMap是一个有序的key-value集合,基于红黑树(Red-Black tree)的 NavigableMap实现。
该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator进行排序,具体取决于使用的构造方法
TreeMap的特性:
根节点是黑色
每个节点都只能是红色或者黑色
每个叶节点(NIL节点,空节点)是黑色的。
如果一个节点是红色的,则它两个子节点都是黑色的,也就是说在一条路径上不能出现两个红色的节点。从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点

【9】请你解释HashMap的容量为什么是2的n次幂?

负载因子默认是0.75, 2^n是为了让散列更加均匀,例如出现极端情况都散列在数组中的一个下标,那么hashmap会由O(1)复杂退化为O(n)的</font

【10】如果hashMap的key是一个自定义的类,该类需要做什么?

使用HashMap,如果key是自定义的类,该类就必须重写hashcode()和equals(),通过hashcode()确定数据存放的位置,通过equals()来对key去重

【11】如何保证线程安全?

通过合理的时间调度,避开共享资源的存取冲突。另外,在并行任务设计上可以通过适当的策略,保证任务与任务之间不存在共享资源,设计一个规则来保证一个客户的计算工作和数据访问只会被一个线程或一台工作机完成,而不是把一个客户的计算工作分配给多个线程去完成

【12】请你简要说明一下线程的基本状态以及状态之间的关系?

其中Running表示运行状态,Runnable表示就绪状态(万事俱备,只欠CPU),Blocked表示阻塞状态,阻塞状态又有多种情况,可能是因为调用wait()方法进入等待池,也可能是执行同步方法或同步代码块进入等锁池,或者是调用了sleep()方法或join()方法等待休眠或其他线程结束,或是因为发生了I/O中断

【13】请你解释一下什么是线程池(thread pool)?

在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源。在Java中更是如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收。所以提高服务程序效率的一个手段就是尽可能减少创建和销毁对象的次数,特别是一些很耗资源的对象创建和销毁,这就是”池化资源”技术产生的原因。线程池顾名思义就是事先创建若干个可执行的线程放入一个池(容器)中,需要的时候从池中获取线程不用自行创建,使用完毕不需要销毁线程而是放回池中,从而减少创建和销毁线程对象的开销

【14】请介绍一下线程同步和线程调度的相关方法

  • wait():使一个线程处于等待(阻塞)状态,并且释放所持有的对象的锁
  • sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,该方法不会释放对象锁,调用此方法要处理InterruptedException异常
  • notify():唤醒一个处于等待状态的线程,当然在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程
  • notityAll():唤醒所有处于等待状态的线程,该方法并不是将对象的锁给所有线程,而是让它们竞争,只有获得锁的线程才能进入就绪状态
  • 通过Lock接口提供了显式的锁机制(explicit lock),增强了灵活性以及对线程的协调。Lock接口中定义了加锁(lock())和解锁(unlock())的方法,同时还提供了newCondition()方法来产生用于线程之间通信的Condition对象;此外,Java 5还提供了信号量机制(semaphore),信号量可以用来限制对某个共享资源进行访问的线程的数量。在对资源进行访问之前,线程必须得到信号量的许可(调用Semaphore对象的acquire()方法);在完成对资源的访问后,线程必须向信号量归还许可(调用Semaphore对象的release()方法)

【15】现在有一个单向链表,谈一谈,如何判断链表中是否出现了环?

使用快慢指针,定义两个指针,同时从链表的头节点出发,一个指针一次走一步,另一个指针一次走两步。如果走得快的指针追上了走得慢的指针,那么链表就是环形链表;如果走得快的指针走到了链表的末尾(next指向 NULL)都没有追上第一个指针,那么链表就不是环形链表

【16】介绍一下,排序都有哪几种方法?请列举出来

排序的方法有:
插入排序(直接插入排序、希尔排序),交换排序(冒泡排序、快速排序),选择排序(直接选择排序、堆排序),归并排序,分配排序(箱排序、基数排序)

【17】String s = new String(“xyz”);创建了几个String Object?

两个对象,一个是"xyx",一个是指向"xyx"的引用对象s

【18】Math.round(11.5)等于多少? Math.round(-11.5)等于多少?

Math.round(11.5)返回(long)12,Math.round(-11.5)返回(long)-11;

【19】short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错?

short s1 = 1; s1 = s1 + 1;有错,s1是short型,s1+1是int型,不能显式转化为short型。可修改为s1 =(short)(s1 + 1) 。short s1 = 1; s1 += 1正确

【20】try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后?

会执行,在return前执行

【21】

【22】

【23】

【24】

【25】

猜你喜欢

转载自blog.csdn.net/qq_43733123/article/details/106171324
今日推荐