2022-03-22
1.正数的原码、反码、补码都一样
2.负数的反码 = 它的原码符号位不变,其他位取反(取反的意思:0 换成 1 、 1 换成 0 )
3.负数的补码 = 它的反码 +1
4.0的反码、补码都是0
在编译阶段根据静态类型可以确定重载方法
重写方法是在运行期间动态分派的
继承是面向对象三大特征之一,可以使得子类具有父类的属性和方法,还可以在子类中重新定义,以及追加属性和方法。
Java中类只支持单继承,不支持多继承
Java中类支持多层继承
内部实现分为三个步骤:先比较引用是否相同(是否为同一对象),再判断类型是否一致(是否为同一类型),最后比较内容是否一致。
1.举例说明不重写会出现什么问题
public static void main(String[] args) { Student stu1 = new Student("张三", 20); Student stu2 = new Student("张三", 20); System.out.println(stu1.equals(stu2)); }不重写结果会返回false
2.说明出现问题的原因
equals方法默认继承的Object类,默认比较两个对象的内存地址
3.说明重写后解决了问题
重写后返回true
1.举例说明不重写会出现什么问题
public static void main(String[] args) { Student stu1 = new Student("张三", 20); Student stu2 = new Student("张三", 20); Map map = new HashMap(); map.put(stu1, 1); map.put(stu2, 2); System.out.println(map); }利用hashmap举例,上面已经重写了equals方法,理论上key相同的话,应该数据会被覆盖,但实际上打印了两个值,如下
2.说明出现问题的原因
因为在HashMap中,是根据key的hashcode值确定数组下标位置的,如果数组下标位置相同,先比较key的hashcode值,如果相同,再用equals方法对比,如果相等,则覆盖。
而如果不重写hashcode方法,默认比较的是物理地址,则stu1和stu2的hashcode值不同
3.说明重写后解决了问题
@Override public int hashCode() { return Objects.hash(name, stuId); }重写后两个对象的hashcode值相同,可以覆盖,结果打印一个值
1.说出结果
创建 1 个或者 2 个对象
2.解释结果
new String 会先去常量池中判断有没有此字符串,如果有则只在堆上创建一个字符串并且指向常量池中的字符串,如果常量池中没有此字符串,则会创建 2 个对象,先在常量池中新建此字符串,然后把此引用返回给堆上的对象
1.解释概念
值传递(pass by value)是指在调用函数时将实际参数复制一份传递到函数中,在函数内对参数进行修改,不会影响到实际参数。
引用传递(pass by reference)是指在调用函数时将实际参数的地址直接传递到函数内,在函数内对参数所进行的修改,将影响到实际参数。
2.java参数传递特点
如果是基础类型,那么在方法传递的时候复制的是(栈中)基础类型的引用和值,如果是引用类型复制的是(栈中)引用地址。
3.结论
在Java中本质上只有值传递,也就说Java的传参只会传递它的副本,并不会传递参数本身
详解
1.总体说明static关键字的应用范围
static 关键字可用于变量、方法、代码块和内部类,表示某个特定的成员只属于某个类本身,而不是该类的某个对象。
2.分条说明用法
2.1静态变量
1)由于静态变量属于一个类,所以不要通过对象引用来访问,而应该直接通过类名来访问。
2)不需要初始化类就可以访问静态变量。
2.2静态方法
1)Java 中的静态方法在编译时解析,因为静态方法不能被重写(方法重写发生在运行时阶段,为了多态)。
2)抽象方法不能是静态的。
3)静态方法不能使用 this 和 super 关键字。
4)成员方法可以直接访问其他成员方法和成员变量。
5)成员方法也可以直接方法静态方法和静态变量。
6)静态方法可以访问所有其他静态方法和静态变量。
7)静态方法无法直接访问成员方法和成员变量。
2.3静态代码块
1)一个类可以有多个静态代码块。
2)静态代码块的解析和执行顺序和它在类中的位置保持一致。
2.4静态内部类
1)静态内部类不能访问外部类的所有成员变量。
2)静态内部类可以访问外部类的所有静态变量,包括私有静态变量。
3)外部类不能声明为 static。
1.从使用上说
1.1final变量
final变量有成员变量或者是本地变量(方法内的局部变量),在类成员中final经常和static一起使用,作为类常量使用。其中类常量必须在声明时初始化,final成员常量可以在构造函数初始化。
1.2final方法
final方法表示该方法不能被子类的方法重写
1.3final类
final类不能被继承,final类中的方法默认也会是final类型的,java中的String类和Integer类都是final类型的。
2.使用细节
1)final成员变量必须在声明的时候初始化或者在构造器中初始化,否则就会报编译错误。final变量一旦被初始化后不能再次赋值。
2)本地变量必须在声明时赋值。 因为没有初始化的过程
3)在匿名类中所有变量都必须是final变量。
4)final方法不能被重写, final类不能被继承
5)接口中声明的所有变量本身是final的。类似于匿名类
6)final和abstract这两个关键字是反相关的,final类就不可能是abstract的。
7)final方法在编译阶段绑定,称为静态绑定(static binding)。
8)将类、方法、变量声明为final能够提高性能,这样JVM就有机会进行估计,然后优化。
3.final好处(为什么使用final)
1)提高了性能,JVM在常量池中会缓存final变量
2)final变量在多线程中并发安全,无需额外的同步开销
3)final方法是静态编译的,提高了调用速度
4)final类创建的对象是只可读的,在多线程可以安全共享
1.语法层面上的区别
1)抽象类可以提供成员方法的实现细节,而接口中只能存在public abstract 方法;
2)抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的;
3)接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态方法;
4)一个类只能继承一个抽象类,而一个类却可以实现多个接口。
2.设计层面上的区别
2.1抽象类是对整个类整体进行抽象,包括属性、行为,但是接口却是对类局部(行为)进行抽象。
举个简单的例子,飞机和鸟是不同类的事物,但是它们都有一个共性,就是都会飞。那么在设计的时候,可以将飞机设计为一个类Airplane,将鸟设计为一个类Bird,但是不能将 飞行 这个特性也设计为类,因此它只是一个行为特性,并不是对一类事物的抽象描述。此时可以将 飞行 设计为一个接口Fly,包含方法fly( ),然后Airplane和Bird分别根据自己的需要实现Fly这个接口。
2.2抽象类作为很多子类的父类,它是一种模板式设计。而接口是一种行为规范,它是一种辐射式设计。
模板式设计:
大家都用过ppt里面的模板,如果用模板A设计了ppt B和ppt C,ppt B和ppt C公共的部分就是模板A了,如果它们的公共部分需要改动,则只需要改动模板A就可以了,不需要重新对ppt B和ppt C进行改动。
辐射式设计:
比如某个电梯都装了某种报警器,一旦要更新报警器,就必须全部更新
1.缓冲范围-128-127
2.面试题
3.底层源码和原理
private static class IntegerCache { static final int low = -128; static final int high; static final Integer cache[]; static { // high value may be configured by property int h = 127; String integerCacheHighPropValue = VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); if (integerCacheHighPropValue != null) { try { int i = parseInt(integerCacheHighPropValue); i = Math.max(i, 127); // Maximum array size is Integer.MAX_VALUE h = Math.min(i, Integer.MAX_VALUE - (-low) -1); } catch( NumberFormatException nfe) { // If the property cannot be parsed into an int, ignore it. } } high = h; cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k = 127; } private IntegerCache() {} }1)内部使用的cache数组作为缓存数据的机制;
2)使用了low、high分别作为缓存的数值的最小值和最大值;
3)low实际上是一个固定的值-128;
4)high是可以设置的:
1.编译性语言和解释性语言概念
编译型语言:把做好的源程序全部编译成二进制代码的可运行程序。然后,可直接运行这个程序。
解释型语言:把做好的源程序翻译一句,然后执行一句,直至结束!
2.java为什么是解释性语言
虽然java也需要编译,编译成.class文件,但是并不是机器可以识别的语言,而是字节码,最终还是需要 jvm的解释,才能在各个平台执行,这同时也是java跨平台的原因。
在Java中,使用 { } 括起来的代码被称为代码块
局部代码块
构造代码块
静态代码块
在一个类中定义一个类。举例:在一个类A的内部定义一个类B,类B就被称为内部类
当发现某个方法需要,接口或抽象类的子类对象,我们就可以传递一个匿名内部类过去,来简化传统的代码
/* 游泳接口 */ interface Swimming { void swim(); } public class TestSwimming { public static void main(String[] args) { goSwimming(new Swimming() { @Override public void swim() { System.out.println("铁汁, 我们去游泳吧"); } }); } /** * 使用接口的方法 */ public static void goSwimming(Swimming swimming){ /* Swimming swim = new Swimming() { @Override public void swim() { System.out.println("铁汁, 我们去游泳吧"); } } */ swimming.swim(); } }
常见的解析工具
DOM4J: 开源组织提供了一套XML的解析的API-dom4j,全称:Dom For Java
xml解析就是从xml中获取到数据
元注解就是描述注解的注解
因为存储数据的char数组是使用final进行修饰的,所以不可变。
这是因为在StringBuffer类内,常用的方法都使用了synchronized 进行同步所以是线程安全的,然而StringBuilder并没有。这也就是运行速度StringBuilder > StringBuffer的原因了。
Java 的反射机制是指在运行状态中,对于任意一个类都能够知道这个类所有的属性和方法; 并且对于任意一个对象,都能够调用它的任意一个方法;这种动态获取信息以及动态调用对象方法的功能成为Java语言的反射机制。
HashMap采用key/value存储结构,每个key对应唯一的value,查询和修改的速度都很快,能达到O(1)的平均时间复杂度。它是非线程安全的,且不保证元素存储的顺序。key值和vaule都可以为空。
不保证元素存储的顺序
Map mp = new HashMap(); for (int i=0; i System.out.println(entry.getKey() + "-" + entry.getValue()); }结果
key1-value1 key2-value2 key0-value0 key5-value5 key6-value6 key3-value3 key4-value4 key9-value9 key7-value7 key8-value8如果想要有序,采用LinkedHashMap
jdk1.7中采用数组+链表
1.7中hashmap有一个内部类Entry,每添加一个新的键值对就将它封装到一个Entry对象中,然后放进容器中。
jdk1.8采用数组+链表+红黑树
数组元素和链表节点采用内部类Node类实现,与jdk1.7的Entry类对比,仅仅只是换了名字。而红黑树采用TreeNode类实现
1)引入红黑树的原因
加快查询速度
数组的查询效率为O(1),链表的查询效率是O(k),红黑树的查询效率是O(log k),k为桶(数组的一个元素又称作桶)中的元素个数,所以当元素数量非常多的时候,转化为红黑树能极大地提高效率。
2)转换阈值
数组长度大于等于64,且链表长度大于等于8,将链表转换成红黑树。
当红黑树中节点数量小于等于6,则将红黑树还原回链表
3)为什么转换阈值是8和6
根据泊松分布,hash碰撞发生8次的概率非常低,此时链表性能已经非常差,后序可能还会继续发生hash碰撞。转换成红黑树主要出于性能考虑。
而红黑树转链表的阈值为6,主要是因为,如果也将该阈值设置于8,那么当hash碰撞在8时,会反生链表和红黑树的不停相互激荡转换,白白浪费资源。
4)为什么采用红黑树而不是平衡二叉树
对于插入删除等操作,红黑树效率更高。原因是平衡二叉树对于平衡性的要求更高,在调整平衡的过程中消耗更大。
详解
5)补充:红黑树的介绍
是一种特殊的二叉查找树
1)hashmap采用的方法
链地址法
hashmap中的hash算法本质上分为三步:取key的hashCode值、高位运算、取模运算
jdk1.8中优化了高位运算的算法,(h = key.hashCode()) ^ (h >>> 16)主要考虑性能优化,使得数组较小的时候,也能保证考虑到高低位都参与到Hash的计算中,同时不会有太大的开销。
第三步取模运算采用h & (table.length -1)。因为HashMap底层数组的长度总是2的n次方。当length总是2的n次方时,h& (length-1)运算等价于对length取模,也就是h%length,但是&比%具有更高的效率。
2)解决hash冲突的主要方法
(1)开放定址法(2)链地址法(3)再哈希法(4)公共溢出区域法
米加小镇世界苹果手机版下载v1.87 iphone手机版
其它手游 894M
下载王牌战争ios版下载v2.31.0 iphone手机版
其它手游 2G
下载四川麻将免费下载v7.10.382 安卓手机版
其它手游 1.65G
下载出发吧麦芬手游下载v1.0.19 安卓版
角色扮演 1.72G
下载跑跑卡丁车游戏下载v1.35.2 安卓最新版
赛车竞速 1.98G
下载剑侠世界起源手游官方版下载v1.18.2 安卓版
角色扮演 693.5M
下载光遇官服下载v0.13.3 安卓正版
休闲益智 1.73G
下载开心消消乐官方正版下载v1.140 安卓手机版
休闲益智 444.1M
下载欢乐斗地主官方正版下载v8.032.016 安卓完整版
下载
宝宝巴士奇妙屋游戏官方版下载v9.83.31.11 安卓版
下载
腾讯欢乐麻将全集最新版下载v7.9.63 官方安卓版
下载
以闪亮之名官方正版下载v2.1.8 安卓国服
下载
剑与远征最新版本下载v1.156.01 安卓版
下载
冲呀饼干人王国游戏下载v2.1.1 安卓版
下载
尘白禁区手游官方版下载v2.4.0.98 安卓版
下载
合金弹头觉醒手游正版下载v1.15.0 官方安卓版
下载