2022-12-1
16.访问修饰符 public,private,protected,以及不写(默认)时的区别?
public:公共的
被public修饰的类、属性、方法都是公开的,所有的类都可以访问
private:私有的
被private修饰的类、属性、方法只有本类才可以访问
default:默认的
被default修饰的类、属性、方法只能在同一个包中的类可以访问
protected:受保护的
被protected修饰的类、方法、属性、只能被本类、本包、和子类访问。
17.Math.round(11.5) 等于多少? Math.round(-11.5)等于多少?
Math.round(11.5)的结果为 12,Math.round(-11.5)的结果为-11。
Math类中提供了三个取整的方法:ceil、floor、round
ceil 方法表示向上取整
floor 方法表示向下取整
round 方法表示四舍五入
18.float f=3.4;是否正确?
不正确
float浮点型 ,3.4双精度型
需要强制类型转换 float f =(float)3.4;
19.int 和 Integer 有什么区别?
int属于基本数据类型
Integer属于包装类型
基本类型:boolean, char, byte,short, int, long,float,double
包装类型:Boolean,Character,Byte,Short,Integer,Long,Float,Double
20.请解释&和&&、|和||的区别?
&和&&都可以用作逻辑与的运算符,表示逻辑与(and),当运算符两边的表达式的结果都为 true 时,整个运算结果才为 true,否则,只要有一方为 false,则结果为 false。
&&具有短路的功能,即如果第一个表达式为 false,则不再计算第二个表达式
&还可以用作位运算符,当&操作符两边的表达式不是 boolean 类型时,&表示按位与操作
或操作:或操作分为两种,一种是普通或,另外一种是短路或;
普通或(|):表示所有的判断条件都要执行,不管前面是否满足;
短路或(||):如果前面的条件已经是 true 了,那么后面无论如何判断都是 true,不用再判断第二个条件了
2022-12-2
21.解释内存中的栈(stack)、堆(heap)和静态区(static area)的用法。
堆区(Heap):专门用来保存对象的实例(new创建的对象和数组),实例上也只是保存对象的属性值,属性的类型和对象的类型标记等,并不保存对象的方法。(方法是指令,保存在stack中)
1.存输的全部都是对象,每个对象都对应着一个class信息(class的目的是得到操作指令)
2.jvm只有一个堆区(heap)被所有线程共享,堆区不存放基本类型和对象引用,只存放对象本身
3..一般由程序员分配释放, 若程序员不释放,程序结束时可能由 OS 回收
栈(stack):
1.每个线程包含一个栈区,栈中只保存基础数据类型的对象和自定义对象的引用(不是对象),对象都存放在
堆区中
2.每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问
3.栈分为 3 个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)
4.由编译器自动分配释放 ,存放函数的参数值,局部变量的值等
静态区(static area):
1.方法区又叫静态区,跟堆一样,被所有的线程共享;方法区包含所有的 class 和 static 变量
2.方法区中包含的都是在整个程序中唯一的元素
3.全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域
stack 是运行的基本单位,在stack中一个对象只对应4个字节的引用地址
heap 是存储的基本单位,在heap中对象的大小是不确定的,动态变化的
eg:
String str = new String("hello");
该语句中变量 str 放在栈上,用 new 创建出来的字符串对象放在堆上,而"hello"这个字面量放在静态区
22.swtich 是否能作用在 byte 上,是否能作用在 long 上,是否能作用在 String上?
在 Java 5 以前,switch(expr)中,expr 只能是 byte、short、char、int。
从 Java 5 开始,Java 中引入了枚举类型,expr 也可以是 enum 类型.
从 Java 7 开始,expr还可以是字符串(String),但是长整型(long)在目前所有的版本中都是不可以的。
总结:在 switch(expr)中,expr只能是一个整数表达式或者枚举常量,整数表达式可以是 int 基本类型或 Integer
包装类型;由于 byte、short、char。都是可以自动转换(隐式转换)为int,所以可以作用在switch上。 JDK1.7中引入新特性,所以 swtich 语句可以接收一个 String 类型的值, String 可以作用在 swtich 上。
23.用最有效率的方法计算 2 乘以 8?
2 << 3(左移 3 位相当于乘以 2 的 3 次方,右移 3 位相当于除以 2 的 3 次方)。
解析:2 << 3, 因为将一个数左移 n 位,就相当于乘以了 2 的 n 次方,那么,一个数乘以 8 只要将其左移 3 位即可,而位运算cpu 直接 支持的,效率最高,所以,2 乘以 8 等於几的最效率的方法是 2 << 3
24.数组有没有 length()方法?String 有没有 length()方法?
数组中没有length() 方法,有length属性
String中有length() 方法,在js 中用来计算字符串的长度
25.在 Java 中,如何跳出当前的多重嵌套循环
方法一:.在外层for循环语句前定义一个标号,在内层for循环体中使用带有标号的bleak语句(不推荐)
ok:
for(int i=0;i<10;i++){
for(int j=0;j<10;j++){
System.out.println("i=" + i + ",j=" + j);
if(j == 5) break ok;
}
}
方法二:让外层的循环条件表达式的结果可以受到里层循环体代码的控制
例如,
要在二维数组中查找到某个数字。
int arr[][] = {{1,2,3},{4,5,6,7},{9}};
boolean found = false;
for(int i=0;i<arr.length && !found;i++){
for(int j=0;j<arr[i].length;j++){
System.out.println("i=" + i + ",j=" + j);
if(arr[i][j] == 5){
found = true;
break;
}
}
}
2022-12-5
26.构造器(constructor)是否可被重写(override)
构造器(constructor)不能被继承,因此不能被重写;但可以被重载
27.重载和重写区别
1.定义不同:重载是定义相同的方法名、参数和个数不同,重写是子类重写父类的方法
2.范围不同:重载是在一个类中,重写是子类与父类之间的
3.多态不同:重载是编译时的多态性,重写是运行时的多态性
4.参数不同:重载的参数个数、参数类型、参数的顺序可以不同,重写父类子方法参数必须相同
5.修饰不同:重载对修饰范围没有要求,重写要求重写方法的修饰范围大于被重写方法的修饰范围
28.两个对象值相同(x.equals(y) == true),但却可有不同的 hash code,这句话对不对?(不懂)
不对,如果两个对象 x 和 y 满足 x.equals(y) == true,它们的哈希码(hash code)应当相同。Java 对于eqauls 方法和 hashCode 方法是这样规定的:
(1)如果两个对象相同(equals 方法返回 true),那么它们的 hashCode 值一定要相同;
(2)如果两个对象的 hashCode 相同,它们并不一定相同。当然,你未必要按照要求去做,但是如果你违背了
上述原则就会发现在使用容器时,相同的对象可以出现在 Set 集合中,同时增加新元素的效率会大大下降(对
于使用哈希存储的系统,如果哈希码频繁的冲突将会造成存取性能急剧下降)。
29.是否可以继承 String 类?
String 类是 final 类,不可以被继承
对 String 类最好的重用方式是关联关系(Has-A)和依赖关系(Use-A)
30.当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?(不懂)
是值传递。
Java 语言的方法调用只支持参数的值传递。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。对象的属性可以在被调用过程中被改变,但对对象引用的改变是不会影响到调用者的。
2022-12-6
31.String 和 StringBuilder、StringBuffer 的区别?
Java 提供了两种类型的字符串:String 和 StringBuffer/StringBuilder,它们可以储存和操作字符串。
String 是只读字符串,String 引用的字符串内容是不能被改变的;
StringBuffer/StringBuilder 类表示的字符串对象可以直接进行修改。StringBuilder 是 Java 5 中引入的,它和 StringBuffer 的方法完全相同,区别在于它是在单线;
String 字符串常量
StringBuffer 字符串变量(线程安全)
StringBuilder 字符串变量(非线程安全)
总结:
1.如果要操作少量的数据用 = String
2.单线程操作字符串缓冲区 下操作大量数据 = StringBuilder
3.多线程操作字符串缓冲区 下操作大量数据 = StringBuffer
32.描述一下 JVM 加载 class 文件的原理机制
Java 中的所有类,都需要由类加载器装载到 JVM 中才能运行。类加载器本身也是一个类,它的工作原理就是把 class 文件从硬盘读取到内存中。在写程序的时候我们几乎不需要关心类的加载,这些都是隐式装载的。
Java 类的加载是动态的,它不会一次性将所有类全部加载后再运行,而是保证程序运行的基础类(像是基类)完全加载到 jvm 中,至于其他类,则在需要的时候才加载。节省内存开销
Java 的类加载器有三个:
Bootstrap Loader // 负责加载系统类 (指的是内置类,像是 String,对应于 C#中的 System 类和 C/C++标准库中的类)
ExtClassLoader //负责加载扩展类(就是继承类和实现类)
AppClassLoader //负责加载应用类(程序员自定义的类)
33.抽象类(abstract class)和接口(interface)有什么异同
抽象类是用来捕捉子类的通用特性的 。它不能被实例化,只能被用作子类的超类。抽象类是被用来创建继
承层级里子类的模板
接口是抽象方法的集合。如果一个类实现了某个接口,那么它就继承了这个接口的抽象方法。实现了这个接口,就必须确保使用这些方法。接口只是一种形式,接口自身不能做任何事情
相同点:
1.他们都不能生成实例,都有抽象方法。
2.接口是特殊的抽象类。
3.接口和抽象类的继承都使用的关键字是 extends。
不同点:
抽象类
- 抽象类中可以定义构造器
- 可以有抽象方法和具体方法
- 成员可以使private、默认、protected、public
- 可以定义成员变量
- 有抽象方法的类必须被声明为抽象类,而抽象类未必要有抽象方法
- 抽象类中可以包含静态方法
- 一个类只能继承一个抽象类
接口
- 接口中不能定义构造器
- 方法全是抽象方法
- 成员全是public
- 定义的成员变量实际上都是常量
- 不能有静态方法
- 一个类能实现多个接口
34.静态嵌套类(Static Nested Class)和内部类(Inner Class)的不同
可以在一个类的内部定义另一个类,这种类称之为嵌套类(nested classes);嵌套类分为两种类型:1. 静态嵌套类 2. 非静态嵌套类,静态嵌套类很少使用,非静态嵌套类也被称之为内部类(Inner Class),嵌套类从JDK1.1开始引入.其中inner类又可分为三种:
- 在一个类(外部类)中直接定义的内部类
- 在一个方法(外部类的方法)中定义的内部类;
- 匿名内部类
静态嵌套类
public class StaticTest {
private static String name = "张三";
private String num = "001";
static class Person // 静态嵌套类
{
private String address = "China";
public String mail = "why278816957@163.com";// 内部类公有成员
public void display() {
// System.out.println(num);//不能直接访问外部类的非静态成员
System.out.println(name);// 只能直接访问外部类的静态成员
System.out.println("Inner " + address);// 访问本内部类成员。
}
}
public void printInfo() {
Person person = new Person();
person.display();
// System.out.println(mail);//不可访问
// System.out.println(address);//不可访问
System.out.println(person.address);// 可以访问内部类的私有成员
System.out.println(person.mail);// 可以访问内部类的公有成员
}
public static void main(String[] args) {
StaticTest staticTest = new StaticTest();
staticTest.printInfo();
}
}
35.Java 中会存在内存泄漏吗,请简单描述。
理论上 Java 有垃圾回收机制(GC)不会存在内存泄露问题(这也是 Java 被广泛使用于服务器端编程的一个重要原因);然而在实际开发中,可能会存在无用但可达的对象,这些对象不能被 GC 回收,因此也会导致内存泄露的发生。
2022-12-7
36.抽象的(abstract)方法是否可同时是静态的(static),是否可同时是本地方法(native),是否可同时被 synchronized 修饰?
都不能
抽象方法需要子类重写,而静态的方法是无法被重写的,因此二者是矛盾的。本地方法
是由本地代码(如 C 代码)实现的方法,而抽象方法是没有实现的,也是矛盾的。synchronized 和方法的实现细节有关,抽象方法不涉及实现细节,因此也是相互矛盾的。
37.阐述静态变量和实例变量的区别
静态变量是被 static 修饰符修饰的变量,也称为类变量,它属于类,不属于类的任何一个对象,一个类不管创建多少个对象,静态变量在内存中有且仅有一个拷贝;
实例变量必须依存于某一实例,需要先创建对象然后通过对象才能访问到它。
静态变量可以实现让多个对象共享内存。
38.是否可以从一个静态(static)方法内部发出对非静态(non-static)方法的调用?
不可以
静态方法只能访问静态成员;非静态方法的调用要先创建对象,因为在调用静态方法时可能对象并没有被初始化。
39.如何实现对象克隆?(不懂)
第一种
实现 Cloneable 接口并重写 Object 类中的 clone()方法;
第二种
实现 Serializable 接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆,
40.GC 是什么?为什么要有 GC?
GC 是垃圾回收的意思
因为内存处理这块是开发人员容易出错的地方,忘记或是错误地回收内存,可能会导致程序或者系统不稳定甚至崩溃,所以 Java 提供垃圾回收机制可以自动地检测对象是否超过作用域,从而达到自动回收的目的。
2022-12-8
41.String s = new String(“xyz”);创建了几个字符串对象?
两个对象
一个是静态区的 “xyz”,一个是用new创建在堆上的对象
42.接口是否可继承(extends)接口?抽象类是否可实现(implements)接口?抽象类是否可继承具体类(concrete class)?
接口可以继承接口,而且支持多重继承。
抽象类可以实现(implements)接口,抽象类可继承具体类也可以继承抽象类。
43.一个".java"源文件中是否可以包含多个类(不是内部类)?有什么限制?
可以有多个类
但是一个源文件中只能有一个 public 的类,并且 public 的类名必须与文件名相一致
44.Anonymous Inner Class(匿名内部类)是否可以继承其它类?是否可以实现接口?
可以继承其他类或者实现其他接口,在 Swing 编程和 Android 开发中常用此方式来实现事件监听和回调。
45.内部类可以引用它的包含类(外部类)的成员吗?有没有什么限制?
一个内部类对象可以访问创建它的外部类对象的成员,包括私有成员
2022-12-9
46.Java 中的 final 关键字有哪些用法?
- 修饰类:表示该类不能被继承
- 修饰方法:表示方法不能被重写
- 修饰变量:表示变量只能一次赋值以后值不能被修改(常量)
47.子父类加载顺序
创建对象时构造器的调用顺序是:
先初始化静态成员,然后调用父类构造器,再初始化非静态成员,最后调用自身构造器
48.数据类型之间的转换:
- 如何将字符串转换为基本数据类型?
- 如何将基本数据类型转换为字符串?
49.怎样将 GB2312 编码的字符串转换为 ISO-8859-1 编码的字符串?
String s1 = "你好";
String s2 = new String(s1.getBytes("GB2312"), "ISO-8859-1");
50.日期和时间
如何获取年月日 时分秒?
创建 java.util.Calendar 实例,调用其 get()方法传入不同的参数即可获得参数所对应的值。Java 8 中可以使用 java.time.LocalDateTimel 来获取;
public class DateTimeTest {
public static void main(String[] args) {
Calendar cal = Calendar.getInstance();
System.out.println(cal.get(Calendar.YEAR));
System.out.println(cal.get(Calendar.MONTH)); // 0 - 11
System.out.println(cal.get(Calendar.DATE));
System.out.println(cal.get(Calendar.HOUR_OF_DAY));
System.out.println(cal.get(Calendar.MINUTE));
System.out.println(cal.get(Calendar.SECOND));
// Java 8
LocalDateTime dt = LocalDateTime.now();
System.out.println(dt.getYear());
System.out.println(dt.getMonthValue()); // 1 - 12
System.out.println(dt.getDayOfMonth());
System.out.println(dt.getHour());
System.out.println(dt.getMinute());
System.out.println(dt.getSecond());
}
}
如何取得从 1970 年 1 月 1 日 0 时 0 分 0 秒到现在的毫秒数?
Calendar.getInstance().getTimeInMillis();
System.currentTimeMillis();
Clock.systemDefaultZone().millis(); // Java 8
如何取得某月的最后一天?
Calendar time = Calendar.getInstance();
time.getActualMaximum(Calendar.DAY_OF_MONTH);
如何格式化日期?
利用 java.text.DataFormat 的子类(如 SimpleDateFormat 类)中的 format(Date)方法可将日期格式化。Java 8 中可以用 java.time.format.DateTimeFormatter 来格式化时间日期。
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Date;
/**
* @version 1.0
* @Author HaiYang
* Created on 2022/12/12 18:10
*/
public class DateTimeTest {
public static void main(String[] args) {
SimpleDateFormat oldFormatter = new SimpleDateFormat("yyyy/MM/dd");
Date date1 = new Date();
System.out.println(oldFormatter.format(date1));
// Java 8
DateTimeFormatter newFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
LocalDate date2 = LocalDate.now();
System.out.println(date2.format(newFormatter));
}
}
打印昨天的当前时刻
import java.util.Calendar;
public class DateTimeTest {
public static void main(String[] args) {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, -1);
System.out.println(cal.getTime());
}
}