Java基础知识

1、面向对象

1.定义:面向过程更注重事情的每一个步骤及顺序,面向对象更注重有哪些参与者(对象)及各自需要做什么
2.优缺点:面向过程比较直接高效,面向对象更易于复用、扩展和维护。
3、三大特性:
 1)封装:可明确标识出允许外部使用的成员函数/数据项
 2)继承:继承基类方法,并做出自己的改变和扩展,子类共性的方法或者属性直接使用父类的,而不需要自己再定义,只需扩展自己个性的
 3)多态:基于对象所属类的不同,外部对同一个方法的调用,实际执行的逻辑不同,多态需要满足三个条件:继承、方法重写、父类引用指向子类对象
     父类类型 变量名 = new 子类对象;
     变量名.方法名();

2、JVM性能调优

1、性能调优的目的:为了减少STW(stop the Word),也就是在GC事件发生过程中,会产生应用程序的停顿,停顿产生时整个应用程序线程就会被暂停,没有任何响应,有点像卡死的感觉,这个停顿被称为STW
2、常用来被分析影响应用性能的工具arthans,(alibaba开源工具)可诊断具体那个Java程序最影响性能,占用线程最多。

3、JDK、JRE、JVM三者区别和联系

JDk:Java development kit java开发工具
JRE:Java runtime environment Java运行时环境
JVM:Java virtual machine Java虚拟机
![1649862830(1)](/assets/1649862830(1)_hrcqqgotj.jpg)

4、==和equals的区别

==对比的是栈中的值,基本数据类型对比的是变量值,引用类型对比的是堆中内存对象的地址
equals:object中也是默认采用==比较,比较内容是否相同。
举例:==就好比是要求必须是同一个房子,equals则要求房子一样就行

5、final

1.修饰类:表示类不可被继承
2.修饰方法:表示方法不可以被子类覆盖,但是可以重载
3.修饰变量:表示变量一旦被赋值就不可以更改他的值
(1)final修饰成员变量:
 -如果final修饰的是类变量,只能在静态初始化块中指定初始值或者声明该类变量时指定初始值
 -如果final修饰的是成员变量,可以在非静态初始化块声明该变量或者构造器中执行初始值
(2)final修饰局部变量
 -系统不会为局部变量进行初始化,局部变量必须由程序员显示初始化,因此使用final修饰局部变量时,可以在定义的时候指定默认值(后面的代码不能对变量再赋值),也可以不指定默认值,而在后面的代码中对final变量赋初始值(仅一次)
(3)final修饰基本类型数据和引用类型数据
 -如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;
 -如果是引用类型的变量,则在对其初始化之后不能再让其指向另一个对象,但是引用的值是可变的。

6、String、StringBuilder、StringBuffer

-String是final修饰的,不可变,每次操作都会产生新的String对象,影响性能
-StringBuffer和StringBuilder都是在原对象上操作
-StringBuffer是线程安全的,StringBuilder线程不安全
-StringBuffer方法都是synchronized修饰的
性能:StringBuilder>StringBuffer>String
-如何选择使用这三个场景:经常需要改变字符串内容时使用后面两个
-优先使用StringBuilder,多线程使用共享变量时使用StringBuffer

7、重载和重写的区别

-重载:发等在同一个类中,方法名必须相同,参数类型不同、个数不同、顺序不同,方法返回值和访问修饰符可以不同,发生在编译时。
-重写:发生在父子类中,方法名、参数列表必须相同,返回值小于等于父类,抛出的异常范围小于等于父类,访问修饰符范围大于等于父类,如果父类方法访问修饰符为private则子类就不能重写该方法。

8、接口和抽象类的区别

 -抽象类可以存在普通成员函数,而接口中只能存在public abstract方法
 -抽象类中的成员变量可以是各种类型的,但接口中的成员变量只能是public static final类型的
 -抽象类只能继承一个,接口可以实现多个。

9、List和Set的区别

List:有序,按照对象进入的顺序保存对象,可重复,允许多个null元素对象,可以使用iterator(迭代器)取出所有元素,再逐一遍历。也可以使用get(int index)获取指定下标的元素
Set:无序,不可重复,最多只能允许一个null元素对象,只能使用iterator(迭代器)取出所有的元素,再逐一遍历。

10、ArrayList和LinkedList的区别

1、ArrayList:基于动态数组,连续内存存储,适合下标访问(随机访问),扩容机制因为数组长度固定,超出长度存数据的时候需要新建数组,
2、LinkedList:基于链表,可以存储在分散的内存中,适合做数据插入和删除操作,不适合查询,需要逐一遍历。

11、进制转换

-Integer.parseInt(String s,int a)表示将“int a”进制的数“String s”转换成十进制

12、HashMap和HashTable的区别和底层实现

区别:
1)HashMap方法没有synchronized修饰,是线程非安全的,HashTable线程安全的;
2)HashMap方法允许key和value为null,而HashTable是不允许的
底层实现:数组+链表实现
-计算key的hash值,二次hash然后对数组长度模,对应到数组下标,也就是数组中要存放的位置;
-如果没有产生hash冲突(下标位置没有元素),则直接创建node存入数组;
-如果产生hash冲突,先进行equals比较,相同则取代该元素,不同,则判断链表高度将该元素插入链表中。需要注意的是,链表高度达到8,数组长度到64,则链表转变为红黑树来存储元素,当数组长度小于64的时则红黑树自动转变为链表。
-当key为null时,则将元素存到下标为0位置。

13 continue和break的用法

1.continue语句是指跳过循环体中剩余语句而强制执行下一次循环,其作用为结束本次循环,即跳过本次循环体中下面还未执行的语句,接着进行是否执行下一次循环的判定。
注意:continue语句只能用在while、for或foreach语句的循环体之中,在这之外的任何地方使用他都会引起语法错误。
2.break语句指强制退出循环,忽略循环体中的任何其他语句和循环体的判断条件,在循环中遇到break语句时循环终止,在循环后面的语句重新开始。
• continue: 用在循环中,基于条件控制,
            "跳过"  某次循坏体内容的执行,继续下一次的执行

• break:
        用在循环中,基于条件控制,
        "终止"   循坏体内容的执行,也就是说结束当前的整个循环

14.str.substring()用法

str.substring(int startIndex)表示截取掉从首字母开始起长度为startIndex长度的字符串,留下剩余的字符串;
str.substring(int startIndex,int endIndex)表示截取从startIndex开始(包含)到endIndex(不包含)的字符串长度,截取到的字符就是需要的值。
示例:
“hamburger”.substring(4) returns “urger” //取得是截取后剩下的值
“smiles”.substring(1, 5) returns “mile” //包含1,不包含5

15、Math.min()和Math.max()方法释义

Java.lang.math.min() 是Java中的内置方法,用于从给定的两个参数返回Minimum或Lowest值。参数采用int,float,double和long形式。
Math.max()则是返回最大的那个值

16、map.getOrDefault()方法作用

java中map.getOrDefault(Object key,V defaultValue)方法的作用是当map集合中有这个key的时候,就使用这个key值,即key对应的value值,否则就使用默认值defaultValue。
-这个方法在统计字符出现次数的时候很方便,会让代码简洁。
示例:
  HashMap<String, String> map = new HashMap<>();
	map.put("name", "jackeylove");
	map.put("age", "18");
	map.put("sex", "男");
	String name = map.getOrDefault("name", "rookie");
	System.out.println(name);// jackeylove,map中存在name,获得name对应的value
	int score = map.getOrDefault("score", "2018世界冠军");
	System.out.println(score);// 2018世界冠军,map中不存在score,使用默认值defaultValue

17、