一、JavaSE基础
1.Java面向对象
面向对象有哪些特性以及如何理解?
- 封装 只对外提供接口,隐藏细节
- 继承 让系统或者功能有一定的延续性
- 多态 编译时的多态和运行时的多态 运行时的多态表现为:A系统访问B系统提供的服务时,B系统有多种提供服务的方式,但一切对A系统来说都是透明的。 还有一种是:方法重写(override) 编译时的多态表现为:方法重载(overload) 如果是四大特性,则加上“抽象” 抽象是将一类对象的共同特征总结起来构造类的过程,包括数据抽象和行为抽象两方面。
2.为什么要用clone?
new一个对象的过程和clone一个对象的过程区别?
Java中创建对象的5种方式 &&new关键字和newInstance()方法的区别 https://www.cnblogs.com/yunger/p/5793632.html
3.&&与&的区别
&&表示为:逻辑,短路运算符; 为何为称之为短路,因为如果&&左边的表达式值为false,右边的表达式就会被直接短路掉,不会进行运算
4.在Java中,如何跳槽当前的多重嵌套循环?
- 标记
- break 例如:
/**
* 使用标记方式
*/
public static void method1(){
System.out.println("***********method1***********");
ok:
for (int i = 1; i < 10; i++) {
for (int j = 1; j < 10; j++) {
if (i==5&&j==3) {
System.out.println("跳出:i="+i+",j="+j);
break ok;
}
}
System.out.println("外层i="+i);
}
}
/**
* 使用break或者countinue
*/
public static void method2(){
System.out.println("***********method2***********");
boolean flag = false;
for (int i = 1; i < 10&&!flag; i++) {
for (int j = 1; j < 10; j++) {
if (i==5&&j==3) {
flag = true;
System.out.println("跳出:i="+i+",j="+j);
break;
}
}
System.out.println("外层i="+i);
}
}
/**
* 这种是不会跳出外层循环,之后继续往下走
*/
public static void method3(){
System.out.println("***********method3***********");
for (int i = 1; i < 10; i++) {
for (int j = 1; j < 10; j++) {
if (i==5&&j==3) {
System.out.println("跳出:i="+i+",j="+j);
break;
}
}
System.out.println("外层i="+i);
}
}
public static void main(String[] args) {
method1();
method2();
method3();
}
结果如下:
5.当一个对象被当作参数传递到一个方法后,此方法可改变该对象的属性,并返回变化后的结果,属于值传递还是引用传递?
值传递,Java中只支持参数的值传递
6.重写(@override)和重载(@overload)的区别?
重载:
//顺序不同
public void method(int a,String b){
}
//类型不同
public void method(String a,int b) {
}
//个数不同
public void method(float a){
}
区别如下:
- 方法名一致,参数列表中参数的顺序、类型、个数不同
- 与方法的返回值无关----也就是说:返回类型不一样,也不能称为重载
- 可以抛出不同的异常,也可以有不同的修饰符
重写的规则
- 参数、返回类型一致
- 不能被重写的:构造方法、final、static
- 访问权限不能小于
- 不能抛出非强制异常
为什么不能根据返回类型区分重载?
因为在调用时,在不指定返回类型时,编译器是不知道要调用哪个函数的。 例如:
float a(int a,int b)
void a(int a,int b)
7.char变量能不能存储一个汉字,为什么?
可以,在Java中,编码格式为Unicode,char类型占2个字节。
8.抽象类(abstract class)和接口(interface)有什么异同?
相同之处:
- 不能被实例化
- 可以作为引用类型(即作为参数传递)
- 如果一个类继承了某个抽象类或者实现了某个接口,都需要对其中的方法进行实现,否则该类仍被需要声明为抽象类 例如:
public interface A {
int method1();
String method2();
}
//需要声明该类为抽象类
public abstract class C implements A{
@Override
public int method1() {
return 0;
}
//可省略该方法,因为未实现
@Override
public abstract String method2();
//错误
A a = new A();
//错误
B b = new B();
}
不同之处:
抽象类:
public abstract class B {
//1.抽象类中可以定义构造器
public B(){
}
//2.可以有抽象方法
abstract int method1();
//3.可以有具体方法
int method2(){
return 0;
}
//4.可以定义成员变量
int a;
//5.抽象类中可以有静态方法
static int method3(){
return 0;
}
//6.有抽象方法的类必须为抽象类,而抽象类中未必有抽象方法
//7.一个类只能继承一个抽象类
}
而接口:
- 接口中不能定义构造器
- 方法中全部都是抽象方法
- 修饰符可以是private、默认、protected、public
- 接口中的成员变量都是为常量
- 接口中不能有静态方法
- 一个类可以实现多个接口
9.Java的异常处理机制?
在Java中,对异常进行了分类,所有的类继承于Throwable这个类,下面的Exception和Error两个类继承,Error异常一般表现为:内存溢出、磁盘读写、jvm堆栈信息错误等,而Exception异常表示为可被处理的异常,又被分为检查异常和运行时异常。
10.finalize 什么作用
Object类的一个方法,在垃圾回收器执行的时候会调用被回收对象的方法,如果覆盖此方法,则可以在垃圾收集时的其他资源回收,例如:关闭文件等。
11.switch目前可以作用在什么类型上面?
java5之前:byte、short、char、int java5之后:增加枚举(enum) java7之后:增加String
12.Java中“+”和StringBuilder/StringBuffer哪个效率更高?为什么?示例:String s = "abc" + "ddd"。
依据情况而定,从反编译的代码中看到有很明显的区别,对于此问题,性能基本一致,但是如果对于循环操作的话,在反编译的过程中,会看到“+”被反编译了10次,创建了10次对象,造成了资源浪费
13.String s1 = "Java";String s2 = "Ja"+"va";s1==s2 ?那s1==s2.intern()
根据上个问题中,Java中的“+”在编译时会被翻译成StringBuilder,此时s2为一个对象,s1为字符串,为false String对象的intern()方法会得到字符串对象在常量池对于的版本引用,此时会返回true
14.如何得到日期的年月日?
java8
LocalDateTime dt = LocalDateTime.now();
//年
System.out.println(dt.getYear());
//月 1-12
System.out.println(dt.getMonthValue());
//日
System.out.println(dt.getDayOfMonth());
//时
System.out.println(dt.getHour());
//分
System.out.println(dt.getMinute());
//秒
System.out.println(dt.getSecond());
15.如何得到1970年1月1日0时0分0秒到现在的毫秒数?
//第一种
Calendar.getInstance().getTimeInMillis();
//第二种
System.currentTimeMillis();
//第三种:java8
Clock.systemDefaultZone().millis();
16.获取当月的第一天和最后一天?
SimpleDateFormat format = new SimpleDateFormat("yyyy-mm-dd");
//获取当月第一天
Calendar c1 = Calendar.getInstance();
c1.add(Calendar.MONTH, 0);
//设置为1号
c1.set(Calendar.DAY_OF_MONTH, 1);
String first = format.format(c1.getTime());
//获取当月最后一天
Calendar c2 = Calendar.getInstance();
c2.set(Calendar.DAY_OF_MONTH, c2.getActualMaximum(Calendar.DAY_OF_MONTH));
String last = format.format(c2.getTime());
System.out.println("该月第一天:"+first+",最后一天:"+last);
//Java8
LocalDate today = LocalDate.now();
//第一天
LocalDate firstDay = LocalDate.of(today.getYear(), today.getMonth(), 1);
LocalDate lastDay = today.with(TemporalAdjusters.lastDayOfMonth());
System.out.println("该月第一天:"+firstDay+",最后一天:"+lastDay);
17.如何格式化日期?
//第一种
SimpleDateFormat oldFormat = new SimpleDateFormat("yyyy/mm/dd");
Date date1 = new Date();
System.out.println(oldFormat.format(date1));
//Java 8
DateTimeFormatter newFormat = DateTimeFormatter.ofPattern("yyyy/mm/dd");
LocalDate date2 = LocalDate.now();
System.out.println(date2.format(newFormat));
在Java8中,引用了新的时间日期API,LocalDate、LocalTime、LocalDateTime、Clock、Instant等,使用了不变模式,是线程安全的。
18.获得昨日的当前时刻?
Calendar c1 = Calendar.getInstance();
c1.add(Calendar.DATE, 1);
System.out.println(c1.getTime());
//java8
LocalDateTime today = LocalDateTime.now();
LocalDateTime yest = today.minusDays(1);
System.out.println(yest);
19.Java 8的日期特性?
- 不变性 在的API中所有的类都是不可变的,线程为安全的
- 清晰 所有的方法都被明确定义用以实现相同的行为
- 可扩展性 基于IOS-8601日历系统上的
- 关注点分离 新的API将时间、日期、时间戳等分离开来
- 使用操作 所有的类都实现了一系列的方法 来完成:加、减、格式化等
20.Java 8 日期/时间常用API
21.总结日期
二、Java的数据类型
1.int和Integer有什么区别,为什么?
int是基本数据类型,Integer是对象,是为了可以让int当作对象来处理,java5时引用的自动装箱拆箱使得可以互换。 例如:
Integer a = new Integer(3);
Integer b = 3;
int c = 3;
//false b会自动装箱成Integer类型
System.out.println(a == b);
//true 因为:a自动拆箱成int类型再和c比较
System.out.println(a == c);
但也不是所有的都会相等。 例如:
Integer f1 = 100,f2=100,f3=150,f4=150;
//true
System.out.println(f1==f2);
//false 因为-128-127的数值不会new Integer对象,而是引用
System.out.println(f3==f4);
2.数据类型的转换
三、Java中的IO
1.字节流和字符流
2.字节流和字符流的区别?
- 字节流读取一个字节处理一个字节,字符流读取到一个或多个字节时,先去查指定的编码表,将查到的字符返回
- 字节流可以处理所有类型的数据,如mp3,图片等;字符流只能处理字符
- 字节流操作byte,字符流操作Unicode字符串
四、Java的集合
1.怎么对HashMap<Integer,User>进行排序?
思路:
- 取得entrySet
- 转换为list
- 循环list,放入linkedHashMap
//针对hashMap进行排序
public static HashMap<Integer, B> sortHashMap(HashMap<Integer, B> map){
//1.拿到map的键值对集合
Set<Entry<Integer, B>> entryset = map.entrySet();
//2.将set转换为list集合,为了使用工具类的排序方法
List<Entry<Integer, B>> list = new ArrayList<>(entryset);
//3.使用Collections集合类对list进行排序,排序规则可以使用匿名类实现
Collections.sort(list,new Comparator<Entry<Integer, B>>() {
@Override
public int compare(Entry<Integer, B> o1, Entry<Integer, B> o2) {
//按照age倒叙排序
return o2.getValue().getAge()-o1.getValue().getAge();
}
});
//4.创建一个有序的LinkedHashMap
LinkedHashMap<Integer, B> linkedHashMap = new LinkedHashMap<>();
//5.将list数据存放到linked中
for (Entry<Integer, B> entry : list) {
linkedHashMap.put(entry.getKey(), entry.getValue());
}
return linkedHashMap;
}
2.集合中哪些是线程安全的,如果不是怎么办?
- Vector、HashTable为线程安全的
- Collections工具类提供了相关的API,可以转换为线程安全的