1、java 中都有哪些引用类型1强引用Java中默认声明的就是强引用比如Object obj new Object();obj null;只要强引用存在垃圾回收器将永远不会回收被引用的对象。如果想被回收可以将对象置为null2软引用SoftReference在内存足够的时候软引用不会被回收只有在内存不足时系统才会回收软引用对象如果回收了软引用对象之后仍然没有足够的内存才会跑出内存溢出异常。byte[] buff new byte[1024 * 1024];SoftReferencebyte[] sr new SoftReference(buff);3弱引用WeakReference进行垃圾回收时弱引用就会被回收。4虚引用PhantomReference5引用队列ReferenceQueue引用队列可以与软引用、弱引用、虚引用一起配合使用。当垃圾回收器准备回收一个对象时如果发现它还有引用就会在回收对象之前把这个引用加入到引用队列中。程序可以通过判断引用队列中是否加入了引用来判断被引用的对象是否将要被垃圾回收这样可以在对象被回收之前采取一些必要的措施。2、在 Java 中为什么不允许从静态方法中访问非静态变量静态变量属于类本身在类加载的时候就会分配内存可以通过类名直接访问非静态变量属于类的对象只有在类的对象产生时才会分配内存通过类的实例去访问静态方法也属于类本身但是此时没有类的实例内存中没有非静态变量所以无法调用。3、说说Java Bean的命名规范JavaBean 类必须是一个公共类并将其访问属性设置为 publicJavaBean 类必须有一个空的构造函数类中必须有一个不带参数的公用构造器此构造器也应该通过调用各个特性的设置方法来设置特性的缺省值。一个javaBean类不应有公共实例变量类变量都为private持有值应该通过一组存取方法getXxx 和 setXxx来访问对于每个特性应该有一个带匹配公用 getter 和 setter 方法的专用实例变量。属性为布尔类型可以使用 isXxx() 方法代替 getXxx() 方法。通常属性名是要和 包名、类名、方法名、字段名、常量名作出区别的:首先:必须用英文不要用汉语拼音1包(package )用于将完成不同功能的类分门别类放在不同的目录(包)下包的命名规则将公司域名反转作为包名。比如www.sohu.com 对于包名每个字母都需要小写。比如com.sohu.test;该包下的Test类的全名是com.sohu.Test.Java 。如果定义类的时候没有使用package,那么java就认为我们所定义的类位于默认包里面(default package)。2类首字母大写如果一个类由多个单词构成那么每个单词的首字母都大写而且中间不使用任何的连接符。尽量使用英文。如ConnectionFactory3方法首单词全部小写如果一个方法由多个单词构成那么从第二个单词开始首字母大写不使用连接符。addPerson4字段与方法相同。如ageOfPerson5常量所有单词的字母都是大写如果有多个单词那么使用下划线链接即可。如public static final int AGE_OF_PERSON 20; //通常加上static篇幅限制下面就只能给大家展示小册部分内容了。整理了一份核心面试笔记包括了Java面试、场景题、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafc需要全套面试笔记及答案【点击此处即可/免费获取】​​​https://docs.qq.com/doc/DQXdYWE9LZ2ZHZ1ho4、Java Bean 属性命名规范问题分析public class User {private String busName;private String pCount;private Boolean isRunning;//正确的命名方式驼峰式的public String getBusName() {return busName;}public void setBusName(String busName) {this.busName busName;}//这是什么public String getpCount() {return pCount;}public void setpCount(String pCount) {this.pCount pCount;}//这个也是不允许的public Boolean getIsRunning() {return isRunning;}public void setIsRunning(Boolean isRunning) {this.isRunning isRunning;}}1. javabean属性命名尽量使用常规的驼峰式命名规则2. 属性名第一个单词尽量避免使用一个字母如eBook eMail。3. boolean属性名避免使用 “is” 开头的名称4. 随着jdk eclipse spring 等软件版本的不断提高 底版本的出现的问题可能在高版本中解决了 低版本原来正常的代码可能在高版本环境下不再支持。5、什么是 Java 的内存模型?在了解什么是 Java 内存模型之前先了解一下为什么要提出 Java 内存模型。之前提到过并发编程有三大问题CPU 缓存在多核 CPU 的情况下带来了可见性问题操作系统对当前执行线程的切换带来了原子性问题译器指令重排优化带来了有序性问题为了解决并发编程的三大问题提出了 JSR-133新的 Java 内存模型JDK 5 开始使用。简单总结下Java 内存模型是 JVM 的一种规范定义了共享内存在多线程程序中读写操作行为的规范屏蔽了各种硬件和操作系统的访问差异保证了 Java 程序在各种平台下对内存的访问效果一致解决并发问题采用的方式限制处理器优化和使用内存屏障增强了三个同步原语synchronized、volatile、final的内存语义定义了 happens-before 规则6、在 Java 中什么时候用重载什么时候用重写1重载是多态的集中体现在类中要以统一的方式处理不同类型数据的时候可以用重载。2重写的使用是建立在继承关系上的子类在继承父类的基础上增加新的功能可以用重写。3简单总结重载是多样性重写是增强剂目的是提高程序的多样性和健壮性以适配不同场景使用时使用重载进行扩展目的是在不修改原方法及源代码的基础上对方法进行扩展或增强时使用重写生活例子你想吃一碗面我给你提供了拉面炒面刀削面担担面供你选择这是重载你想吃一碗面我不但给你端来了面还给你加了青菜加了鸡蛋这个是重写设计模式cglib实现动态代理核心原理用的就是方法的重写详细解答Java的重载(overload) 最重要的应用场景就是构造器的重载构造器重载后提供多种形参形式的构造器可以应对不同的业务需求加强程序的健壮性和可扩展性比如我们最近学习的Spring源码中的ClassPathXmlApplicationContext它的构造函数使用重载一共提供了10个构造函数这样就为业务的选择提供了多选择性。在应用到方法中时主要是为了增强方法的健壮性和可扩展性比如我们在开发中常用的各种工具类比如我目前工作中的短信工具类SMSUtil, 发短信的方法就会使用重载针对不同业务场景下的不同形参提供短信发送方法这样提高了工具类的扩展性和健壮性。总结重载必须要修改方法(构造器)的形参列表可以修改方法的返回值类型也可以修改方法的异常信息即访问权限使用范围是在同一个类中目的是对方法(构造器)进行功能扩展以应对多业务场景的不同使用需求。提高程序的健壮性和扩展性。java的重写(override) 只要用于子类对父类方法的扩展或修改但是在我们开发中为了避免程序混乱重写一般都是为了方法的扩展比如在cglib方式实现的动态代理中代理类就是继承了目标类对目标类的方法进行重写同时在方法前后进行切面织入。总结方法重写时参数列表返回值得类型是一定不能修改的异常可以减少或者删除但是不能抛出新的异常或者更广的异常方法的访问权限可以降低限制但是不能做更严格的限制。4在里氏替换原则中子类对父类的方法尽量不要重写和重载。我们可以采用final的手段强制来遵循7、举例说明什么情况下会更倾向于使用抽象类而不是接口接口和抽象类都遵循”面向接口而不是实现编码”设计原则它可以增加代码的灵活性可以适应不断变化的需求。下面有几个点可以帮助你回答这个问题在 Java 中你只能继承一个类但可以实现多个接口。所以一旦你继承了一个类你就失去了继承其他类的机会了。接口通常被用来表示附属描述或行为如 Runnable 、 Clonable 、 Serializable 等等因此当你使用抽象类来表示行为时你的类就不能同时是 Runnable 和 Clonable( 注这里的意思是指如果把 Runnable 等实现为抽象类的情况 ) 因为在 Java 中你不能继承两个类但当你使用接口时你的类就可以同时拥有多个不同的行为。在一些对时间要求比较高的应用中倾向于使用抽象类它会比接口稍快一点。如果希望把一系列行为都规范在类继承层次内并且可以更好地在同一个地方进行编码那么抽象类是一个更好的选择。有时接口和抽象类可以一起使用接口中定义函数而在抽象类中定义默认的实现。8、实例化对象有哪几种方式newclone()通过反射机制创建//用 Class.forName方法获取类在调用类的newinstance方法Class? cls Class.forName(com.dao.User);User u (User)cls.newInstance();序列化反序列化//将一个对象实例化后进行序列化再反序列化也可以获得一个对象远程通信的场景下使用ObjectOutputStream out new ObjectOutputStream (new FileOutputStream(D:/data.txt));//序列化对象out.writeObject(user1);out.close();//反序列化对象ObjectInputStream in new ObjectInputStream(new FileInputStream(D:/data.txt));User user2 (User) in.readObject();System.out.println(反序列化user user2);in.close();9、byte类型1271等于多少byte的范围是-128~127。字节长度为8位最左边的是符号位而127的二进制为01111111所以执行1操作时01111111变为10000000。大家知道计算机中存储负数存的是补码的兴衰。左边第一位为符号位。那么负数的补码转换成十进制如下一个数如果为正则它的原码、反码、补码相同一个正数的补码将其转化为十进制可以直接转换。已知一个负数的补码将其转换为十进制数步骤如下先对各位取反将其转换为十进制数加上负号再减去1例如10000000最高位是1是负数①对各位取反得01111111转换为十进制就是127加上负号得-127再减去1得-12810、Java 容器都有哪些1Collection① setHashSet、TreeSet② listArrayList、LinkedList、Vector2MapHashMap、HashTable、TreeMap11、Collection 和 Collections 有什么区别1Collection是最基本的集合 接口Collection派生了两个子接口list和set分别定义了两种不同的存储方式。2Collections是一个包装类它包含各种有关集合操作的静态方法对集合的搜索、排序、线程安全化等。此类不能实例化就像一个工具类服务于Collection框架。12、list与Set区别1List简介实际上有两种List一种是基本的ArrayList,其优点在于随机访问元素另一种是LinkedList,它并不是为快速随机访问设计的而是快速的插入或删除。ArrayList由数组实现的List。允许对元素进行快速随机访问但是向List中间插入与移除元素的速度很慢。LinkedList 对顺序访问进行了优化向List中间插入与删除的开销并不大。随机访问则相对较慢。还具有下列方 法addFirst(), addLast(), getFirst(), getLast(), removeFirst() 和 removeLast(), 这些方法 (没有在任何接口或基类中定义过)使得LinkedList可以当作堆栈、队列和双向队列使用。2Set简介Set具有与Collection完全一样的接口因此没有任何额外的功能。实际上Set就是Collection,只是行为不同。这是继承与多态思想的典型应用表现不同的行为。Set不保存重复的元素(至于如何判断元素相同则较为负责)Set : 存入Set的每个元素都必须是唯一的因为Set不保存重复元素。加入Set的元素必须定义equals()方法以确保对象的唯一性。Set与Collection有完全一样的接口。Set接口不保证维护元素的次序。HashSet为快速查找设计的Set。存入HashSet的对象必须定义hashCode()。TreeSet 保存次序的Set, 底层为树结构。使用它可以从Set中提取有序的序列。3list与Set区别① List,Set都是继承自Collection接口② List特点元素有放入顺序元素可重复 Set特点元素无放入顺序元素不可重复重复元素会覆盖掉元素虽然无放入顺序但是元素在set中的位置是有该元素的HashCode决定的其位置其实是固定的加入Set 的Object必须定义equals()方法 另外list支持for循环也就是通过下标来遍历也可以用迭代器但是set只能用迭代因为他无序无法用下标来取得想要的值。③ Set和List对比Set检索元素效率低下删除和插入效率高插入和删除不会引起元素位置改变。List和数组类似List可以动态增长查找元素效率高插入删除元素效率低因为会引起其他元素位置改变。篇幅限制下面就只能给大家展示小册部分内容了。整理了一份核心面试笔记包括了Java面试、场景题、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafc需要全套面试笔记及答案【点击此处即可/免费获取】​​​https://docs.qq.com/doc/DQXdYWE9LZ2ZHZ1ho13、HashMap 和 Hashtable 有什么区别HashMap是线程不安全的HashTable是线程安全的HashMap中允许键和值为nullHashTable不允许HashMap的默认容器是16为2倍扩容HashTable默认是11为2倍1扩容14、说一下 HashMap 的实现原理1简介HashMap基于map接口元素以键值对方式存储允许有null值HashMap是线程不安全的。2基本属性初始化大小默认162倍扩容负载因子0.75初始化的默认数组sizethreshold。判断是否需要调整hashmap容量3HashMap的存储结构JDK1.7中采用数组链表的存储形式。HashMap采取Entry数组来存储key-value每一个键值对组成了一个Entry实体Entry类时机上是一个单向的链表结构它具有next指针指向下一个Entry实体以此来解决Hash冲突的问题。HashMap实现一个内部类Entry重要的属性有hash、key、value、next。JDK1.8中采用数据链表红黑树的存储形式。当链表长度超过阈值8时将链表转换为红黑树。在性能上进一步得到提升。15、set有哪些实现类1HashSetHashSet是set接口的实现类set下面最主要的实现类就是HashSet也就是用的最多的此外还有LinkedHashSet和TreeSet。HashSet是无序的、不可重复的。通过对象的hashCode和equals方法保证对象的唯一性。HashSet内部的存储结构是哈希表是线程不安全的。2TreeSetTreeSet对元素进行排序的方式元素自身具备比较功能需要实现Comparable接口并覆盖compareTo方法。元素自身不具备比较功能需要实现Comparator接口并覆盖compare方法。3LinkedHashSetLinkedHashSet是一种有序的Set集合即其元素的存入和输出的顺序是相同的。16、说一下 HashSet 的实现原理HashSet实际上是一个HashMap实例数据存储结构都是数组链表。HashSet是基于HashMap实现的HashSet中的元素都存放在HashMap的key上面而value都是一个统一的对象PRESENT。private static final Object PRESENT new Object();AI生成项目HashSet中add方法调用的是底层HashMap中的put方法put方法要判断插入值是否存在而HashSet的add方法首先判断元素是否存在如果存在则插入如果不存在则不插入这样就保证了HashSet中不存在重复值。通过对象的hashCode和equals方法保证对象的唯一性。17、ArrayList 和 LinkedList 的区别是什么ArrayList是动态数组的数据结构实现查找和遍历的效率较高LinkedList 是双向链表的数据结构增加和删除的效率较高18、如何实现数组和 List 之间的转换String[] arr {zs,ls,ww};ListString list Arrays.asList(arr);System.out.println(list);ArrayListString list1 new ArrayListString();list1.add(张三);list1.add(李四);list1.add(王五);String[] arr1 list1.toArray(new String[list1.size()]);System.out.println(arr1);for(int i 0; i arr1.length; i){System.out.println(arr1[i]);}19、在 Queue 中 poll()和 remove()有什么区别1offer()和add()区别增加新项时如果队列满了add会抛出异常offer返回false。2poll()和remove()区别poll()和remove()都是从队列中删除第一个元素remove抛出异常poll返回null。3peek()和element区别peek()和element用于查询队列头部元素为空时element抛出异常peek返回null。20、哪些集合类是线程安全的Vector就比Arraylist多了个同步化机制线程安全。Stack栈也是线程安全的继承于Vector。Hashtable就比Hashmap多了个线程安全。ConcurrentHashMap:是一种高效但是线程安全的集合