湖北省住房部城乡建设厅网站首页,网站制作哪家公司好,有没有做西餐的视频网站,能够做渗透的网站java基础1.什么是面向对象#xff0c;谈谈对面向对象的理解2.JDK JRE JVM的区别与联系3.和equals4.hashCode与equals5.String StringBuffer StringBuilder的区别6.重载和重写的区别7.接口和抽象类8.List和Set的区别9.ArrayList和LinkedList10.HashMap和HashTable的区别#x…
java基础1.什么是面向对象谈谈对面向对象的理解2.JDK JRE JVM的区别与联系3.和equals4.hashCode与equals5.String StringBuffer StringBuilder的区别6.重载和重写的区别7.接口和抽象类8.List和Set的区别9.ArrayList和LinkedList10.HashMap和HashTable的区别底层实现是什么11.谈谈ConcurrentHashMap的扩容机制12.从jdk1.7到jdk1.8虚拟机发生了什么变化13.说一下HashMap的put方法14.泛型中extends和super的区别15.深拷贝和浅拷贝16.HashMap的扩容机制17.CopyOnWriteArrayList的底层原理是怎样的18.java中的异常体系19.什么是字节码字节码的好处是什么20.数据库连接池的工作原理和实现方案21.什么是反射22.switch的作用范围23.和的区别24.short类型与int类型计算25.数组和String有没有length()方法26.最有效率的方法计算2乘以827.Integer常量池的范围在 -128~127 之间28.java中实现多态的机制是什么29.构造方法有哪些特性30.值传递和引用传递的区别31.final关键字31.fianl和static的区别32.静态变量和实例变量的区别33.静态方法和实例方法有何不同34.String str “i” 和String str new String(“1”)一样吗35.String类的常用方法36.String中的equals是如何重写的37.Object类中finalize()方法作用38.System.gc() 和 Runtime.gc() 作用39.内部类可以引用它的包含类外部类的成员吗40.简单概述下异常41.什么是序列化以及序列化的优势42.集合和数组的区别1.什么是面向对象谈谈对面向对象的理解
和面向过程相比它们是两种不同的处理问题的角度。
面向过程更注重事情的每一个步骤及顺序面向对象更注重事情有哪些参与者以及它们各自需要做什么。比如洗衣机洗衣服
面向过程会将任务拆解成一系列的步骤(函数)打开洗衣机 --- 放衣服 --- 放洗衣粉 --- 清洗 --- 烘干
面向对象会拆出人和洗衣机两个对象人打开洗衣机、放衣服、放洗衣粉 洗衣机清洗、烘干面向对象三大特性封装、继承、多态
封装明确标识出允许外部使用的所有成员函数和数据项内部细节对外部调用透明外部调用无需关心内部实现
继承子类继承父类的方法并且可以做出自己的改变和拓展
多态基于对象所属类不同外部对同一个方法的调用实际执行逻辑不同。继承 方法重写 父类引用指向子类对象 父类类型 变量名 new 子类对象; 变量名.方法名();2.JDK JRE JVM的区别与联系
JDKjava开发工具包含JRE和java开发所需要的工具JREjava运行时环境包含JVM和类库JVMjava虚拟机运行编译好的字节码文件每个系统的JVM不同因此可以实现一处编译处处运行3.和equals
1
在比较基本数据类型的时候 比较的是变量值在比较引用类型的时候 比较的是堆中内存对象的地址2equals
在没有重写时equals和相同但是equals通常会重写。
比如String中equlas被重写比较的是两个字符串的内容。4.hashCode与equals
hashCode的作用是获取哈希码也称为散列码哈希码的作用是确定该对象在哈希表中的索引位置。散列表中存储时的是键值对
能根据key快速的检索出对应的value。以HashSet检查重复为例
对象加入HashSet时HashSet会先计算对象的hashCode值来判断对象加入的位置看该位置是否有值。如果没有hashSet
会假设对象没有重复出现。如果有值这时会调用equals()方法来检查两个对象的值是否真的相同如果两者相同HashSet
就不会让其加入集合如果不同就会重新散列到其他位置。这样就大大减少了equals的次数相应就大大提高了执行速度。如果两个对象相等则hashCode一定也相同
两个对象相等对两个对象分别调用equals方法返回true
两个对象有相同的hashCode值它们也不一定相等5.String StringBuffer StringBuilder的区别
String是不可变的如果尝试修改会新生成一个字符串对象StringBuffer 和StringBuilder是可变的。
StringBuffer 是线程安全的StringBuilder线程不安全所以在单线程下StringBuilder效率更高6.重载和重写的区别
重载发生在同一个类中方法名相同参数列表不同返回值类型和访问修饰符可以不同重写发生在子类和父类中子类重写父类方法方法名相同参数列表相同返回值范围 父类抛出异常的范围 父类
访问修饰符的范围 父类子类不能重写父类私有方法7.接口和抽象类
抽象类中可以定义抽象方法也可以定义普通方法。 接口中只能定义抽象方法。抽象类中的成员变量可以是各种类型的。 接口中的成员变量只能是public static final类型的。抽象类的设计目的是代码复用。 接口的设计目的是对类的行为进行约束。一个类只能继承一个抽象类在这个抽象类中必须继承或编写出其所有子类的所有共性。因此定义抽象类的代价高。
一个类可以实现多个接口因此在设计阶段难度会降低。8.List和Set的区别
List有序(按对象进入的顺序保存对象) 不去重 允许多个null元素对象。Set无序 去重 最多允许有一个null元素对象。9.ArrayList和LinkedList
ArrayList底层是基于数组实现的。 LinkedList底层是基于链表实现的。ArrayList更适合随机查找。 LinkedList更适合删除和添加。ArrayList和LinkedList都实现了List接口但LinkedList还额外实现了Deque接口可以当作队列来使用。10.HashMap和HashTable的区别底层实现是什么
HashMap是非线程安全的。 HashTable的方法有synchronized关键字修饰是线程安全的。HashMap允许key和value为null。 HashTable不允许。HashMap底层实现
JDK1.7数组链表
JDK1.8数组链表红黑树链表高度到8、数组长度超过64链表会转为红黑树。
1计算key的hash值二次hash然后对数组长度取模对应到数组下标。
2如果没有产生hash冲突(下标位置没有元素)则直接创建Node存入数组。
3如果产生hash冲突先进行equals比较相同则取代该元素不同则判断链表高度插入链表链表高度达到8并且数组
长度到64则转变为红黑树长度低于6则将红黑树转回到链表。
4key如果为null存在下标0的位置。11.谈谈ConcurrentHashMap的扩容机制
JDK1.7
11.7版本的ConcurrentHashMap是基于Segment分段实现的
2每个Segment相当于一个小型的HashMap
3每个·Segment内部会进行扩容和HashMap的扩容逻辑类似
4先生成新的数组然后转移原数到新数组中
5扩容的判断也是每个Segment内部单独判断的判断是否超过阈值JDK1.8
11.7版本的ConcurrentHashMap不再基于Segment实现而是以每个数组下标作为节点实现
2当某个线程进行put时如果发现ConcurrentHashMap正在进行扩容那么该线程一起进行扩容
3如果某个线程put时发现没有正在进行扩容则将key-value添加到ConcurrentHashMap中然后判断是否超过阈值
超过了则进行扩容
4ConcurrentHashMap支持多个线程同时扩容
5扩容之前也先生成一个新的数组
6在转移元素时先将原数组分组将每组分给不同的线程来进行元素的转移每个线程负责一组或多组的元素转移工作12.从jdk1.7到jdk1.8虚拟机发生了什么变化
JDK1.7中存在永久代JDK1.8中永久代变为元空间。元空间所占的内存不是在JVM内部而是在本地内存空间。不管是永久代还是元空间都是方法区的具体实现。原因
方法区所存储的类信息通常是比较难确定的所以对于方法区的大小是比较难指定的太小了容易出现方法区溢出太大了又会
占用太多JVM的内存空间而转移到本地内存后则不会影响JVM所占用的内存。13.说一下HashMap的put方法
1、根据key通过二次hash使用二次hash得到的值对数组长度取模运算得到数组下标2、如果该数组下标位置为空则将key和value封装为对象并放入该位置3、如果该数组下标位置元素不为空则1如果是JDK1.7则先判断是否需要扩容如果需要扩容就进行扩容如果不需要扩容就生成对象并使用头插法添加到当前链表中2如果是JDK1.8则会先判断当前位置上的类型看是红黑树还是链表a.如果是红黑树则将key和value封装为一个红黑树节点并添加到红黑树去在这个过程中会判断红黑树是否存在当前key如果存在则更新valueb.如果是链表则将key和value封装为链表节点并通过尾插法插入到链表的最后位置去在过程中遍历链表判断是否存在当前key如果存在就更新value。插入到链表后会看当前链表的结点个数如果节点个数超过了8并且数组长度超过了64则将链表转成红黑树c.将key和value插入到链表或红黑树中后再判断是否需要进行扩容如果需要就扩容如果不需要就结束put方法14.泛型中extends和super的区别
? extends T 表示包括T在内的任何T的子类? super T 表示T在内的任何T的父类15.深拷贝和浅拷贝
深拷贝和浅拷贝就是指对象的拷贝一个对象中会存在两种类型的属性一种是基本数据类型一种是引用数据类型1浅拷贝只会拷贝基本数据类型的值以及实例对象的引用地址并不会复制一份引用地址所指向的对象2深拷贝既会拷贝基本数据类型的值也会针对实例对象的引用地址所指向的对象进行复制16.HashMap的扩容机制
JDK1.7
1当数组中的容量达到总容量的0.75的时候开始扩容扩容为旧数组的两倍容量先生成新的数组
2遍历旧数组中的每个位置上的链表上的每个元素
3取每个元素的key并基于新数组的长度计算出每个元素在新数组中的下标
4将所有元素添加到新数组中
5所有元素转移完了之后将新数组赋值给HashMap对象的table属性JDK1.8
1当数组中的容量达到总容量的0.75的时候开始扩容扩容为旧数组的两倍容量先生成新的数组
2遍历旧数组中的每个位置上的链表或者红黑树
3如果是链表遍历链表上的每个元素并根据它们的key重新计算数组下标并添加到新数组中去
4如果是红黑树则先遍历红黑树根据每个元素的key计算出该元素在新数组中的下标位置a.统计每个下标位置的元素个数b.如果该位置下的元素个数超过了8则生成一个新的红黑树并将根节点添加到新数组的对应位置c.如果该位置下的元素个数没有超过8则生成链表并将链表的头节点添加到新数组的对应位置
5所有元素转移完了之后将新数组赋值给HashMap对象的table属性17.CopyOnWriteArrayList的底层原理是怎样的
1CopyOnWriteArrayList的内部也是用数组实现的在向CopyOnWriteArrayList添加元素时会复制一个新的数组写操作在新数组上进行读操作在原数组上进行2写操作的时候会加锁防止出现并发写入丢失数据的问题3写操作结束之后会把原数组指向新数组4CopyOnWriteArrayList允许写操作时来读取数据大大提高了读的性能因此适合读多写少的应用场景但是CopyOnWriteArrayList会比较占内存同时可能读到的数据不是实时最新的数据所以不适合实时性要求很高的场景18.java中的异常体系
1java中的所有异常都是来自顶级父类ThrowableThrowable下有两个子类Exception和Error2Error是程序无法处理的错误一旦出现这个错误则程序将被迫停止运行3Exception不会导致程序停止又分为两个部分RuntimeException和CheckedExceptionRuntimeException常常发生在程序运行过程中会导致程序当前线程执行失败CheckedException常常发生在程序编译过程中会导致编译不通过19.什么是字节码字节码的好处是什么
编译器(javac)将java源文件(*.java)编译成为字节码文件(*.class)。可以做到一处编译到处运行windows上编译好的
class文件可以直接在linux上运行通过这种方式可以做到跨平台。java跨平台有一个前提条件就是不同的操作系统上安装的JDK和JRE是不一样的虽然字节码是通用的但是需要把字节码
解释成各个操作系统的机器码需要不同的解释器所以针对各个操作系统需要有各自的JDK或JRE采用字节码的好处
1可以实现跨平台
2提高了代码执行的性能编译器在编译源码时可以做一些编译期的优化比如锁消除、标量替换、方法内联等20.数据库连接池的工作原理和实现方案
1数据库连接是一种关键的有限的昂贵资源对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性影响到程序的性能指标2数据库连接池负责分配、管理和释放数据库连接它允许应用程序重复使用一个现有的数据库连接而不是重新建立一个3释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接泄露4数据库连接池在初始化时将创建一定数量的数据库连接放到连接池中这些数据库连接的数量是由最小数据库连接数来设定的。无论这些数据库连接是否被使用连接池都将一直保证至少这么多的连接数量5连接池的最大数据库连接数量限定了这个连接池能占有的最大连接数当应用程序向连接池请求的连接数超过最大连接数量时这些请求将被加入到等待队列中21.什么是反射
1反射是用来描述类的信息的2对于任意一个类都能够知道这个类的所有属性和方法3对于任意一个对象都能够调用它的任意一个方法和属性4这种动态获取类的信息以及动态调用对象的方法的功能称为java语言的发射机制22.switch的作用范围
1可以用在byte short char int enum String2不可以long23.和的区别
1逻辑与 短路与2它们在程序中最终的运算结果是完全一致的如果是运算发不管左边是true还是false右边表达式一定会执行 如果是如果左边表达式的结果为false,右边表达式不执行3运算符还可以使用在二进制位运算上按位与24.short类型与int类型计算
1short s1 1; s1 s11; 这个是错误的由于1是int类型因此 s11的运算结果也是int类型需要强制类型转换才能赋值给short类型2short s1 1; s1 1; 这个是正确的因为s1 1相当于s1 (short)(s11)其中有隐含的强制类型转换25.数组和String有没有length()方法
数组中只有length属性
String有length()方法26.最有效率的方法计算2乘以8
23将2左移3位27.Integer常量池的范围在 -128~127 之间
public class Test {public static void main(String[] args) {Integer t1100,t2100,t3130,t4130;System.out.println(t1t2);//trueSystem.out.println(t3t4);//false//因为t1/t2的值在 -128~127 之间,那么不会new新的Integer对象//而是直接引用常量池中的Integer对象,所以结果是true}}28.java中实现多态的机制是什么
父类或接口定义的引用变量可以指向子类或者具体实现类的实例对象而程序调用的方法在运行期才动态绑定
就是引用变量所指向的具体实例对象的方法也就是内存里正在运行的这个对象的方法而不是引用变量的类
型中定义的方法29.构造方法有哪些特性
1名字与类名相同2没有返回值3生成类的对象时自动执行无需调用4不可以被重写的那可以被重载30.值传递和引用传递的区别
1值传递指在调用方法时将实际参数复制一份到方法中这样的话如果方法对其传递过来的形式参数进行修改将不会影响到实际参数2引用传递指在调用方法时将对象的地址直接传递到方法中如果在对形式参数进行修改将影响到实际参数的值31.final关键字
1被final关键字修饰的类不能被继承。final类中的成员变量可以根据需要设为final但是final类中的所有成员方法都会被隐式地指定为final方法2被final修饰地方法不能被重写以防任何继承类修改它3被final修饰的基本数据类型的变量其数值一旦在初始化之后便不能更改被final修饰的引用类型的变量则在对其初始化之后便不能再让其指向另一个对象但是它指向的对象的内容可以改变31.fianl和static的区别
static数于类级别的不可变而final是对象级别的不可变32.静态变量和实例变量的区别
1静态变量是不属于任何实例对象属于类的在内存中只会有一份在类的加载过程中JVM只为静态变量分配一次内存空间2实例变量每次创建对象都会为每个对象分配成员变量内存实例变量是属于实例对象的在内存中创建几次对象就有几份成员变量33.静态方法和实例方法有何不同
1外部调用静态方法时可以使用 类名.方法名 和 对象名.方法名 两种方式而实例方法只有后面这种方式2静态方法在访问本类成员时只允许访问静态成员(即静态变量和静态方法)而实例方法则无此限制public class Test {public static void main(String[] args) {A bnew B();//执行到此处,结果为 1a2bbnew B();执行到此处,结果为 1a2b2b}}class A{static {System.out.println(1);}public A(){System.out.println(2);}
}class B extends A{static {System.out.println(a);}public B(){System.out.println(b);}
}34.String str “i” 和String str new String(“1”)一样吗
不一样因为内存的分配方式不一样
1String str “i” 的方式JVM会将其分配在常量池
2String str new String(i) 的方式JVM会将其分配在堆内存中String str new String(i)是创建了两个对象一个是静态存储区的i,一个是用new创建在堆上的对象35.String类的常用方法
public class Test {public static void main(String[] args) {String strabcd123;int a str.indexOf(a);//返回指定字符的索引char c str.charAt(2);//返回指定索引处的字符str.replace(a,A);//字符串替换 a:oldChar A:newCharstr.trim();//去除字符串两端空格//将字符串从d处分割,返回分割后的字符串数组 [abc,123]String[] ds str.split(d);byte[] bytes str.getBytes();//返回字符串byte类型数组[97 98 99 100 49 50 51]int length str.length();//返回字符串长度char[] chars str.toCharArray();//返回字符串char类型的数组String s str.toLowerCase();//将字符串转换为小写字母String s1 str.toUpperCase();//将字符串转换为大写字母//截取字符串 1:开始位置 3:结束位置,1位置的字符会被截取到 3位置的不会被截取到String substring str.substring(1, 3);boolean equals str.equals(1234);//比较字符串是否相等 }}36.String中的equals是如何重写的
1首先会判断要比较的两个字符串它们的引用是否相等如果相等的话直接返回true不相等的话继续判断2然后再判断被比较的对象是否是String的实例如果不是的话直接返回false3如果是的话再比较两个字符串的长度是否相等如果不相等的话直接返回false4长度如果相同会比较字符串中的每个字符是否相等一旦有一个字符不相等就直接返回false37.Object类中finalize()方法作用
垃圾回收器回收对象前会调用此方法可以在此方法中做释放资源等清理操作38.System.gc() 和 Runtime.gc() 作用
提示JVM要进行垃圾回收39.内部类可以引用它的包含类外部类的成员吗
一个内部类对象可以访问创建它的外部类对象的成员包括私有成员40.简单概述下异常
1Throwable是java语言中所有错误和异常的超类2Error类及其子类程序无法处理的错误表示运行应用程序中出现了严重的错误3Exception程序本身可以捕获并且处理的异常。Exception又分为两类运行时异常和编译时异常4运行时异常都是RuntimeException类及其子类异常如空指针异常、下标越界异常等这些异常是不检查异常程序中可以选择捕获处理也可以不处理。javac编译器不会检查它即使不捕获它或抛出它也会编译通过5编译异常从语法角度讲是必须进行处理的异常如果不处理程序就不能编译通过。如IOException、SQLException等以及用户自定义的Exception异常一般情况下不自定义检查异常。41.什么是序列化以及序列化的优势
1序列化就是指把对象转换为字节序列的过程序列化后的字节流保存了对象的状态以及相关的描述信息从而方便从网络上传输或者保存在本地文件中达到对象状态的保存与重建的目的2反序列化客户端从文件或网络上获得序列化后的对象字节流后根据字节流中所保存的对象状态及描述信息通过反序列化重建对象优势
1实现了数据的持久化通过序列化可以把数据永久的保存在硬盘上
2利用序列化实现远程通信即在网络上传送对象的字节序列
3通过序列化在进程间传递对象42.集合和数组的区别
1数组是固定长度的 集合是可变长度的2数组可以存储基本数据类型也可以存储引用数据类型 集合只能存储引用数据类型3数组存储的元素必须是同一个数据类型 集合存储的对象可以是不同数据类型