Loading

Java基础

一、Java 基础

1.JDK与JRE的区别

  • JDK:Java Development Kit 的简称,java 开发工具包,提供了 java 的开发环境和运行环境。
  • JRE:Java Runtime Environment 的简称,java 运行环境,为 java 的运行提供了所需环境。

  具体来说 JDK 其实包含了 JRE,同时还包含了编译 java 源码的编译器 javac,还包含了很多 java 程序调试和分析的工具。简单来说:如果你需要运行 java 程序,只需安装 JRE 就可以了,如果你需要编写 java 程序,需要安装 JDK。

2. == 和 equals 的区别是什么?

== 解读

对于基本类型和引用类型 == 的作用效果是不同的,如下所示:

  • 基本类型:比较的是值是否相同;
  • 引用类型:比较的是引用是否相同;

equals 本质上就是 ==,只不过 String 和 Integer 等重写了 equals 方法,把它变成了值比较。

什么是面向对象?

 

3. 两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?

不对,两个对象的 hashCode()相同,equals()不一定 true。
代码示例:

    String str1 = "通话";
    String str2 = "重地";
    System.out.println(String.format("str1:%d | str2:%d", str1.hashCode(),str2.hashCode()));
    System.out.println(str1.equals(str2));

执行的结果:

    str1:1179395 | str2:1179395

    false

代码解读:很显然“通话”和“重地”的 hashCode() 相同,然而 equals() 则为 false
因为在散列表中,hashCode()相等即两个键值对的哈希值相等,然而哈希值相等,并不一定能得出键值对相等。

4. final 在 java 中有什么作用?

    final 修饰的类叫最终类,该类不能被继承。
    final 修饰的方法不能被重写。
    final 修饰的变量叫常量,常量必须初始化,初始化之后值就不能被修改。

 

6. String 属于基础的数据类型吗?

String 不属于基础类型,基础类型有 8 种:byte、boolean、char、short、int、float、long、double,而 String 属于对象。

 

7. java 中操作字符串都有哪些类?它们之间有什么区别?

操作字符串的类有:String、StringBuffer、StringBuilder。

String 和 StringBuffer、StringBuilder 的区别在于 String 声明的是不可变的对象,每次操作都会生成新的 String 对象,然后将指针指向新的 String 对象,而 StringBuffer、StringBuilder 可以在原有对象的基础上进行操作,
所以在经常改变字符串内容的情况下最好不要使用 String。 StringBuffer 和 StringBuilder 最大的区别在于,StringBuffer 是线程安全的,而 StringBuilder 是非线程安全的,但 StringBuilder 的性能却高于 StringBuffer,所以在单线程环境下推荐使用 StringBuilder,多线程环境下推荐使用 StringBuffer。

8. String str="i"与 String str=new String("i")一样吗?

不一样,因为内存的分配方式不一样。String str="i"的方式,java 虚拟机会将其分配到常量池中;而 String str=new String("i") 则会被分到堆内存中。

9. 如何将字符串反转?

使用 StringBuilder 或者 stringBuffer 的 reverse() 方法。

示例代码:

    // StringBuffer reverse
    StringBuffer stringBuffer = new StringBuffer();
    stringBuffer.append("abcdefg");
    System.out.println(stringBuffer.reverse()); // gfedcba
    // StringBuilder reverse
    StringBuilder stringBuilder = new StringBuilder();
    stringBuilder.append("abcdefg");
    System.out.println(stringBuilder.reverse()); // gfedcba

10. String 类的常用方法都有那些?

  • indexOf():返回指定字符的索引。
  • charAt():返回指定索引处的字符。
  • replace():字符串替换。
  • trim():去除字符串两端空白。
  • split():分割字符串,返回一个分割后的字符串数组。
  • getBytes():返回字符串的 byte 类型数组。
  • length():返回字符串长度。
  • toLowerCase():将字符串转成小写字母。
  • toUpperCase():将字符串转成大写字符。
  • substring():截取字符串。
  • equals():字符串比较。

11. 抽象类必须要有抽象方法吗?

不需要,抽象类不一定非要有抽象方法,但是包含抽象方法的类一定要被声明为抽象类。(自己的理解:锅里不一定必须得有水。但是有水必须得有个锅)

12. 普通类和抽象类有哪些区别?

普通类不能包含抽象方法,抽象类可以包含抽象方法。
抽象类不能直接实例化,普通类可以直接实例化。

13. 抽象类能使用 final 修饰吗?

不能,定义抽象类就是让其他类继承的,如果定义为 final 该类就不能被继承,这样彼此就会产生矛盾,所以 final 不能修饰抽象类,如下图所示,编辑器也会提示错误信息:

14. 接口和抽象类有什么区别?

    实现:抽象类的子类使用 extends 来继承;接口必须使用 implements 来实现接口。
    构造函数:抽象类可以有构造函数;接口不能有。
    main 方法:抽象类可以有 main 方法,并且我们能运行它;接口不能有 main 方法。
    实现数量:类可以实现很多个接口;但是只能继承一个抽象类。
    访问修饰符:接口中的方法默认使用 public 修饰;抽象类中的方法可以是任意访问修饰符。

15. java 中 IO 流分为几种?

  • 按数据流向:输入流和输出流

输入和输出都是从程序的角度来说的。

输入流:数据流向程序

输出流:数据从程序流出。
    

  • 按处理单位:字节流和字符流

字节流:一次读入或读出是8位二进制

字符流:一次读入或读出是16位二进制

JDK 中后缀是 Stream 是字节流;后缀是 Reader,Writer 是字符流

 

  • 按功能:节点流和处理流

节点流:直接与数据源相连,读入或写出

处理流:与节点流一块使用,在节点流的基础上,再套接一层

16. BIO、NIO、AIO 有什么区别?

  • BIO:Block IO 同步阻塞式 IO,就是我们平常使用的传统 IO,它的特点是模式简单使用方便,并发处理能力低。
  • NIO:New IO 同步非阻塞 IO,是传统 IO 的升级,客户端和服务器端通过 Channel(通道)通讯,实现了多路复用。
  • AIO:Asynchronous IO 是 NIO 的升级,也叫 NIO2,实现了异步非堵塞 IO ,异步 IO 的操作基于事件和回调机制。

面向对象五大基本原则是什么

    • 单一职责原则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)
      设计时采用多个与特定客户类有关的接口比采用一个通用的接口要好。就比如一个手机拥有打电话,看视频,玩游戏等功能,把这几个功能拆分成不同的接口,比在一个接口里要好的多。

 JAVA种8种基本数据类型

Byte、shortintlongcharfloatdoubleboolean

装箱和拆箱

自动装箱是 Java 编译器在基本数据类型和对应的对象包装类型之间做的一个转化。
比如:把
int 转化成 Integer,double 转化成 Double,等等。反之就是自动拆箱。 原始类型: booleancharbyteshortintlongfloatdouble 封装类型:Boolean,Character,Byte,Short,Integer,Long,Float,Double

String 转出 int 型,判断能不能转?如何转?

答:可以转,得处理异常 Integer.parseInt(s) 主要为 NumberFormatException:1)当
你输入为字母时,也就是内容不是数字时,如 abcd 2)当你输入为空时 3)当你输入超出
int 上限时 Long.parseLong("123")转换为 long

int和Integer的区别

1、Integer是int的包装类,int则是java的一种基本数据类型 
2、Integer变量必须实例化后才能使用,而int变量不需要 
3、Integer实际是对象的引用,当new一个Integer时,实际上是生成一个指针指向此对象;而int则是直接存储数据值 
4、Integer的默认值是null,int的默认值是0

 值传递与引用传递

值传递:
(形式参数类型是基本数据类型):方法调用时,实际参数把它的值传递给对应的形式参数,形式参数只是用实际参数的值初始化自己的存储单元内容,是两个不同的存储单元,
所以方法执行中形式参数值的改变不影响实际参数的值。 引用传递:
(形式参数类型是引用数据类型参数):也称为传地址。方法调用时,实际参数是对象(或数组),这时实际参数与形式参数指向同一个地址,
在方法执行中,对形式参数的操作实际上就是对实际参数的操作,这个结果在方法结束后被保留了下来,所以方法执行中形式参数的改变将会影响实际参数。

 重写和重载的特点和区别?

a)    重载
简单说,就是函数或者方法有同样的名称,但是参数列表不相同的情形,这样的同名不同参数的函数或者方法之间,互相称之为重载函数或者方法。
b)    重写
重写指的是在Java的子类与父类中有两个名称、参数列表和返回值类型都相同的方法的情况。由于他们具有相同的方法签名,所以子类中的新方法将覆盖父类中原有的方法。
重写是父类与子类之间的多态性,对父类的函数进行重新定义。
c)    区别
重载是让类以统一的方式处理不同类型数据的一种手段。多个同名函数同时存在,具有不同的参数个数/类型。重载是一个类中多态性的一种表现。
而重写是父类与子类之间的多态性,是对父类的函数进行重新定义。

final, finally, finalize的区别。

final 用于声明属性,方法和类, 分别表示属性不可变, 方法不可覆盖, 类不可继承.
finally 是异常处理语句结构的一部分,表示总是执行.
finalize 是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等. JVM不保证此方法总被调用.

事务的特性有那些

a)    原子性(Atomicity)
事务中的所有操作要么全部执行,要么都不执行。如果事务没有原子性的保证,那么在发生系统 故障的情况下,数据库就有可能处于不一致状态。
b)    一致性(Consistency)
主要强调的是,如果在执行事务之前数据库是一致的,那么在执行事务之后数据库也还是一致的。所谓一致性简单地说就是数据库中数据的完整性,包括它们的正确性。
c)    隔离性(Isolation)
即使多个事务并发(同时)执行,每个事务都感觉不到系统中有其他的事务在执行,因而也就能保证数据库的一致性。
d)    持久性(Durability)
事务成功执行后它对数据库的修改是永久的,即使系统出现故障也不受影响。

线程的状态都有哪些?创建一个线程的常用方法有哪些?

第一是创建(New)状态。在生成线程对象,并没有调用该对象的start方法,这是线程处于创建状态。 
  第二是就绪(Runnable)状态。当调用了线程对象的start方法之后,该线程就进入了就绪状态,但是此时线程调度程序还没有把该线程设置为当前线程,此时处于就绪状态。在线程运行之后,从等待或者睡眠中回来之后,也会处于就绪状态。 
  第三是运行(Running)状态。线程调度程序将处于就绪状态的线程设置为当前线程,此时线程就进入了运行状态,开始运行run函数当中的代码。 
  第四是阻塞(Blocked)状态。线程正在运行的时候,被暂停,通常是为了等待某个时间的发生(比如说某项资源就绪)之后再继续运行。sleep,suspend,wait等方法都可以导致线程阻塞。 
  第五是死亡(Terminated)状态。如果一个线程的run方法执行结束或者调用stop方法后,该线程就会死亡。对于已经死亡的线程,无法再使用start方法令其进入就绪。

一、继承Thread类创建线程子类
    1.在这子类中重写run方法,在run方法内写线程任务代码
    2.创建该子类实例,即是创建了一个线程实例
    3.调用该实例的start方法来启动该线程
二、建一个类去实现Runnable接口
    1.该类去实现接口的run方法,run方法内写线程任务代码
    2.创建该类实例,把该实例当作一个标记target传给Thread类,如:Thread t = new Thread(该类实例);即创建一个线程对象
    3.调用线程的star方法来启用该线程

阐述你对构造函数以及常量的理解?

构造函数是类在实例化成对象时用来做一些事情的,而这些事情是该对象被创建时必须做的事。例如初始化属性,
但不限于此。另外我们可以对构造函数进行重载,是让我们在类的实例化时能够更多元化。 简单地说,用final修饰过的变量就叫常量,常量一旦定义了就不允许被修改。
往大的说,定义常量,是不想让某些固定的属性或方法被调用后改变了值,或者被继承后重写。往底层说,常量存放在常量池里,在类加载之前就已经被加载,且不会改变。

静态变量与实例变量的区别

一种是被static关键字修饰的变量,叫类变量或者静态变量。另一种没有static修饰,为实例变量。
类的静态变量在内存中只有一个,java虚拟机在加载类的过程中为静态变量分配内存,静态变量位于方法区,被类的所有实例共享。
静态变量可以直接通过类名进行访问,其生命周期取决于类的生命周期。
而实例变量取决于类的实例。每创建一个实例,java虚拟机就会为实例变量分配一次内存,实例变量位于堆区中,其生命周期取决于实例的生命周期。

 二、容器

18. java 容器都有哪些?

常用容器的图录:

19. Collection 和 Collections 有什么区别?

    java.util.Collection 是一个集合接口(集合类的一个顶级接口)。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java 类库中有很多具体的实现。Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式,其直接继承接口有List与Set。
    Collections则是集合类的一个工具类/帮助类,其中提供了一系列静态方法,用于对集合中元素进行排序、搜索以及线程安全等各种操作。

21. HashMap 和 Hashtable 有什么区别?

    hashMap去掉了HashTable 的contains方法,但是加上了containsValue()和containsKey()方法。
    hashTable同步的,而HashMap是非同步的,效率上逼hashTable要高。
    hashMap允许空键值,而hashTable不允许。

22. 如何决定使用 HashMap 还是 TreeMap?

对于在Map中插入、删除和定位元素这类操作,HashMap是最好的选择。然而,假如你需要对一个有序的key集合进行遍历,TreeMap是更好的选择。

23. 说一下 HashMap 的实现原理?

    HashMap 基于 Hash 算法实现,通过 put(key,value) 存储,get(key) 来获取 value
    当传入 key 时,HashMap 会根据 key,调用 hash(Object key) 方法,计算出 hash 值,根据 hash 值将 value 保存在 Node 对象里,Node 对象保存在数组里
    当计算出的 hash 值相同时,称之为 hash 冲突,HashMap 的做法是用链表和红黑树存储相同 hash 值的 value
    当 hash 冲突的个数:小于等于 8 使用链表;大于 8 时,使用红黑树解决链表查询慢的问题

ps:
  • 上述是 JDK 1.8 HashMap 的实现原理,并不是每个版本都相同,比如 JDK 1.7 的 HashMap 是基于数组 + 链表实现,所以 hash 冲突时链表的查询效率低
  • hash(Object key)  方法的具体算法是 (h = key.hashCode()) ^ (h >>> 16),经过这样的运算,让计算的 hash 值分布更均匀

 24. 说一下 HashSet 的实现原理?

    HashSet底层由HashMap实现
    HashSet的值存放于HashMap的key上
    HashMap的value统一为PRESENT

25. ArrayList 和 LinkedList 的区别是什么?

最明显的区别是 ArrrayList底层的数据结构是数组,支持随机访问,
而 LinkedList 的底层数据结构是双向循环链表,不支持随机访问。
使用下标访问一个元素,ArrayList 的时间复杂度是 O(1),而 LinkedList 是 O(n)。

为什么基本类型不能做为HashMap的键值?

    Java中是使用泛型来约束 HashMap 中的key和value的类型的,HashMap<K, V>
    泛型在Java的规定中必须是对象Object类型的,基本数据类型不是Object类型,不能作为键值
    map.put(0, "ConstXiong")中编译器已将 key 值 0 进行了自动装箱,变为了 Integer 类型

Java中已经数组类型,为什么还要提供集合?

数组的优点:
    数组的效率高于集合类
    数组能存放基本数据类型和对象;集合中只能放对象 

数组的缺点:
    不是面向对象的,存在明显的缺陷
    数组长度固定且无法动态改变;集合类容量动态改变
    数组无法判断其中实际存了多少元素,只能通过length属性获取数组的申明的长度
    数组存储的特点是顺序的连续内存;集合的数据结构更丰富
JDK 提供集合的意义:
    集合以类的形式存在,符合面向对象,通过简单的方法和属性调用可实现各种复杂操作
    集合有多种数据结构,不同类型的集合可适用于不同场合
    弥补了数组的一些缺点,比数组更灵活、实用,可提高开发效率

 

 
 
posted @ 2021-02-09 14:14  Robinzhao  阅读(55)  评论(0)    收藏  举报