1.java各个包:
(1)java.lang包: (这个是系统的基础类)
包装类,Character类,String类,StringBuffer类,Math类,Class类,Object类
(2)java.util包:(这个是系统辅助类,特别是集合类)
Date类,Calendar类,Random类,集合类(ArrayList类,LinkedList类,HashMap类),Vector类,concurrent并
java.util包下的集合类都是快速失败的,不能在多线程下发生并发修改(迭代过程中被修改)算是一种安全机制吧。
Tip:安全失败(fail—safe)大家也可以了解下,java.util.concurrent包下的容器都是安全失败,可以在多线程下并发使用,并发修改。
(3)java.io包:(这里面是所有输入输出有关的类,比如文件操作等;)
FileInputStream类,FileOutputStream类,BufferedReade类r,FileReader类,BufferedWriter类,FileWriter
类,DataInputStream类,DataOutputStream类
(4)java.nio:为了完善 io 包中的功能,提高 io 包中性能而写的一个新包;
(5)java.net:这里面是与网络有关的类;
(6)java.sql:这个是数据库操作的类。
**2.**JAVA跳出循环的三种方式
(1)使用关键字break;return;continue
(2)使用布尔值进行控制
(3)使用标签 的 break 和 continue 语句,作用有点类似于 C 和 C++中的 goto 语句,不建议使用
3.请你说明String 和StringBuffer,StringBuilder的区别
(1)String:是final类,是不可变对象,不能被继承。修改值时创建一个新的String对象,将值保存进去
(2)StringBuffer:是可改的对象。创建只能通过构造方法,成功后再内存中分配空间,初始化为null。赋值时可通过append方法。 本质是一个线程安全的可修改的字符序列,所有修改数据的方法都加上了synchronized。
(3)StringBuilder:JDK1.5发布,与StringBuffer相比,去掉了线程安全的部分。
(4) : StringBuffer与StringBuilder都继承了AbstractStringBuilder,底层都是利用可修改的Char数组(JDK9后是byte数组) 。
(5) :如果有大量字符串需要拼接,如果能预知大小,最好在new StringBuffer, StringBuilder的时候设置capacity, 避免多次扩容,扩容要抛弃原有数组拷贝创建新的数组。
总结:少量操作字符串使用String就够了,如果在程序中需要对字符串频繁修改连接操作,String在操作字符串的时候new了很多次StringBuffer,建议使用StringBuffer, 这样性能更高,很多情况下我们操作字符串不需要线程安全,可以用StringBuilder, 减小开销。
String 底层是final char[];
StringBuilder 底层 是char[],默认大小是16,扩容时是(oldCapacity+1)*2;
value = Arrays.copyOf(value, newCapacity);
4.具有缓存机制的类?
(int类型的取值范围
首先要搞清楚字节(byte 即B)和比特(bit即b)的概念: 1个字节=8个比特int是四个字节 ,且int是带符号的(也就是包含负数)。 四个字节就是4个byte 即 4X8个bit ,也就是2的32次方。 也就是有32位,其中最高位1表示负数,0表示正数 。也就是真正的数字其实是31位 也就是2的31次方,另外考虑到正数这边还有个0 ,所以能表示最大的整数就是 2147483648-1 =2147483647所以说int的取值范围是 -2147483648~2147483647**)**
该类的作用是将数值等于-128-127(默认)区间的Integer实例缓存到cache数组中。当再次创建值在-128-127区间的Integer实例时,会复用缓存中的实例,也就是直接指向缓存中的Integer实例。
缓存范围?
Byte,Short,Integer,Long为 -128 到 127,Character范围为 0 到 127
除了Integer可以指定缓存范围,其它类都不行。
public native int hashCode(); // 返回的是该对象引用指向对象的内存地址
public boolean equals(Object obj) { // equals方法是利用==来比较的也是对象的内存地址。
return (this == obj);}
native关键字说明其修饰的方法是一个原生态方法,方法对应的实现不是在当前文件,而是在用其他语言(如C和C++)实现的文件中。
Java语言本身不能对操作系统底层进行访问和操作,但是可以通过JNI接口(Java Native Interface)调用其他语言来实现对底层的访问。
JNI的书写步骤如下:a.编写带有native声明的方法的Java类等
(1)请你解释Object若不重写hashCode()的话,hashCode()如何计算出来的?
Object 的 hashcode 方法是本地方法,也就是用 c 、c++ 实现的,该方法直接返回对象的内存地址。
public static int hashCode(byte[] value) {
int h = 0; for (byte v : value) { h = 31 * h + (v & 0xff);} return h; }
//hash值= hashcode(key) & (length-1)
(2)设有长度为 n****n 的数组,其哈希值 h****h 的计算公式为:****h)=310an−1+311an−2+312an−3…+31n−1a0=∑n−1i=031ian−i−1h=310a**n−1+311a**n−2+312a**n−3…+31n−1a0=i=0∑n−131ian−i−1
(3)为什么用31?
由于哈希码(HashCode)的目的是为了区分对象,所以其分布自然是越均匀越好。
以31即满足素数的要求,又可以快速计算。
(4)就hashCode的实现代码中,做了两大优化:
1)使用 加乘运行 代替 连续阶乘 运算以提高效率;
2)使用可以用 位左移操作 计算的31代替其他运算。
(5)重写equals,不重写hashCode会出现的问题:
假设两个对象,重写了其equals方法,其相等条件是属性相等,就返回true。如果不重写hashcode方法,其返回的依然是两个对象的内存地址值,必然不相等。这就出现了equals方法相等,但是hashcode不相等的情况。这不符合hashcode的规则。
(6)hashCode()介绍
hashCode() 的作用是获取哈希码,也称为散列码;它实际上是返回一个int整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。hashCode() 定义在JDK的Object.java中,这就意味着Java中的任何类都包含有hashCode()函数。
散列表存储的是键值对(key-value),它的特点是:能根据“键”快速的检索出对应的“值”。这其中就利用到了散列码!(可以快速找到所需要的对象)
(7)为什么要有 hashCode
我们以“HashSet 如何检查重复”为例子来说明为什么要有 hashCode:
当你把对象加入 HashSet 时,HashSet 会先计算对象的 hashcode 值来判断对象加入的位置,同时也会与其他已经加入的对象的 hashcode 值作比较,如果没有相符的hashcode,HashSet会假设对象没有重复出现。但是如果发现有相同 hashcode 值的对象,这时会调用 equals()方法来检查 hashcode 相等的对象是否真的相同。如果两者相同,HashSet 就不会让其加入操作成功。如果不同的话,就会重新散列到其他位置。(摘自我的Java启蒙书《Head first java》第二版)。这样我们就大大减少了 equals 的次数,相应就大大提高了执行速度。
(8)hashCode()与equals()的相关规定
如果两个对象相等,则hashcode一定也是相同的
两个对象相等,对两个对象分别调用equals方法都返回true
两个对象有相同的hashcode值,它们也不一定是相等的
因此,equals 方法被覆盖过,则 hashCode 方法也必须被覆盖
hashCode() 的默认行为是对堆上的对象产生独特值。如果没有重写 hashCode(),则该 class 的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)
6.自增主键用完了怎么办
int存储大小为4byte,即232。用完了可以换成BigInt,他的存储大小为264。可以使用mysql5.6及以上版本提供的在线修改功能进行列属性的替换。
但在实际情况下,在出现自增主键用完的情况之前,就进行分表操作了。
7**.**
主流浏览器 | 内核 | 主流浏览器 | 内核 |
---|---|---|---|
IE | trident | firefox | Gecko |
Chrom | webkit/blink | Opera | presto |
Safari | webkit |
8.SpEl表达式:
提供在程序运行时构造复杂表达式来完成对象属性存储及方法调用等。(注入Bean)
9.字符转换:
string->int : int age = Integer.parseInt(“2”);
int->String: String str = String.valueOf(age);
11.关于== 和equals
String a = new String("AAA");
String b = new String("AAA");
String a1= "AAA";
String b1="AAA";
if (a==b){
System.out.println("a==b");}
if (a1==b1){
System.out.println("a1==b1");}
if (a==a1){
System.out.println("a==a1");}
if (a.equals(b)){
System.out.println("a.equals(b)");}
if (a1.equals(b1)){
System.out.println("a1.equals(b1)");}
if (a.equals(a1)){
System.out.println("a.equals(a1)");}}
(1)==比较基本数据类型时,比较值是否相等;比较引用时,比较其地址是否相等。
(2)equals:String进行了重写,只比较值是否相等。不进行重写,底层也是==。
12. Java基本类型占用的字节数:
1字节: byte , boolean 2字节: short, char
4字节: int , float 8字节: long , double
附录: Unicode/GBK:中文2字节 注: 1字节(byte)=8(bits)
UTF-8:中文通常3字节, 在拓展B区之后的是4字节
综上,中文字符在编码中占用的字节数一般是2-4个字节。
GBK、GB2312<=>Unicode<=>UTF8
13.java和c++的区别:
java | c++ | |
---|---|---|
编译/跨平台性 | 一次编译,生成字节码,随处运行(被解释器解释成机器码)(通过JVM跨平台性) | 一次编译形成机器码 |
面向对象 | 纯面向对象,全在类中定义(封装,继承,多态) | 还有面向过程的东西,如全局变量和全局函数 |
多继承 | 不支持类的多继承,但是可以实现多个接口 | 可以多继承 |
内存管理 | JVM的GC内存机制,自动回收 | 手动回收 |
---|---|---|
指针/重载运算符等 | 无指针()内存更加安全,但是有引用不支持重载运算符 | 有指针可以重载7 |
(1)面向对象和面向过程
面向对象 | 面向过程 |
---|---|
优:易维护、易复用、易扩展 | 优:性能高 |
缺:性能比面向过程低 | 缺:没有三易 |
模型化,抽象出一个类,不管功能如何实现,只管拿来用 | 具体化的,流程化的,解决一个问题,你需要一步一步的分析,一步一步的实现。 |
(2)**多态:**引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,
*****多态分为编译时多态和运行时多态。其中编辑时多态是静态的,主要是指方法的重载,它是根据参数列表的不同来区分不同的函数,通过编辑之后会变成两个不同的函数,在运行时谈不上多态。而运行时多态是动态的,它是通过动态绑定来实现的,也就是我们所说的2多态性。
*****Java实现多态有三个必要条件:继承、重写、向上转型。
(3)面向对象五大基本原则是什么(可选)
单一职责原则SRP(Single Responsibility Principle):类的功能要单一,不能包罗万象,跟杂货铺似的
开放封闭原则OCP(Open-Close Principle):一个模块对于拓展是开放的,对于修改是封闭的,想要增加功能热烈欢迎,想要修改,哼,一万个不乐意。
里式替换原则LSP(the Liskov Substitution Principle LSP):子类可以替换父类出现在父类能够出现的任何地方。比如你能代表你爸去你姥姥家干活。哈哈~~
依赖倒置原则DIP(the Dependency Inversion Principle DIP)
高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象。抽象不应该依赖于具体实现,具体实现应该依赖于抽象。就是你出国要说你是中国人,而不能说你是哪个村子的。比如说中国人是抽象的,下面有具体的xx省,xx市,xx县。你要依赖的抽象是中国人,而不是你是xx村的。
接口分离原则ISP(the Interface Segregation Principle ISP)
设计时采用多个与特定客户类有关的接口比采用一个通用的接口要好。就比如一个手机拥有打电话,看视频,玩游戏等功能,把这几个功能拆分成不同的接口,比在一个接口里要好的多。
14.正则表达式
(1)概念及用途:在编写处理字符串的程序时,经常会有查找符合某些复杂规则的字符串的需要。正则表达式就是用于描述这些规则的工具
(2)Java中是如何支持正则表达式操作的?
Java中的String类提供了支持正则表达式操作的方法,包括:matches()、replaceAll()、replaceFirst()、split()。
此外,Java中可以用Pattern类表示正则表达式对象,它提供了丰富的API进行各种正则表达式操作。
**15.**比较一下Java和JavaSciprt?
Java | JavaScript |
---|---|
面向对象 | 脚本语言,基于对象 |
先编译,在执行 | 解释性编译语言(不编译,浏览器进行解释执行) |
强类型变量,需编译前声明 | 弱类型,运行时推断数据类型 |
**16.**请你讲讲&和&&的区别?
&运算符有两种用法:(1)按位与;(2)逻辑与。 &&运算符是短路与运算。
**17.**基本数据类型/对象包装类型(wrapper class)
(1)
- 原始类型: boolean,char,byte,short,int,long,float,double
- 包装类型:Boolean,Character,Byte,Short,Integer,Long,Float,Double
Java是一个近乎纯洁的面向对象编程语言,但是为了编程的方便还是引入了基本数据类型,但是为了能够将这些基本数据类型当成对象操作,Java为每一个基本数据类型都引入了对应的包装类型(wrapper class)从Java 5开始引入了自动装箱/拆箱机制,使得二者可以相互转换。
**(2)引用数据类型:**类(class)、接口(interface)、数组([])
(3)
**(4)**转换原则
*****boolean类型与其他基本类型不能进行类型的转换
*在Java中,整数类型(byte/short/int/long)中,对于未声明数据类型的整形,其默认类型为int型。在浮点类型(float/double)中,对于未声明数据类型的浮点型,默认为double型。
**隐式类型转换:(**从存储范围小的类型到存储范围大的类型.)
byte ->short(char)->int->long->float->double
显式类型转换:
double→float→long→int→short(char)→byte
18.请你讲讲一个十进制的数在内存中是怎么存的? 补码的形式。
19. 你知道java8的新特性吗,请简单介绍一下
接口的默认方法(default),
lambda表达式—-java8最大的亮点,使得java提供了对函数式编程的支持
方法引用—–简化了方法调用
可重复注解——转化成注解值数组,使得注解更加好用。
更好的类型推测机制—–泛型等不确定类型能更好地推测出来
扩展注解的支持—–java8现在能几乎为任何类型添加注解
反射的部分增强—–能获取的基础信息更多
Java8增加的类库Optional(防止空指针,通过回调函数产生一个默认值),Stream(一串支持连续、并行聚集操作的元素,可以代替foreach),Date/Time(一个java的日期API),js引擎Nashorn(允许java和javascript互相调用),Base64(Java类库的标准),并行(parallel)数组,并发(在新增Stream机制与lambda的基础之上,在java.util.concurrent中加入了一些新方法)
java8增加的java工具:Nashorn引擎: jjs,类依赖分析器:依赖分析器jdeps
java8虚拟机改动:PermGen空间被移除了,取而代之的是Metaspace(JEP 122)。JVM选项-XX:PermSize与-XX:MaxPermSize分别被-XX:MetaSpaceSize与-XX:MaxMetaspaceSize所代替。
**20.**核心类库主要是java.lang包:包含了运行Java程序必不可少的系统类,如基本数据类型、基本数学函数、字符串处理、线程、异常处理类等,系统缺省加载这个包
21.什么是跨平台性?原理是什么
所谓跨平台性,是指java语言编写的程序,一次编译后,可以在多个系统平台上运行。
实现原理:Java程序是通过java虚拟机在系统平台上运行的,只要该系统可以安装相应的java虚拟机,该系统就可以运行java程序。
22.什么是字节码?采用字节码的最大好处是什么
(1)字节码:Java源代码经过虚拟机编译器编译后产生的文件(即扩展为.class的文件),它不面向任何特定的处理器,只面向虚拟机。
(2)Java语言通过字节码的方式,在一定程度上解决了传统解释型语言执行效率低的问题,同时又保留了解释型语言可移植的特点。所以Java程序运行时比较高效,而且,由于字节码并不专对一种特定的机器,因此,Java程序无须重新编译便可在多种不同的计算机上运行。
23.什么是Java程序的主类?应用程序和小程序的主类有何不同?
一个程序中可以有多个类,但只能有一个类是主类。在Java应用程序中,这个主类是指包含main()方法的类。而在Java小程序中,这个主类是一个继承自系统类JApplet或Applet的子类。应用程序的主类不一定要求是public类,但小程序的主类要求必须是public类。主类是Java程序执行的入口点。
外部类不能用private、protected修饰,可用default修饰
Java应用程序与小程序之间有那些差别?
简单说应用程序是从主线程启动(也就是main()方法)。applet小程序没有main方法,主要是嵌在浏览器页面上运行(调用init()线程或者run()来启动),嵌入浏览器这点跟flash的小游戏类似。
24.switch 是否能作用在 byte 上,是否能作用在 long 上,是否能作用在 String 上
在 Java 5 以前,switch(expr)中,expr 只能是 byte、short、char、int。从 Java5 开始,Java 中引入了枚举类型,expr 也可以是 enum 类型,从 Java 7 开始,expr 还可以是字符串(String),但是长整型(long)在目前所有的版本中都是不可以的。
25.用最有效率的方法计算 2 乘以 8
2 << 3(左移 3 位相当于乘以 2 的 3 次方,右移 3 位相当于除以 2 的 3 次方)。
26.Math.round(11.5) 等于多少?Math.round(-11.5)等于多少
Math.round(11.5)的返回值是 12,Math.round(-11.5)的返回值是-11。四舍五入的原理是在参数上加 0.5 然后进行下取整。
27.float f=3.4;是否正确
不正确。3.4 是双精度数,将双精度型(double)赋值给浮点型(float)属于下转型(down-casting,也称为窄化)会造成精度损失,因此需要强制类型转换float f =(float)3.4; 或者写成 float f =3.4F;。
28.short s1 = 1; s1 = s1 + 1;有错吗?short s1 = 1; s1 += 1;有错吗
对于 short s1 = 1; s1 = s1 + 1;由于 1 是 int 类型,因此 s1+1 运算结果也是 int型,需要强制转换类型才能赋值给 short 型。
而 short s1 = 1; s1 += 1;可以正确编译,因为 s1+= 1;相当于 s1 = (short(s1 + 1);其中有隐含的强制类型转换。
29.Java语言采用何种编码方案?有何特点?
Java语言采用Unicode编码标准,Unicode(标准码),它为每个字符制订了一个唯一的数值,因此在任何的语言,平台,程序都可以放心的使用。
30.final 有什么用?
(1)被final修饰的类不可以被继承,(2)被final修饰的方法不可以被重写,(3)被final修饰的变量不可以被改变,被final修饰不可变的是变量的引用,而不是引用指向的内容,引用指向的内容是可以改变的
31.final finally finalize区别
final可以修饰类、变量、方法。
finally一般作用在try-catch代码块中,在处理异常的时候,通常我们将一定要执行的代码方法finally代码块中,表示不管是否出现异常,该代码块都会执行,一般用来存放一些关闭资源的代码。
finalize是一个方法,属于Object类的一个方法,而Object类是所有类的父类,该方法一般由垃圾回收器来调用,当我们调用System.gc() 方法的时候,由垃圾回收器调用finalize(),回收垃圾,一个对象是否可回收的最后判断。
32.this关键字的用法(指向对象本身的一个指针)
(1)普通的直接引用,this相当于是指向当前对象本身.
(2)形参与成员名字重名,用this来区分:this.name = name;
33.super关键字的用法(超类,离自己最近的一个父类)
(1)普通的直接引用,与this类似.
(2)子类中的成员变量或方法与父类中的成员变量或方法同名时,用super进行区分
(3)引用父类构造函数,super(参数)
34.static存在的主要意义
没有创建对象,也能使用属性和调用方法,
形成静态代码块以优化程序性能。static块可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次。只需要进行一次的初始化操作都放在static代码块中进行。
1.接口可以实现接口吗?
ans:不可以实现,但是可以继承一一个或多 个接口.
2.抽象类可以实现接口吗?
ans:可以
3.接口默认的修饰符
所有的接口的成员变量默认都是:puiblic static final的
所有接口的方法默认都是: public abstract
4、接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。
5、抽象类里的抽象方法必须全部被子类所实现,如果子类不能全部实现父类抽象方法,那么该子类只能是抽象类。同样,一个实现接口的时候,如不能全部实现接口方法,那么该类也只能为抽象类。
6、抽象方法只能申明,不能实现,接C是设计的结果,抽象类是重构的结果
7、抽象类里可以没有抽象方法
8、抽象方法要被实现,所以不能是静态的,也不能是私有的。
9、接口可继承接口,并可多继承接口,但类只能单继承。
***
存储位置
成员变量:随着对象的创建而存在,随着对象的消失而消失,存储在堆内存中。
局部变量:在方法被调用,或者语句被执行的时候存在,存储在栈内存中。当方法调用完,或者语句结束后,就自动释放。
成员变量:有默认初始值。
局部变量:没有默认初始值,使用前必须赋值。
**36.**在Java中定义一个不做事且没有参数的构造方法的作用
Java程序在执行子类的构造方法之前,如果没有用super()来调用父类特定的构造方法,则会调用父类中“没有参数的构造方法”。因此,如果父类中只定义了有参数的构造方法,而在子类的构造方法中又没有用super()来调用父类中特定的构造方法,则编译时将发生错误,因为Java程序在父类中找不到没有参数的构造方法可供执行。解决办法是在父类里加上一个不做事且没有参数的构造方法。
37.在调用子类构造方法之前会先调用父类没有参数的构造方法,其目的是?
帮助子类做初始化工作。
38.一个类的构造方法的作用是什么?若一个类没有声明构造方法,改程序能正确执行吗?为什么?
主要作用是完成对类对象的初始化工作。可以执行。因为一个类即使没有声明构造方法也会有默认的不带参数的构造方法。
39.构造方法有哪些特性?
名字与类名相同;没有返回值,但不能用void声明构造函数;生成类的对象时自动执行,无需调用。
40.静态变量和实例变量区别
静态变量: 静态变量由于不属于任何实例对象,属于类的,所以在内存中只会有一份,在类的加载过程中,JVM只为静态变量分配一次内存空间。
实例变量: 每次创建对象,都会为每个对象分配成员变量内存空间,实例变量是属于实例对象的,在内存中,创建几次对象,就有几份成员变量。
41.静态变量与普通变量区别
static变量也称作静态变量,静态变量和非静态变量的区别是:静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。
还有一点就是static成员变量的初始化顺序按照定义的顺序进行初始化。
42.静态方法和实例方法有何不同?
(1)在外部调用静态方法时,可以使用"类名.方法名"的方式,也可以使用"对象名.方法名"的方式。而实例方法只有后面这种方式。也就是说,调用静态方法可以无需创建对象。
(2)静态方法在访问本类的成员时,只允许访问静态成员(即静态成员变量和静态方法),而不允许访问实例成员变量和实例方法;实例方法则无此限制
43.在一个静态方法内调用一个非静态成员为什么是非法的?
因为静态方法是在类加载的时候进行初始化,此时还不存在实例对象,无法调用实例对象的成员。
44.内部类的分类有哪些
内部类可以分为四种:成员内部类、局部内部类、匿名内部类和静态内部类。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NhXAwaPh-1606288222233)(e:\xunlei\有道云笔记\file\[email protected]\a27c6cef55f84f6689da65ffed9323cb\clipboard.png)]
(1)静态内部类可以访问外部类所有的静态变量,而不可访问外部类的非静态变量;静态内部类的创建方式,new 外部类.静态内部类(),如下:
(2)定义在类内部,成员位置上的非静态类,就是成员内部类。
成员内部类可以访问外部类所有的变量和方法,包括静态和非静态,私有和公有。成员内部类依赖于外部类的实例,它的创建方式外部类实例.new 内部类(),如下:
(3)定义在方法中的内部类,就是局部内部类。
定义在实例方法中的局部类可以访问外部类的所有变量和方法,定义在静态方法中的局部类只能访问外部类的静态变量和方法。局部内部类的创建方式,在对应方法内,new 内部类(),如下:
(4)匿名内部类就是没有名字的内部类,日常开发中使用的比较多。
匿名内部类必须继承一个抽象类或者实现一个接口。
匿名内部类不能定义任何静态成员和静态方法。
当所在的方法的形参需要被匿名内部类使用时,必须声明为 final。
匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法。
45.内部类的优点
一个内部类对象可以访问创建它的外部类对象的内容,包括私有数据!
内部类不为同一包的其他类所见,具有很好的封装性;
内部类有效实现了“多重继承”,优化 java 单继承的缺陷。
匿名内部类可以很方便的定义回调。
46.内部类有哪些应用场景
一些多算法场合
解决一些非面向对象的语句块。
适当使用内部类,使得代码更加灵活和富有扩展性。
当某个类除了它的外部类,不再被其他的类使用时。
47.局部内部类和匿名内部类访问局部变量的时候,为什么变量必须要加上final?
因为生命周期不一致, 局部变量直接存储在栈中,当方法执行结束后,非final的局部变量就被销毁。而局部内部类对局部变量的引用依然存在,如果局部内部类要调用局部变量时,就会出错。加了final,可以确保局部内部类使用的变量与外层的局部变量区分开,解决了这个问题。
*final放在 常量池里
*jdk7以后,字符串常量池和静态变量都从方法区移出也就是所说的永久代,移到了堆区。
*方法体中的引用变量和基本类型的变量都在栈上,其他都在堆上。
48.
49.
值传递:指的是在方法调用时,传递的参数是按值的拷贝传递,传递的是值的拷贝,也就是说传递后就互不相关了。
**引用传递:**指的是在方法调用时,传递的参数是按引用进行传递,其实传递的引用的地址,也就是变量所对应的内存空间的地址。传递的是值的引用,也就是说传递前和传递后都指向同一个引用(也就是同一个内存空间)。
*当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里是值传递
***** Java 中只有值传递
**50.**java和javax没有区别。这都是一个名字。
51.java 中 IO 流分为几种?
按照流的流向分,可以分为输入流和输出流;
按照操作单元划分,可以划分为字节流和字符流;
按照流的角色划分为节点流和处理流。
(1)4个抽象类基类中派生出来的。
InputStream/Reader: 所有的输入流的基类,前者是字节输入流,后者是字符输入流。
OutputStream/Writer: 所有输出流的基类,前者是字节输出流,后者是字符输出流。
52.BIO,NIO,AIO 有什么区别?
BIO:Block IO 同步阻塞式 IO,就是我们平常使用的传统 IO,它的特点是模式简单使用方便,并发处理能力低。
NIO:Non IO 同步非阻塞 IO,是传统 IO 的升级,客户端和服务器端通过 Channel(通道)通讯,实现了多路复用。
AIO:Asynchronous IO 是 NIO 的升级,也叫 NIO2,实现了异步非堵塞 IO ,异步 IO 的操作基于事件和回调机制。
详细回答
BIO (Blocking I/O): 同步阻塞I/O模式,数据的读取写入必须阻塞在一个线程内等待其完成。在活动连接数不是特别高(小于单机1000)的情况下,这种模型是比较不错的,可以让每一个连接专注于自己的 I/O 并且编程模型简单,也不用过多考虑系统的过载、限流等问题。线程池本身就是一个天然的漏斗,可以缓冲一些系统处理不了的连接或请求。但是,当面对十万甚至百万级连接的时候,传统的 BIO 模型是无能为力的。因此,我们需要一种更高效的 I/O 处理模型来应对更高的并发量。
NIO (New I/O): NIO是一种同步非阻塞的I/O模型,在Java 1.4 中引入了NIO框架,对应 java.nio 包,提供了 Channel , Selector,Buffer等抽象。NIO中的N可以理解为Non-blocking,不单纯是New。它支持面向缓冲的,基于通道的I/O操作方法。 NIO提供了与传统BIO模型中的 Socket 和 ServerSocket 相对应的 SocketChannel 和 ServerSocketChannel 两种不同的套接字通道实现,两种通道都支持阻塞和非阻塞两种模式。阻塞模式使用就像传统中的支持一样,比较简单,但是性能和可靠性都不好;非阻塞模式正好与之相反。对于低负载、低并发的应用程序,可以使用同步阻塞I/O来提升开发速率和更好的维护性;对于高负载、高并发的(网络)应用,应使用 NIO 的非阻塞模式来开发
AIO (Asynchronous I/O): AIO 也就是 NIO 2。在 Java 7 中引入了 NIO 的改进版 NIO 2,它是异步非阻塞的IO模型。异步 IO 是基于事件和回调机制实现的,也就是应用操作之后会直接返回,不会堵塞在那里,当后台处理完成,操作系统会通知相应的线程进行后续的操作。AIO 是异步IO的缩写,虽然 NIO 在网络操作中,提供了非阻塞的方法,但是 NIO 的 IO 行为还是同步的。对于 NIO 来说,我们的业务线程是在 IO 操作准备好时,得到通知,接着就由这个线程自行进行 IO 操作,IO操作本身是同步的。查阅网上相关资料,我发现就目前来说 AIO 的应用还不是很广泛,Netty 之前也尝试使用过 AIO,不过又放弃了。
53.Files的常用方法都有哪些?
Files. exists():检测文件路径是否存在。
Files. createFile():创建文件。
Files. createDirectory():创建文件夹。
Files. delete():删除一个文件或目录。
Files. copy():复制文件。
Files. move():移动文件。
Files. size():查看文件个数。
Files. read():读取文件。
Files. write():写入文件。
54.什么是反射机制?
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
(1)静态编译和动态编译:
**静态编译:**在编译时确定类型,绑定对象
**动态编译:**运行时确定类型,绑定对象
(2)反射机制优缺点
优点: 运行期类型的判断,动态加载类,提高代码灵活度。
缺点: 性能瓶颈:反射相当于一系列解释操作,通知 JVM 要做的事情,性能比直接的java代码要慢很多。
(3)反射机制的应用场景有哪些?
举例:①我们在使用JDBC连接数据库时使用Class.forName()通过反射加载数据库的驱动程序;②Spring框架也用到很多反射机制,最经典的就是xml的配置模式。Spring 通过 XML 配置模式装载 Bean 的过程:1) 将程序内所有 XML 或 Properties 配置文件加载入内存中; 2)Java类里面解析xml或properties里面的内容,得到对应实体类的字节码字符串以及相关的属性信息; 3)使用反射机制,根据这个字符串获得某个类的Class实例; 4)动态配置实例的属性
(4)Java获取反射的三种方法
1.通过new对象实现反射机制
2.通过路径实现反射机制
3.通过类名实现反射机制
55.字符型 常量和字符串 常量的区别
(1)形式上: 字符常量是单引号引起的一个字符 字符串常量是双引号引起的若干个字符
(2)含义上: 字符常量相当于一个整形值(ASCII值),可以参加表达式运算 字符串常量代表一个地址值(该字符串在内存中存放位置)
(3)占内存大小 字符常量只占一个字节 字符串常量占若干个字节(至少一个字符结束标志)
56.什么是字符串常量池?
字符串常量池位于堆内存中,专门用来存储字符串常量,可以提高内存的使用率,避免开辟多块空间存储相同的字符串,在创建字符串时 JVM 会首先检查字符串常量池,如果该字符串已经存在池中,则返回它的引用,如果不存在,则实例化一个字符串放到池中,并返回其引用。
57.String有哪些特性
(1)不变性:String 是只读字符串,是一个典型的 immutable 对象,对它进行任何操作,其实都是创建一个新的对象,再把引用指向该对象。不变模式的主要作用在于当一个对象需要被多线程共享并频繁访问时,可以保证数据的一致性。
(2)常量池优化:String 对象创建之后,会在字符串常量池中进行缓存,如果下次创建同样的对象时,会直接返回缓存的引用。
(3)final:使用 final 来定义 String 类,表示 String 类不能被继承,提高了系统的安全性。
58.String底层
59.String str="i"与 String str=new String(“i”)一样吗?
不一样,因为内存的分配方式不一样。String str="i"的方式,java 虚拟机会将其分配到常量池中;而 String str=new String(“i”) 则会被分到堆内存中。
60.String s = new String(“xyz”);创建了几个字符串对象
两个对象,一个是静态区的"xyz",一个是用new创建在堆上的对象。
61.如何将字符串反转?
使用 StringBuilder 或者 stringBuffer 的 reverse() 方法。
62.数组有没有 length()方法?String 有没有 length()方法
数组没有 length()方法 ,有 length 的属性。String 有 length()方法。JavaScript中,获得字符串的长度是通过 length 属性得到的,这一点容易和 Java 混淆。
63.String 类的常用方法都有那些?
indexOf():返回指定字符的索引。 charAt():返回指定索引处的字符。
replace():字符串替换。
trim():去除字符串两端空白。
split():分割字符串,返回一个分割后的字符串数组。
getBytes():返回字符串的 byte 类型数组。
length():返回字符串长度。
toLowerCase():将字符串转成小写字母。 toUpperCase():将字符串转成大写字符。
substring():截取字符串。
equals():字符串比较。
64.在使用 HashMap 的时候,用 String 做 key 有什么好处?
HashMap 内部实现是通过 key 的 hashcode 来确定 value 的存储位置,因为字符串是不可变的,所以当创建字符串时,它的 hashcode 被缓存下来,不需要再次计算,所以相比于其他对象更快。
65.等差数列:
66.500以内质数
67. Spring中提供通过Web容器来启动Spring框架的类有:ContextLoaderListener、ContextLoaderServlet
68 .在多媒体计算机系统中,能用以存储多媒体信息的是()。软盘、硬盘、光盘
不能的是:光缆
69. transient关键字:
用transient关键字标记的成员变量不参与序列化过程
为什么用它呢?
不想用serialization机制来保存它。或者 应该是为了节约磁盘空间,避免造成不必要的浪费吧
70. jdk1.7以前bai的版本switch(expr1)中,expr1是一个整数du表达式,整数表达式可以是int基本zhi类型或Integer包装类型,由于,daobyte,short,char都可以隐含转换为int,所以,这些类型以及这些类型的包装类型也是可以的。因此传递给 switch 和case 语句的参数应该是 int、 short、 char 或者 byte,还有enum。
long,string 都不能作用于swtich。
在jdk 1.7中switch的参数类型可以是字符串类型。
**80.**各自功能分别是:
(1)floor 返回不大于的最大整数 (返回double)。
(2)round 则是4舍5入的计算,入的时候是到大于它的整数
round方法,它表示“四舍五入”,算法为Math.floor(x+0.5),即将原来的数字加上0.5后再向下取整,所以,Math.round(11.5)的结果为12,Math.round(-11.5)的结果为-11。(返回int)。
(3)ceil 则是不小于他的最小整数(返回double)。
所以一定注意他返回来的是double类型还是int类型
tener、ContextLoaderServlet
68**.在多媒体计算机系统中,能用以存储多媒体信息的是()**。软盘、硬盘、光盘
不能的是:光缆
**69.**transient关键字:
用transient关键字标记的成员变量不参与序列化过程
为什么用它呢?
不想用serialization机制来保存它。或者 应该是为了节约磁盘空间,避免造成不必要的浪费吧
**70.**jdk1.7以前bai的版本switch(expr1)中,expr1是一个整数du表达式,整数表达式可以是int基本zhi类型或Integer包装类型,由于,daobyte,short,char都可以隐含转换为int,所以,这些类型以及这些类型的包装类型也是可以的。因此传递给 switch 和case 语句的参数应该是 int、 short、 char 或者 byte,还有enum。
long,string 都不能作用于swtich。
在jdk 1.7中switch的参数类型可以是字符串类型。
**80.**各自功能分别是:
(1)floor 返回不大于的最大整数 (返回double)。
(2)round 则是4舍5入的计算,入的时候是到大于它的整数
round方法,它表示“四舍五入”,算法为Math.floor(x+0.5),即将原来的数字加上0.5后再向下取整,所以,Math.round(11.5)的结果为12,Math.round(-11.5)的结果为-11。(返回int)。
(3)ceil 则是不小于他的最小整数(返回double)。
所以一定注意他返回来的是double类型还是int类型
需要int类型,可以获取到后强制换换int(value)。