面向对象的特征:

继承、封装和多态

final, finally, finalize 的区别

final

final关键字可以用于类,方法,变量前,用来表示该关键字修饰的类,方法,变量具有不可变的特性。

(1)final关键字用于基本数据类型前:这时表明该关键字修饰的变量是一个常量,在定义后该变量的值就不能被修改。

(2)final关键字用于方法声明前:这时意味着该方法时最终方法,只能被调用,不能被覆盖,但是可以被重载。

(3)final关键字用于类名前:此时该类被称为最终类,该类不能被其他类继承。

finalize

finalize方法来自于java.lang.Object,用于回收资源。

可以为任何一个类添加finalize方法。finalize方法将在垃圾回收器清除对象之前调用。

在实际应用中,不要依赖使用该方法回收任何短缺的资源,这是因为很难知道这个方法什么时候被调用。

finally

当代码抛出一个异常时,就会终止方法中剩余代码的处理,并退出这个方法的执行。假如我们打开了一个文件,但在处理文件过程中发生异常,这时文件还没有被关闭,此时就会产生资源回收问题。对此,java提供了一种好的解决方案,那就是finally子句,finally子句中的语句是一定会被执行的,所以我们只要把前面说的文件关闭的语句放在finally子句中无论在读写文件中是否遇到异常退出,文件关闭语句都会执行,保证了资源的合理回收。

Exception、Error、运行时异常与一般异常有何异同

error表示系统级的错误,是java运行环境内部错误或者硬件问题,不能指望程序来处理这样的问题,除了退出运行外别无选择,它是Java虚拟机抛出的。

exception 表示程序需要捕捉、需要处理的异常,是由与程序设计的不完善而出现的问题,程序必须处理的问题

Java中的异常,主要可以分为两大类,即受检异常(checked exception)和 非受检异常(unchecked exception)

对于受检异常来说,如果一个方法在声明的过程中证明了其要有受检异常抛出:

public void test() throw new Exception{ }

那么,当我们在程序中调用他的时候,一定要对该异常进行处理(捕获或者向上抛出),否则是无法编译通过的。这是一种强制规范。

这种异常在IO操作中比较多。比如FileNotFoundException ,当我们使用IO流处理一个文件的时候,有一种特殊情况,就是文件不存在,所以,在文件处理的接口定义时他会显示抛出FileNotFoundException,起目的就是告诉这个方法的调用者,我这个方法不保证一定可以成功,是有可能找不到对应的文件的,你要明确的对这种情况做特殊处理哦。

所以说,当我们希望我们的方法调用者,明确的处理一些特殊情况的时候,就应该使用受检异常。

对于非受检异常来说,一般是运行时异常,继承自RuntimeException。在编写代码的时候,不需要显示的捕获,但是如果不捕获,在运行期如果发生异常就会中断程序的执行。

这种异常一般可以理解为是代码原因导致的。比如发生空指针、数组越界等。所以,只要代码写的没问题,这些异常都是可以避免的。也就不需要我们显示的进行处理。

试想一下,如果你要对所有可能发生空指针的地方做异常处理的话,那相当于你的所有代码都需要做这件事。

请写出5种常见到的runtime exception

NullPointerException - 空指针引用异常
ClassCastException - 类型强制转换异常。
IllegalArgumentException - 传递非法参数异常。
ArithmeticException - 算术运算异常
ArrayStoreException - 向数组中存放与声明类型不兼容对象异常
IndexOutOfBoundsException - 下标越界异常
NegativeArraySizeException - 创建一个大小为负数的数组错误异常
NumberFormatException - 数字格式异常
SecurityException - 安全异常
UnsupportedOperationException - 不支持的操作异常

int 和 Integer 有什么区别,Integer的值缓存范围

1. 默认值不同,基本类型的默认值为0, false或\u0000,包装类默认为null

2. 初始化不同,一个需要new,一个不需要

3. 存储方式不同

4. int.class是原始类型,Integer.class是对象类型, 所以一个有成员变量和方法,一个没有。包装类就是把基本类型 「包装」 在一个类里,并提供一些常用的操作。毕竟面向对象。
-128》127

包装类,装箱和拆箱

https://blog.csdn.net/w372426096/article/details/81909792

String、StringBuilder、StringBuffer

String是字符串常量,StringBuffer是字符串变量(线程安全),StringBuilder是字符串变量(非线程安全)。

简要说,String类型和StringBuffer类型主要性能区别其实在于String是不可变对象,每次对String类型进行改变其实都等同于生成了一个新的String对象,然后将指针指向新的String对象,所以经常改变内容的字符串最好不用String,而如果是StringBuffer,每次结果都会对StringBuffer对象本身进行操作,而不是新的对象,所以一般情况下推荐使用StringBuffer.

StringBuffer

java.lang.StringBuffer线程安全的可变字符序列。一个类似于String的字符串缓冲区,可将字符缓冲区安全地用于多个线程。

StringBuffer上主要操作是append和insert方法,可重载这些方法以接受任意类型的数据。

StringBulider

java.lang.StringBuilder 提供一个与StringBuffer兼容的API,但不保证同步,该类被设计用于StringBuffer的一个简易替换,用于字符串缓冲区被单个线程使用的时候。如果可能,建议优先使用。

大多数实现中,它比StringBuffer要快。

重载和重写的区别

重载(Overloading)和重写(Overriding)是Java中两个比较重要的概念。但是对于新手来说也比较容易混淆。

重载

简单说,就是函数或者方法有同样的名称,但是参数列表不相同的情形,这样的同名不同参数的函数或者方法之间,互相称之为重载函数或者方法。

重写

重写指的是在Java的子类与父类中有两个名称、参数列表都相同的方法的情况。由于他们具有相同的方法签名,所以子类中的新方法将覆盖父类中原有的方法。

关于重载和重写,你应该知道以下几点:

1、重载是一个编译期概念、重写是一个运行期间概念。

2、重载遵循所谓“编译期绑定”,即在编译时根据参数变量的类型判断应该调用哪个方法。

3、重写遵循所谓“运行期绑定”,即在运行的时候,根据引用变量所指向的实际对象的类型来调用方法

4、因为在编译期已经确定调用哪个方法,所以重载并不是多态。而重写是多态。重载只是一种语言特性,是一种语法规则,与多态无关,与面向对象也无关。(注:严格来说,重载是编译时多态,即静态多态。但是,Java中提到的多态,在不特别说明的情况下都指动态多态)

正是因为Java在继承中有方法的重写,所以,这也体现了Java的动态多态性。

重写,指的是方法。并没有提到成员变量。成员变量不会被重写,这里就有另外一个词:隐藏。

在一个类中,子类中的成员变量如果和父类中的成员变量同名,那么即使他们类型不一样,只要名字一样。父类中的成员变量都会被隐藏。在子类中,父类的成员变量不能被简单的用引用来访问。而是,必须从父类的引用获得父类被隐藏的成员变量,一般来说,我们不推荐隐藏成员变量,因为这样会使代码变得难以阅读。其实,简单来说,就是子类不会去重写覆盖父类的成员变量,所以成员变量的访问不能像方法一样使用多态去访问。

抽象类和接口有什么区别

接口和抽象类,最明显的区别就是接口只是定义了一些方法而已,在不考虑Java8中default方法情况下,接口中是没有实现的代码的。

抽象类中的抽象方法可以有public、protected和default这些修饰符,而接口中默认修饰符是public。不可以使用其它修饰符。

关于如何选择,我们一般会把接口暴露给外部,然后在业务代码中实现接口。如果多个实现类中有相同可复用的代码,则在接口和实现类中间加一层抽象类,将公用部分代码抽出到抽象类中。可以参考下模板方法模式,这是一个很好的理解接口、抽象类和实现类之间关系的设计模式。

说说反射的用途及实现

https://blog.csdn.net/w372426096/article/details/84616662

反射:https://blog.csdn.net/w372426096/article/details/82661866

说说自定义注解的场景及实现

https://blog.csdn.net/w372426096/article/details/84615928

列出自己常用的JDK包

java.lang: 这个是系统的基础类,比如String等都是这里面的,这个package是唯一一个可以不用import就可以使用的Package

java.io: 这里面是所有输入输出有关的类,比如文件操作等

java.net: 这里面是与网络有关的类,比如URL,URLConnection等。

java.util : 这个是系统辅助类,特别是集合类Collection,List,Map等。

java.sql: 这个是数据库操作的类,Connection, Statememt,ResultSet等

MVC设计思想

MVC是一种架构模式 --- 程序分层,分工合作,既相互独立,又协同工作

MVC是一种思考方式 --- 需要将什么信息展示给用户? 如何布局? 调用哪些业务逻辑?

MVC核心思想:业务数据抽取同业务数据实现相分离

equals与==的区别

equals()比较的是内容是否相同,'=='比较的是地址是否相同

hashCode和equals方法的区别与联系

hashCode()和equals()定义在Object类中,这个类是所有java类的基类,所以所有的java类都继承这两个方法。

hashCode()方法被用来获取给定对象的唯一整数。这个整数被用来确定对象被存储在HashTable类似的结构中的位置。默认的,Object类的hashCode()方法返回这个对象存储的内存地址的编号。

1、如果两个对象相等,那么他们一定有相同的哈希值(hash code)。

2、如果两个对象的哈希值相等,那么这两个对象有可能相等也有可能不相等。(需要再通过equals来判断)

http://www.hollischuang.com/archives/1290

什么是Java序列化和反序列化,如何实现Java序列化?或者请解释Serializable 接口的作用

https://blog.csdn.net/w372426096/article/details/83503619

Object类中常见的方法

registerNatives()   //私有方法
getClass()    //返回此 Object 的运行类。
hashCode()    //用于获取对象的哈希值。
equals(Object obj)     //用于确认两个对象是否“相同”。
clone()    //创建并返回此对象的一个副本。
toString()   //返回该对象的字符串表示。   
notify()    //唤醒在此对象监视器上等待的单个线程。   
notifyAll()     //唤醒在此对象监视器上等待的所有线程。   
wait(long timeout)    //在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量前,导致当前线程等待。   
wait(long timeout, int nanos)    //在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量前,导致当前线程等待。
wait()    //用于让当前线程失去操作权限,当前线程进入等待序列
finalize()    //当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。

Java的平台无关性如何体现出来的

跨平台指的是一种语言在计算机上的运行不受平台的约束,一次编译,到处执行。 平台无关有两种:源代码级和目标代码级。

我们常说的跨平台,或者平台无关,指的就是目标代码,或者说是软件交付件跨平台。

C和C++具有一定程度的源代码级平台无关,表明用C或C++写的应用程序不用修改只需重新编译就可以在不同平台上运行。但是,关键是要重新编译。可是,一般软件交付都是给你个成品,对于C或者C++开发出的软件,只能运行在某个平台的。没有源码,怎么编译。

Java编译出来的是字节码,去到哪个平台都能用,只要有那个平台的JDK就可以运行,所以,Java程序的最大优势就是平台无关。对于Java,交付的就是一堆jar包或者war包,只要系统上有个Java虚拟机,就可以直接运行,这不就是跨平台了么。

我们使用的C、C++还有Java等高级语言,都需要最终被编译成机器语言,才能被计算机执行。

C语言和C++语言的编译过程是把源代码编译生成机器语言。这样机器可以直接执行。但是不同系统对同一段“机器语言”的处理结果可能是不一样的,原因可能有很多,比如CPU的指令集不同的。C语言不能实现跨平台运行,就是因为它编译出来的文件的格式,只适用于某种cpu,其他cpu无法识别。

那么Java是如何实现跨平台的呢?

我们编写的Java源码,编译后会生成一种 .class 文件,称为字节码文件。这种字节码文件需要经过JVM虚拟机,然后翻译成机器语言,才能被机器执行。

那么,由于我们可以在不同的操作系统上安装不同的JVM,而JVM封装了所有对于.class文件的处理,即JVM帮我们把字节码翻译成机器语言的过程中就已经充分考虑到对应平台的特性了。比如,一个.class文件,在不同机器上最终生成的机器语言可能是不同的,但是这种不同不需要我们关心,JVM会保证他可以正常运行,完整的表达正确的程序语义。

JDK和JRE的区别.

JDK(Java Development Kit)是针对Java开发员的产品,是整个Java的核心,包括了Java运行环境JRE、Java工具和Java基础类库。Java Runtime Environment(JRE)是运行JAVA程序所必须的环境的集合,包含JVM标准实现及Java核心类库。JVM是Java Virtual Machine(Java虚拟机)的缩写,是整个java实现跨平台的最核心的部分,能够运行以Java语言写作的软件程序。

  

接口和类的区别

接口和抽象类,最明显的区别就是接口只是定义了一些方法而已,在不考虑Java8中default方法情况下,接口中是没有实现的代码的。

抽象类中的抽象方法可以有public、protected和default这些修饰符,而接口中默认修饰符是public。不可以使用其它修饰符。

关于如何选择,我们一般会把接口暴露给外部,然后在业务代码中实现接口。如果多个实现类中有相同可复用的代码,则在接口和实现类中间加一层抽象类,将公用部分代码抽出到抽象类中。可以参考下模板方法模式,这是一个很好的理解接口、抽象类和实现类之间关系的设计模式。

Java 8有哪些新特性

http://blog.didispace.com/books/java8-tutorial/

String s="abc"和String s=new String("abc")区别;

https://blog.csdn.net/huanghanqian/article/details/79514266

String s="a"+"b"和stringBuilder.append()的区别,常量池中存的是a,b,ab还是只有ab

看了反编译之后的代码我们发现,其实String对“+”的支持其实就是使用了StringBuilder以及他的append、toString两个方法。

常量池存在a,b,ab

Java中的回调机制;

https://www.jianshu.com/p/49ce57720d91

开闭原则说一下;

链接:牢记面向对象五个基本原则-HollisChuang's Blog

发布/订阅使用场景;

ZK,MQ

KMP算法(一种改进的字符串匹配算法);

Java 8流式迭代的好处?

序列化和反序列化底层如何实现的

ObjectOutputStream 、ObjectInputStream、 readObject writeObject

wait方法能不能被重写?

wait是final类型的,不可以被重写,不仅如此,notify和notifyall都是final类型的,wait能不能被中断;

让你设计一个cache如何设计;

JDK中哪些实现了单例模式?

split的源码,split("a|b|c");得出多少个数组;

String [] b = "a|b|c".split("\\|");需要转译

static的抽象方法可以吗?

静态是属于字节码的;一个抽象类可以没有抽象方法,只是为了不让别人来实例化它; 以上两点可以说明,静态方法只要有字节码存在就可以运行,所以抽象类中可以有静态方法。 我再多说一嘴,静态和抽象不能共存与方法上,因为静态属于字节码,不需要对象就可以运行,而抽象方法没有方法体,运行没有意义,所以不能共存。

Object toString 方法常用的地方,为什么要重写该方法

java提供默认toString方法不友好,打印出来看不懂,重写是为了程序猿自己能看懂

冯诺依曼体系结构

五大部件组成

1.存储器用来存放数据和程序

2.运算器主要运行算数运算和逻辑运算,并将中间结果暂存到运算器中

3.控制器主要用来控制和指挥程序和数据的输入运行,以及处理运算结果

4.输入设备用来将人们熟悉的信息形式转换为机器能够识别的信息形式,常见的有键盘,鼠标等

5.输出设备可以将机器运算结果转换为人们熟悉的信息形式,如打印机输出,显示器输出等

反向代理(Springboot,负载均衡)

从用途上来讲:正向代理的典型用途是为在防火墙内的局域网客户端提供访问Internet的途径。正向代理还可以使用缓冲特性减少网络使用率。反向代理的典型用途是将防火墙后面的服务器提供给Internet用户访问。反向代理还可以为后端的多台服务器提供负载平衡,或为后端较慢的服务器提供缓冲服务。另外,反向代理还可以启用高级URL策略和管理技术,从而使处于不同web服务器系统的web页面同时存在于同一个URL空间下。

从安全性来讲:正向代理允许客户端通过它访问任意网站并且隐藏客户端自身,因此你必须采取安全措施以确保仅为经过授权的客户端提供服务。反向代理对外都是透明的,访问者并不知道自己访问的是一个代理。

打个比方,a,b,c三个人,正向代理是a通过b向C借钱,a知道c的存在 。反向代理是a向b借钱,b又向C借,a不知道c的存在。

动态代理

代理:https://blog.csdn.net/w372426096/article/details/82659354

两个Integer的引用对象传给一个swap方法在方法内部交换引用,返回后,两个引用的值是否会发现变化

public class SwapTest {

private void swapTest(Integer i1,Integer i2){
        Integer tem = i1;
        i1 = i2;
        i2 = tem;

}

public static void main(String[] args) {
        // TODO Auto-generated method stub
        Integer i1 = new Integer(1);
        Integer i2 = new Integer(2);
        new SwapTest().swapTest(i1, i2);
        System.out.println(i1 +":" + i2);
    }

}

执行输出如下:
1:2

分析如下:
//这时候传入的只是i1,i2的两个内存引用
 new SwapTest().swapTest(i1, i2);

//然后在方法里i1,i2非调用时的i1,i2,再怎么去互换他的引用,也不影响在调用时候的引用。
    private void swapTest(Integer i1,Integer i2){
        Integer tem = i1;
        i1 = i2;
        i2 = tem;
    }

如果交换的是全局的引用,比如这样:

public class SwapTest {

private static Integer i1 = new Integer(1);
    private static Integer i2 = new Integer(2);
    private void swapTest(){
        Integer tem = i1;
        i1 = i2;
        i2 = tem;
    }

public static void main(String[] args) {
        new SwapTest().swapTest();
        System.out.println(i1 +":" + i2);
    }

}

执行输出结果:
2:1

字符串的格式化方法 ;时间的格式化方法

String format静态方法

System.out.println(String.format("hello %s", "world"));//hello world
    System.out.println(String.format("hello %c", 'a'));//hello a
    System.out.println(String.format("hello %b", false));//hello false
    System.out.println(String.format("hello %d", 15));//hello 15
    System.out.println(String.format("hello %f", 3.14));//hello 3.140000(注意帮我们算精度了,还是我们自己处理成String类型用%s传更好)
    System.out.println(String.format("合格率 %d%%", 20));//合格率 20%

https://blog.csdn.net/mengdao5323/article/details/78306462

SimpleDateFormat类,String.format(),Calendar类三种方法

类序列化时类的版本号的用途,如果没有指定一个版本号,系统是怎么处理的?如果加了字段会怎么样?

序列化是将对象的状态信息转换为可存储或传输的形式的过程。我们都知道,Java对象是保存在JVM的堆内存中的,也就是说,如果JVM堆不存在了,那么对象也就跟着消失了。而序列化提供了一种方案,可以让你在即使JVM停机的情况下也能把对象保存下来的方案。就像我们平时用的U盘一样。把Java对象序列化成可存储或传输的形式(如二进制流),比如保存在文件中。这样,当再次需要这个对象的时候,从文件中读取出二进制流,再从二进制流中反序列化出对象。

但是,虚拟机是否允许反序列化,不仅取决于类路径和功能代码是否一致,一个非常重要的一点是两个类的序列化 ID 是否一致,即serialVersionUID要求一致。

在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常,即是InvalidCastException。这样做是为了保证安全,因为文件存储中的内容可能被篡改。

当实现java.io.Serializable接口的类没有显式地定义一个serialVersionUID变量时候,Java序列化机制会根据编译的Class自动生成一个serialVersionUID作序列化版本比较用,这种情况下,如果Class文件没有发生变化,就算再编译多次,serialVersionUID也不会变化的。但是,如果发生了变化,那么这个文件对应的serialVersionUID也就会发生变化。

基于以上原理,如果我们一个类实现了Serializable接口,但是没有定义serialVersionUID,然后序列化。在序列化之后,由于某些原因,我们对该类做了变更,重新启动应用后,我们相对之前序列化过的对象进行反序列化的话就会报错。

定时器用什么做的

分布式调度系统:https://blog.csdn.net/u012379844/article/details/82716146

import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;public class TimeTest {public static void main(String[] args) {timer1();//timer2();//timer3();//timer4();}// 第一种方法:设定指定任务task在指定时间time执行 schedule(TimerTask task, Date time)public static void timer1() {Timer timer = new Timer();timer.schedule(new TimerTask() {public void run() {System.out.println("-------设定要指定任务--------");}}, 2000);// 设定指定的时间time,此处为2000毫秒}// 第二种方法:设定指定任务task在指定延迟delay后进行固定延迟peroid的执行// schedule(TimerTask task, long delay, long period)public static void timer2() {Timer timer = new Timer();timer.schedule(new TimerTask() {public void run() {System.out.println("-------设定要指定任务--------");}}, 1000, 5000);}// 第三种方法:设定指定任务task在指定延迟delay后进行固定频率peroid的执行。// scheduleAtFixedRate(TimerTask task, long delay, long period)public static void timer3() {Timer timer = new Timer();timer.scheduleAtFixedRate(new TimerTask() {public void run() {System.out.println("-------设定要指定任务--------");}}, 1000, 2000);}// 第四种方法:安排指定的任务task在指定的时间firstTime开始进行重复的固定速率period执行.// Timer.scheduleAtFixedRate(TimerTask task,Date firstTime,long period)public static void timer4() {Calendar calendar = Calendar.getInstance();calendar.set(Calendar.HOUR_OF_DAY, 12); // 控制时calendar.set(Calendar.MINUTE, 0);    // 控制分calendar.set(Calendar.SECOND, 0);    // 控制秒Date time = calendar.getTime();     // 得出执行任务的时间,此处为今天的12:00:00Timer timer = new Timer();timer.scheduleAtFixedRate(new TimerTask() {public void run() {System.out.println("-------设定要指定任务--------");}}, time, 1000 * 60 * 60 * 24);// 这里设定将延时每天固定执行}
}

线程如何退出结束

终止线程的三种方法
    有三种方法可以使终止线程。
    1.  使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。
    2.  使用stop方法强行终止线程(这个方法不推荐使用,因为stop和suspend、resume一样,也可能发生不可预料的结果)。
    3.  使用interrupt方法中断线程。 
1. 使用退出标志终止线程
    当run方法执行完后,线程就会退出。但有时run方法是永远不会结束的。如在服务端程序中使用线程进行监听客户端请求,或是其他的需要循环处理的任务。 在这种情况下,一般是将这些任务放在一个循环中,如while循环。如果想让循环永远运行下去,可以使用while(true){……}来处理。但要想使 while循环在某一特定条件下退出,最直接的方法就是设一个boolean类型的标志,并通过设置这个标志为true或false来控制while循环 是否退出。下面给出了一个利用退出标志终止线程的例子。

package chapter2; public class ThreadFlag extends Thread
{ public volatile boolean exit = false; public void run() { while (!exit); } public static void main(String[] args) throws Exception { ThreadFlag thread = new ThreadFlag(); thread.start(); sleep(5000); // 主线程延迟5秒 thread.exit = true;  // 终止线程thread thread.join(); System.out.println("线程退出!"); }
} 

在上面代码中定义了一个退出标志exit,当exit为true时,while循环退出,exit的默认值为false.在定义exit时,使用了一个 Java关键字volatile,这个关键字的目的是使exit同步,也就是说在同一时刻只能由一个线程来修改exit的值,
    2. 使用stop方法终止线程
    使用stop方法可以强行终止正在运行或挂起的线程。我们可以使用如下的代码来终止线程:
thread.stop();
    虽然使用上面的代码可以终止线程,但使用stop方法是很危险的,就象突然关闭计算机电源,而不是按正常程序关机一样,可能会产生不可预料的结果,因此,并不推荐使用stop方法来终止线程。
    3. 使用interrupt方法终止线程
    使用interrupt方法来终端线程可分为两种情况:
    (1)线程处于阻塞状态,如使用了sleep方法。
    (2)使用while(!isInterrupted()){……}来判断线程是否被中断。
    在第一种情况下使用interrupt方法,sleep方法将抛出一个InterruptedException例外,而在第二种情况下线程将直接退出。下面的代码演示了在第一种情况下使用interrupt方法。

package chapter2; public class ThreadInterrupt extends Thread
{ public void run() { try { sleep(50000);  // 延迟50秒 } catch (InterruptedException e) { System.out.println(e.getMessage()); } } public static void main(String[] args) throws Exception { Thread thread = new ThreadInterrupt(); thread.start(); System.out.println("在50秒之内按任意键中断线程!"); System.in.read(); thread.interrupt(); thread.join(); System.out.println("线程已经退出!"); }
} 

上面代码的运行结果如下:
    在50秒之内按任意键中断线程!
    sleep interrupted 
    线程已经退出!
    在调用interrupt方法后, sleep方法抛出异常,然后输出错误信息:sleep interrupted.
    注意:在Thread类中有两个方法可以判断线程是否通过interrupt方法被终止。一个是静态的方法interrupted(),一个是非静态的方 法isInterrupted(),这两个方法的区别是interrupted用来判断当前线是否被中断,而isInterrupted可以用来判断其他 线程是否被中断。因此,while (!isInterrupted())也可以换成while (!Thread.interrupted())。

对象的深浅复制

https://blog.csdn.net/baiye_xing/article/details/71788741

Java 8有哪些新特性:

Stream,lamda

Hashcode如何重写

Google首席Java架构师Joshua Bloch在他的著作《Effective Java》中提出了一种简单通用的hashCode算法

1. 初始化一个整形变量,为此变量赋予一个非零的常数值,比如int result = 17;

2. 选取equals方法中用于比较的所有域,然后针对每个域的属性进行计算:

(1) 如果是boolean值,则计算f ? 1:0

(2) 如果是byte\char\short\int,则计算(int)f

(3) 如果是long值,则计算(int)(f ^ (f >>> 32))

(4) 如果是float值,则计算Float.floatToIntBits(f)

(5) 如果是double值,则计算Double.doubleToLongBits(f),然后返回的结果是long,再用规则(3)去处理long,得到int

(6)如果是对象应用,如果equals方法中采取递归调用的比较方式,那么hashCode中同样采取递归调用hashCode的方式。 否则需要为这个域计算一个范式,比如当这个域的值为null的时候,那么hashCode值为0

(7)如果是数组,那么需要为每个元素当做单独的域来处理。如果你使用的是1.5及以上版本的JDK,那么没必要自己去 重新遍历一遍数组,java.util.Arrays.hashCode方法包含了8种基本类型数组和引用数组的hashCode计算,算法同上,

关于hashcode,我们一定要知道一个口诀:

1、hashcode相等,两个对象不一定相等,需要通过equals方法进一步判断;

2、hashcode不相等,两个对象一定不相等;

3、equals方法为true,则hashcode肯定一样;

4、equals方法为false,则hashcode不一定不一样;

Java基础的数据类型和占多少字节

一个字节8位

字符型:char(16位)

布尔型:boolean

数值型:1.整型:byte(8位)、short(16位)、int(32位)、long(64位) 2.浮点型:float(32位)、double(64位)

将long型的数据转换成int型,如何转换

一、强制类型转换

[java]  long ll = 300000;  int ii = (int)ll;

二、调用intValue()方法[java]  long ll = 300000;  int ii= new Long(ll).intValue();

三、先把long转换成字符串String,然后在转行成Integer[java]  long ll = 300000;

int ii = Integer.parseInt(String.valueOf(ll));

优化:

https://mp.weixin.qq.com/s/l0PdALKXma9MgcaMNmGZAg

【成神之路】Java基础相关面试题相关推荐

  1. Java工程师成神之路java基础知识之集合类(二)

    Java 8中Map相关的红黑树的引用背景.原理等 HashMap的容量.扩容 很多人在通过阅读源码的方式学习Java,这是个很好的方式.而JDK的源码自然是首选.在JDK的众多类中,我觉得HashM ...

  2. 【成神之路】Mysql相关面试题

    Mysql基础: DDL.DML.DCL分别指什么?数据库常见的命令? DDL(Data Definition Languages)语句:即数据库定义语句,用来创建数据库中的表.索引.视图.存储过程. ...

  3. 【成神之路】SSM相关面试题

    Springbean的作用域 bean的作用域 创建一个bean定义,其实质是用该bean定义对应的类来创建真正实例的"配方".把bean定义看成一个配方很有意义,它与class很 ...

  4. 【成神之路】集合相关面试题

    List 和 Set 区别 List,Set都是继承自Collection接口. 都是用来存储一组相同类型的元素的. List特点:元素有放入顺序,元素可重复 . 有顺序,即先放入的元素排在前面. S ...

  5. Alibaba技术专家倾心五年打造 Java成神之路:基础篇

    近日里,很多人邀请我回答各种j2ee开发的初级问题,我无一都强调java初学者要先扎实自己的基础知识,那什么才是Java的基础知识?又怎么样才算掌握了java的基础知识呢?这个问题还真值得仔细思考. ...

  6. cad的lisp程序大集合_大数据成神之路-Java高级特性增强(CopyOnWriteArraySet)

    大数据成神之路 大数据成神之路: 点我去成神之路系列目录^_^ 预计更新500+篇文章,已经更新40+篇~ 本系列的大纲会根据实际情况进行调整,欢迎大家关注~ 导语 CopyOnWriteArrayS ...

  7. JVM成神之路-Java内存模型(JMM)

    Java 内存模型基础 什么是 Java 内存模型(JMM-共享内存模型) 内存模型描述了程序中各个变量(实例域.静态域和数组元素)之间的关系,以及在实际计算机系统中将变量存储到内存和从内存中取出变量 ...

  8. Java详细学习路线及路线图(2020最新版) | Java工程师成神之路 | Java最全学习路线

    这篇文章主要是关于小白Java学习路线, 整个学习路线非常的清晰明确,适合各种层次的Java自学者,非常全面的Java学习路线. 整理不易,记得帮忙点个赞哟~ 第一阶段:Java基础 学习任何一门编程 ...

  9. JVM成神之路-Java垃圾回收

    Java垃圾回收机制 为什么要进行垃圾回收? 随着程序的运行,内存中存在的实例对象.变量等信息占据的内存越来越多,如果不及时进行垃圾回收,必然会带来程序性能的下降,甚至会因为可用内存不足造成一些不必要 ...

最新文章

  1. 统计学Java_【gloomyfish】基于Java的统计学计算结果
  2. 【Linux 内核】Linux 内核体系架构 ( 硬件层面 | 内核空间 | 用户空间 | 内核态与用户态切换 | 系统调用 | 体系结构抽象层 )
  3. 2.2.5 Adam优化算法
  4. Swift编程语言学习2.1——基础运营商(在)
  5. Lanchester战争模型:用可分离变量的微分方程占卜战事
  6. 【 Grey Hack 】记一次被黑经历
  7. oracle中修改多个字段默认值_利用VBA代码在已有的数据表中删除、添加、修改字段...
  8. ITextSharp生成PDF
  9. (27)VHDL实现非(数据流描述)
  10. 体检结果(2018年10月,胃肠镜)
  11. Linq之ToDictionaryTSource, TKey, TElement用法
  12. 2021-08-10 C3P0连接池
  13. Netty4.0学习笔记系列之二:Handler的执行顺序
  14. 闲谈IPv6-v4/v6协议转换报文的checksum无关性
  15. Hadoop安装教程 Mac版
  16. jpg转pdf怎么转换?jpg转pdf方法
  17. 水果编曲软件除了做电音还能做什么
  18. java web图书管理_基于Javaweb的图书管理系统
  19. 基于Multisim的220v转12v典型开关电源电路仿真
  20. 3无重复字符的最长子串longest-substring-without-repeating-characters

热门文章

  1. CSS选择器 优先级
  2. 智能取餐柜是什么东西?可以实现什么功能?
  3. 我的世界java种子 要塞,我的世界:中国版罕见种子,一个遗迹顶你十个,大多数玩家未见过...
  4. 一看就舒心的图片「唯美仙境」
  5. Black群晖7.01 CPU型号识别错误
  6. Coursera | Andrew Ng (02-week-3-3.1)—调参处理
  7. 强网杯 2019]随便注 【SQL注入】四种解法
  8. 苹果企业级开发者账号使用规范(同样适用于个人及公司级开发者账号)
  9. Allegro走线自动关闭其它飞线操作指导
  10. 算法题(四十):BFS解决网易2017年笔试题——地牢逃脱