Java基础
this与super的区别:从本质上讲,this是一个指向本对象的指针,然而super是一个JAVA关键字
static存在的意义:
1.创建独立于具体对象的域变量或者方法
2.形成静态代码块用以优化代码
static的独特之处:
1.被static修饰代码独立于该类的任何对象,直接被类的实例对象所共享
2.在该类被第一次加载的时候,就会去加载被static修饰的部分
3.static变量值在类加载的时候分配空间,以后创建类对象的时候不会重新分配
4.被static修饰的变量或者方法是优先于对象存在的,也就是说当一个类加载完毕之后,即便没有创建 对象,也可以去访问。
在 Java 中,如何跳出当前的多重嵌套循环:
可以在外面的循环语句前定义一个标号,然后在里层循环体的代码中使 用带有标号的break 语句,即可跳出外层循环。
面向对象的三大特征:
抽象:抽象是将一类对象的共同特征总结出来构造类的过程。包括数据抽象和行为抽象。抽象只关注对象有哪些属性和行为,并不关注这些行为的细节。
封装:把一个对象的属性私有化,同时提供一些可以被外界访问的属性的方法,如果属性不想被外界访问,就可以不提供。但是没意义
继承:是使用已经存在的类的定义作为基础来建立新类的技术。新类的定义可以增加新的数据和新的功能,也可以使用父类的功能,但不能选择性的继承父类,
注意:
1.子类拥有父类非私有的属性和方法
2.子类也可以拥有自己的属性和方法,即对父类进行拓展
3.子类可以用自己的方式去实现父类的方法
多态:所谓多态就是指父类或接口定义的引用变量可以指向子类或具体实现类的实例对象,提高了程序的拓展性。
在java中有两种方式可以实现:
继承(多个子类对同一方法的重写)
接口(实现接口并覆盖接口中的统一方法)
方法重载实现的是编译时的多态性(也称前绑定),而方法重写实现的是运行时的多态性(也称后绑定)
抽象类和借口的对比:
抽象类是用来捕捉子类通用特性的,接口是接口方法的集合
内部类的优点:
一个内部类对象可以访问创建它的外部类对象的内容,包括私有数据!
内部类不为同一包的其他类所见,具有很好的封装性
内部类有效实现了“多重继承”,优化java单继承的缺陷
匿名内部类可以很方便的定义回调
局部内部类和匿名内部类访问局部变量是为什么一定要加final?
因为生命周期不一致,局部变量直接储存在栈中,当方法执行结束后,非final的局部变量就会被销毁,
==和equals的区别
==的作用是判断两个对象的地址值是否相等,即判断两个对象是不是同一个对象
(基本类型比较的是值,引用类型比较的是内存地址值)
equlas():它的作用是判断两个对象是否相等,但他一般有两种使用情况:
情况1:类没有覆盖 equals() 方法。则通过 equals() 比较该类的两个对象时, 等价于通过“==”比较这两个对象。
情况2:类覆盖了 equals() 方法。一般,我们都覆盖 equals() 方法来两个对象 的内容相等;若它们的内 容相等,则返回 true (即,认为这两个对象相等)。
hashCode 与 equals (重要)
HashSet如何检查重复?
JDK中常用的包有哪些?
java.lang:这个是系统的基础类;
java.io:这里面是所有输入输出有关的类,比如文件操作等;
java.nio:为了完善 io 包中的功能,提高 io 包中性能而写的一个新包;
java.net:这里面是与网络有关的类;
java.util:这个是系统辅助类,特别是集合类;
java.sql:这个是数据库操作的类。
BIO NIO AIO 有什么区别?
简答:
Java获取反射的三种方法:
1.通过new对象实现反射机制
2.通过路径实现反射机制
3.通过类名实现反射机制
字符型常量和字符串常量的区别:
形式上:一个是单引号,一个是双引号
String有哪些特性:
不变性,常量池优化,final
数组有没有 length()方法?String 有没有 length()方法:数组没有 length()方法 ,有 length 的属性。
String 类的常用方法都有那些?
indexOf():返回指定字符的索引。
charAt():返回指定索引处的字符。
replace():字符串替换。
trim():去除字符串两端空白。
split():分割字符串,返回一个分割后的字符串数组。
getBytes():返回字符串的 byte 类型数组。
length():返回字符串长度。
toLowerCase():将字符串转成小写字母。
toUpperCase():将字符串转成大写字符。
substring():截取字符串。
equals():字符串比较。
在使用HASHMAP的时候,用String做key有什么好处?
HashMap内部实现是通过key的hashcode来确定value的储存位置,,因为字符串是不变的,所以当创建字符串时,它的hashcode被缓存下来,不需要再次计算,所以相对于其他对象更快。
集合的特点:
对象封装数据,对象多了也需要储存,集合用于存储对象
对象的个数确定可以使用数组,对象的个数不确定可以用集合,因为集合是可变长度的。
集合和数组的区别:
数组是固定长度的,集合可变长度
数组可以存储基本数据类型,也可以存储引用数据类型。集合只能存储引用数据类型
数组存储的元素必须是同一数据类型,集合存储的对象可以是不同数据类型
数据结构:容器中存储数据的方式
使用集合框架的好处:
Map接口和Collection接口是所有集合框架的父接口:
List,Set,Map三者的区别?
list有序,元素可以重复,可以插入多个null值,元素有索引
set无序,不允许重复,只允许存入一个null值
map是一个键值对集合,key无序,唯一,value允许重复
List、Set、Map 是否继 承自 Collection 接口?
map不是
集合框架底层数据结构:
Collection :
List
List Arraylist: Object数组
LinkedList: 双向循环链表
Set
HashSet(无序,唯一):基于 HashMap 实现的,底层采用 HashMap 来保存元素
TreeSet(有序,唯一): 红黑树(自平衡的排序二叉树。) Map
Java集合的快速失败机制 “fail-fast”?
原因:“是java集合的一种错误检测机制,当多个线程对集合进行结构上的改变的操作 时,有可能会产生 failfast 机制。”
解决办法:
1. 在遍历过程中,所有涉及到改变modCount值得地方全部加上 synchronized。
2. 使用CopyOnWriteArrayList来替换ArrayList
怎么确保一个集合不能被修改?
可以使用 Collections. unmodifiableCollection(Collection c) 方法来创建一个 只读集合,这样改变集合 的任何操作都会抛出 Java. lang. UnsupportedOperationException 异常。
collection接口下的List接口 迭代器iterator是什么?迭代器提供遍历任何collectin的接口
我们可以从一个collertion中使用迭代器来获取迭代实例
如何边遍历边移除 Collection 中的元素?
边遍历边移除 iterator.remove();
Iterator 和 ListIterator 有什么区别?
iterator可以遍历set和list 而listiterator只能遍历list
Iterator 只能单向遍历,而 ListIterator 可以双向遍历(向前/后遍历)。
ListIterator 可以实现 Iterator 接口
遍历一个 List 有哪些不同的方式?
for 循环遍历
迭代器遍历
foreach循环遍历
每种方法的实现原理是什 么?
Java 中 List 遍历 的最佳实践是什么?
说一下 ArrayList 的优缺点?
优点?底层以数组实现,是一种随机访问模式,查找速度快
在顺序添加元素的时候非常方便
缺点?删除元素的时候也需要做一次元素复制操作,如果复制的元素较多,就会耗费性能
插入元素的时候也同上
如何实现数组和 List 之间的转换?
数组转 List:使用 Arrays. asList(array) 进行转换。
List 转数组:使用 List 自带的 toArray() 方法。
ArrayList 和 LinkedList 的区别是什么?
1.ArrayList是动态数组的数据结构实现,而LinkList是双向链表的数据结构实现
2.ArrayList比LinkList访问效率要快,因为arraylist是随机访问数据,而linklist是线性访问,比较慢
3.在非首尾进行增删操作时,linkedlist比arraylist效率高,因为arraylist删除数据要影响其他数据的下标
4.linkerlist比arrsylist要更占内存,因为linkedlist除了储存数据,还要储存两个引用,一个指向前一个因素,一个指向后一个因素。
5.线程都不安全,
多线程场景下如何使用 ArrayList?
ArrayList 不是线程安全的,如果遇到多线程场景,可以通过 Collections 的 synchronizedList 方法将其转换成线程安全的容器后再使用
Set接口
说一下 HashSet 的实现原理?
HashSet 是基于 HashMap 实现的,HashSet的值存放于HashMap的key上
关于hashset的去重:
因为hashmap的key是唯一的,以此来判断
hashCode()与equals()的相关规定:
. 如果两个对象相等,则hashcode一定也是相同的
2. 两个对象相等,对两个equals方法返回true
3. 两个对象有相同的hashcode值,它们也不一定是相等的
4. 综上,equals方法被覆盖过,则hashCode方法也必须被覆盖
5. hashCode()的默认行为是对堆上的对象产生独特值。如果没有重写hashCode(),则该class的两个 对象无论如何都不会相等(即使这两个对象指向相同的数据)。
说一下 HashMap 的实现原理?
HashMap 基于 Hash 算法实现的,
1. 当我们往Hashmap中put元素时,利用key的hashCode重新hash计算出当前对象的元素在数组中 的下标
2. 存储时,如果出现hash值相同的key,此时有两种情况。(1)如果key相 同,则覆盖原始值;(2)如果key不同(出现冲突),则将当前的key-value 放入链表中
3. 获取时,直接找到hash值对应的下标,在进一步判断key是否相同,从而找到对应值。
4.核心就是使用了数组的存储方 式,然后将冲突的key的对象放入链表中,一旦发现冲突就在链表中做进一步的对比。
需要注意Jdk 1.8中对HashMap的实现做了优化,当链表中的节点数据超过八个 之后,该链表会转为红黑树来提高查询效率,从原来的O(n)到O(logn)
HashMap的扩容操作是怎么实现的?
HashMap是怎么解决哈希冲突的?
1. 使用链地址法(使用散列表)来链接拥有相同hash值的数据;
2. 使用2次扰动函数(hash函数)来降低哈希冲突的概率,使得数据分布更平均;
3. 引入红黑树进一步降低遍历的时间复杂度,使得遍历更快;
能否使用任何类作为 Map 的 key?
可以使用任何类作为 Map 的 key,然而在使用之前,需要考虑以下几点: 如果类重写了 equals() 方 法,也应该重写 hashCode() 方法。类的所有实例需要遵循与 equals() 和 hashCode() 相关的规则。
为什么HashMap中String、Integer这样的包装类适合作为K?
String、Integer等包装类的特性能够保证Hash值的不可更改性和计算准确性,能够有效的减少 Hash碰撞的几率
(都是final类型,即不可变性,保证key的不可更改性,不会存在获取 hash值不同的情况 内部已重写了equals()、hashCode()等方法,遵守了HashMap内部的规范(不清楚可以去上面看看 putValue的过程),不容易出现Hash值计算错误的情况)
Vector,ArrayList, LinkedList的区别是什么?
vector和arraylist都是以数组的形式存储在内存中的,linkedlist是以链表的形式
list中允许有重复的元素,set中不允许重复
vector线程同步,arraylist,linkerlist线程不同步
linkerlist适合插入,删除,不适合查找,arraylist适合查找,不适合插入删除
arraylist在元素填满容器时,会自动扩容50%,而vector是100%,所以arraylist更节省空间
HashMap的数据结构:
jdk1.8之前list + 链表
jdk1.8之后list + 链表(当链表长度到8时,转化为红黑树)
HashMap的扩容因子:
默认0.75,也就是会浪费1/4的空间,达到扩容因子时,会将list扩容一倍,0.75 是时间与空间一个平衡 值;
说说你知道的几个Java集合类:
list、set、queue、map 实现类
String 编码UTF-8 和GBK的区别:
GBK编码:是指中国的中文字符,其实它包含了简体中文与繁体中文字符,另外还有一种字符 “gb2312”,这种字符仅能存储简体中文字符。 UTF-8编码:它是一种全国家通过的一种编码,如果你的网站涉及到多个国家的语言,那么建议你 选择UTF-8编码。
UTF8编码格式很强大,支持所有国家的语言,正是因为它的强大,才会导致它占用的空间大小要比GBK 大,对于网站打开速度而言,也是有一定影响的。 GBK编码格式,它的功能少,仅限于中文字符,当然它所占用的空间大小会随着它的功能而减少,打开 网页的速度比较快。
Java 和 C++的区别
都是面向对象的语言,都支持封装,继承,多态
java不提供直接访问内存,程序内存更加安全
java的类是单继承的,c++是多重继承的,
java有自动内存管理机制,不需要程序员手动释放无用内存
异常:
用来封装错误信息的对象,由 异常类型 报错信息 报错行号 组成
继承结构:父类Throwable
error:我们无法修复的错误:如虚拟机运行错误,ViryulMachineErrorJava
栈内存溢出错误:StarkOverFlowError
内存溢出错误:OutOfMemoryError
exception:我们可以修复的错误:如运行时异常:RuntimeException
编译时异常
注意:编译时异常一定要处理,运行时异常不一定不报错
程序错误分类:
编译错误,运行时错误,逻辑错误
为什么要使用spring?
spring提供ioc技术,容器会帮你管理依赖的对象,从而不需要自己创建和管理对象了,更轻松的实现了程序的解耦。
spring提供了事务支持,使事务操作更加方便
spring提供了面向切面编程,这可以更方便的处理某一类的问题
更方便的框架集成,spring可以很方便的集成其他框架,比如mybatis
. 解释一下什么是 aop?
aop是面向切面编程,通过预编译的方式和运行期动态代理 实现程序功能的统一维护的一种技术,
简单来说就是统一处理某一切面类的问题的编程思想,比如统一处理日志,异常等。
解释一下什么是ioc?
Inversionof Control:控制反转,是spring的核心,对于spring框架来说,就是由spring框架来负责控制对象的生命周期和对象间的关系
简单来说,控制就是指当前对象对内部成员的控制权,控制反转指的是,这种控制权不由当前对象管理了,由第三方容器来管理。
spring 有哪些主要模块?
spring core: 框架的最基础属性,提供ioc和依赖注入特性。
spring context:构建于core封装包基础上的context封装包,提供了一种框架式的对象访问方法。
spring dao:Data Access Object 提供了JDBC的抽象层
spring aop:提供了面向切面的编程实现,让你可以自定义拦截器、切点等
spring web:提供了针对Web开发的集成特性
spring web mvc : spring中的mvc封装包提供了web应用的Model-View-Controller(MVC)的实现。
spring常用的注入方式有哪些?
setter属性注入
构造方法注入
注解方式注入
spring中的bean是安全的吗?
这里的bean默认是单例模式,spring框架并没有对bean进行多线程的封装处理,实际上bean是无状态的,所以是安全的,如果bean是有状态的,那么就需要改变bean的作用域,把“singleton”变更为“prototype”, 这样请求 bean 相当于 new Bean()了,所以就可以保证线程安全了。