1. 什么是程序的copy
    答: 想对一个对象进行处理,又想保留原有的数据进行接下来的操作,就需要克隆了,Java语言中克隆针对的是类的实例
  2. 浅拷贝和深海拷贝的区别是
    答:浅拷贝只是复制了对象的引用地址,两个对象指向同一个内存地址,所以修改其中任意的值,另一个值都会随之变化,这就是浅拷贝
    深拷贝:两个对象都拥有各个独立的数据,不会相互影响。
  3. 拷贝的工具类中谁的效率最高 为什么
    答: cgilb beanutils最高 Apache BeanUtils最差
    因为apanche Beanutils为了追求完美 非常多的校验、兼容、日志打印等代码,过度的包装导致性能下降严重
  4. SimplateDateFormat方法中 y和Y的区别
    答 因为不同的国家对新年第一天的定义不一样导致 Y y有区别 WEEK
  5. 三目运算符中的对象和基本类型比较为什么会出现空指针
    答::由于使用了三目运算符,并且第二、第三位操作数分别是基本
    类型和对象。所以对对象进行拆箱操作,由于该对象为 null,所以在拆箱过程中调用到了null
  6. hashMap 中采用的扩容机制的条件是什么
    答:其实,HashMap 的扩容条件就是当 HashMap 中的元素个数(size)超过临界值(threshold)时就会自动扩容。
  7. hashMap为什么要指定大小
    答:一个合理的初始化容量可以有效的提高性能 ,如果我们没有设置初始容量大小,
    随着元素的不断增加,HashMap 会发生多次扩容,而 HashMap 中的扩 容机制决定了每次扩容都需要重建 hash 表,是非常影响性能的
  8. 扩容规则是什么
    答: HashMap 会采用第一个大于该数值的 2 的幂作为初始化
    容量(大约在hash存储3/4的情况下再次扩容)
  9. 如果在知道hashMap内存的情况下怎么建表
    答:Maps.newHashMapWithExpectedSize(数)
  10. 为什么禁止使用 Executors 创建线程池?
  • java开发手册中明确指明 创建线程的时候不要用Executors创建线程 池, 而是推荐使用ThreadpoolExecutors
  • 允许请求长度为Integer_max_value可能会堆积大量的请求,导致内存溢出
  • 允许请求创建线程为Integer_max_value可能会创建大量线程导致内存溢出
  1. 原因
  • 导致 OOM 的其实是 LinkedBlockingQueue.offer 方法。
  • Java 中 的 BlockingQueue 主 要 有 两 种 实 现, 分 别 是 ArrayBlockingQueue 和 LinkedBlockingQueue
  • newFixedThreadPool 中创建 LinkedBlockingQueue 时,并未指定容
    量。此时,LinkedBlockingQueue 就是一个无边界队列,对于一个无边界队列来说,是可以不断的向队列中加入任务的,这种情况下就有可能因为任务过多而导致内存溢出问题
  • 解决办法在创建线程时使用
new ThreadPoolExecutor(指定,指定)
public class ExecutorsDemo {
 private static ThreadFactory namedThreadFactory = new 
ThreadFactoryBuilder()
 .setNameFormat("demo-pool-%d").build();
 private static ExecutorService pool = new ThreadPoolExecutor(5, 200,
 0L, TimeUnit.MILLISECONDS,
 new LinkedBlockingQueue<Runnable>(1024), namedThreadFactory, new 
ThreadPoolExecutor.
AbortPolicy());
 public static void main(String[] args) {
 for (int i = 0; i < Integer.MAX_VALUE; i++) {
 pool.execute(new SubThread());
 }
 }
}
  1. 为什么ArrayList中subList不能强行转化为ArrayList
  • SubList 并没有重新创建一个 List,而是直接引用了原有的 List(返回了父类的视图),只是指定了一下他要使用的元素的范围而已(从fromIndex(包含),到 toIndex(不包含))。
  • SubList 只是 ArrayList 的内部类,他们之间并没有集成关系,故无法直接进行强制类型转换。
  • List 的 subList 方法并没有创建一个新的 List,而是使用了原 List 的视图,这个视图使用内部类 SubList 表示
  • 如果需要对 subList 作出修改,又不想动原 list。那么可以创建 subList 的一个拷贝:
  1. String中拼接方式 以及为什么不能在for循环中+
  • concat Stringbuffer中的append
  • String在for中+ ==new StringBulider.append…toString
  1. StringBuffer 和 StringBuilder区别
  • append 会直接拷贝字符到内部的字符数组中,如果字符数组长度不够会进行扩展
  • StringBuffer 和 StringBuilder 类似,最大的区别就是 StringBuffer
    是线程安全的 加入了 synchronized
  1. 为什么在foreach中禁止使用add/remave
  • 在增强 for 循环中,集合遍历是通过 iterator
    进行的,但是元素的 add/remove 却是直接使用的集合类自己的方法。这就导致iterator 在遍历的时候,会发现有一个元素在自己不知不觉的情况下就被删除 / 添加了,就会抛出一个异常
  • fail-fast,即快速失败,它是 Java 集合的一种错误检测机制。当多个线程对集
    合(非 fail-safe 的集合类)进行结构上的改变的操作时,有可能会产生 fail-fast 机制,
  1. 为什么不要使用日志的api
  • 为了在应用中屏蔽掉底层日志框架的具体实现。这样的话,即使有一天要更换代码的日志框架,只需要修改 jar 包,最多再改改日志输出相关的配置文件就可以了。这就是解除了应用和日志框架之间的耦合。
  • 最佳实践就是在应用中使用如 Log4j + SLF4J 这样的组合来进行日志输出
  1. 为什么禁止定义SimpleDateFormat 为static类型
  • SimpleDateFormat是线程不安全的类 一般不要定义为static 如果非要定义要加上锁 或者使用DateUtils
  • SimpleDateFormat 中的 format 方法在执行过程中,会使用一个成员变量calendar 来保存时间。这其实就是问题的关键
  • 由于我们在声明 SimpleDateFormat 的时候,使用的是 static 定义的。那么这 个 SimpleDateFormat 就 是 一 个 共 享 变 量, 随 之SimpleDateFormat 中 的calendar 也就可以被多个线程访问到
  1. new Date()
    new Date()获取的是计算机时间
    打印美国时间
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
   sdf.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));
  System.out.println(sdf.format(Calendar.getInstance().getTime()))
  1. 解决办法
  • 使用局部变量
  • 对于共享变量进行加锁
  • 使用ThreadLocal保证每一个线程独一无二
  • 使用DateTimeFormatter

String dateStr= "2016 年 10 月 25 日 ";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy 年 MM 月 dd 日 ");
LocalDate date= LocalDate.parse(dateStr, formatter);
// 日期转换为字符串
LocalDateTime now = LocalDateTime.now();
DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy 年 MM 月 dd 日 hh:mm a");
String nowStr = now .format(format);
  1. 为什么禁止开发人员使用 isSuccess 作为变量名?
  • pojo中不要再boolean中命名加上is,因为他的属性方法也是is开头,再序列化时属性名变成了没有is,导致获取不到值
  1. 为什么使用序列化
  • 序列化是一种对象持久化的手段
  • 当你想把的内存中的对象状态保存到一个文件中或者数据库中时候;
  1. 为什么POJO类中要定义为封装类 而不是基本类型
  • 封装类在面对null值的时候会报错 ,而基础类型不报错,导致如果数据为null 基础类型会显示为0 不产生异常 难以发现问题
  1. 为什么禁止修改serialVersionUID
  • Serializable 和 Externalizable类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法进行序列化或反序列化。可序列化类的所有子类型本身都是可序列化的
  • 一旦类实现了 Serializable,就建议明确的定义一个 serialVersionUID。不然在修改类的时候,就会发生异常。
  1. 组合和聚合的区别
  • 组合A类的构造方法里创建B类的对象,也就是说,当A类的一个对象产生时,B类的对象随之产生,当A类的这个对象消亡时,它所包含的B类的对象也随之消亡。
  • 聚合A类的对象在创建时不会立即创建B类的对象,而是等待一个外界的对象传给它传给它的这个对象不是A类创建的。