一: 什么是函数式接口
定义: 首先是一个接口,其次这个接口只能存在一个抽象方法。
特点:
1、接口有且仅有一个抽象方法
2、允许定义静态方法
3、允许定义默认方法
4、允许java.lang.Object中的public方法
5、FunctionInterface注解不是必须的,如果一个接口符合"函数式接口"定义,那么加不加该注解都没有影响。加上该注解能够更好地让编译器进行检查。如果编写的不是函数式接口,但是加上了@FunctionInterface,那么编译器会报错。
二: 反射创建Class对象的三种方式
1、对象.getClass()
2、类.class
3、Class.forName(类的全路径)
得到class对象后,可以通过newInstance()或者newInstance(args)来创建无参或者有参的对象。
三:基本数据类型计算
小于int的数据类型(byte, char, short)进行运算时,首先会把这些类型的变量值强制转为int类型进行计算,最后会得到int类型的值,因此在这种类型计算的时候,非常需要注意计算结果的接收类型,如short计算,要使用Int类型接收,否则无法通过编译。
四:Short类型的计算
1、总结:
小于int类型的取值运算时都会被自动转换成int后再进行运算,因此要注意接收值的类型。
2、具体案例:
1、short a = 1; a = a + 1; 编译不通过,应该改为: a = (short)a + 1;
2、a +=1:编译通过,java语言规范中关于复合赋值(+=、-=等等): E1 op = E2等价与E1 = (T)(E1 op E2),其中T表示E1的数据类型,即复合赋值自带了隐式转换。
五:常见的JAVA类型和数据库类型对应关系
integer、int ---> int tinyint、smallint ---> short bigint ---> long decimal、numeric ---> java.math.BigDecimal float ---> float double ---> double char、varchar ---> String boolean、bit ---> boolean date ---> java.sql.Date time ---> java.sql.Time timestamp ---> java.sql.Timestamp blob ---> java.sql.Blob clob ---> java.sql.Clob array ---> java.sql.Array
六: Integer类型的最大最小值,LongL类型的最大最小值
一: Integer类型所占的字节数为: 4个字节,也就是32位,也就是2的32次方
最小值:Integer.MIN_VALUE=-2147483648
最大值:Integer.MAX_VALUE=2147483647
二:Long占8个字节
最小值:Integer.MIN_VALUE=-9223372036854775808
;最大值:Integer.MAX_VALUE=9223372036854775807
七:系统的健壮性指的是什么
健壮的程序并不是没有异常,而是能够处理异常和定位异常!
健壮性是指软件对于规范要求以外的输入情况的处理能力。所谓健壮的系统是指对于规范要求以外的输入能够判断出这个输入不符合规范要求,并能有合理的处理方式。
八: 双斜杠和单斜杠的区别
1.url前面是双斜杠(//mljr.com/car.html)双斜杠是相对协议进行url转换的,如果当前页使用的是https协议,那么转换后的url就是https://mljr.com/car.html。
2.url前面是单斜杠(/newcar.html) 单斜杠是相对服务器根目录进行url转换的
九:基本类型的常见装拆箱场景
特点:
装箱操作会创建对象,频繁的装箱操作会消耗许多内存,影响性能,所以可以避免装箱的时候应该尽量避免。
场景:
1、当两种不同类型用==比较时,包装器类的需要拆箱, 当同种类型用==比较时,会自动拆箱或者装箱。
2、当一个基础数据类型与封装类进行==、+、-、*、/运算时,会将封装类进行拆箱,对基础数据类型进行运算
3、不同类型的包装类equals比较返回的应该是false,因为基础数据类型都重写了equals方法,会先判断是不是相同类型,如果是才会判断值是否一致
4、equals(Object o) 因为原equals方法中的参数类型是封装类型,所传入的参数类型(a)是原始数据类型,所以会自动对其装箱,反之,会对其进行拆箱
5、当两种不同类型用==比较时,包装器类的需要拆箱, 当同种类型用==比较时,会自动拆箱或者装箱。
十:闭包
(一): 定义
是一种能被调用的对象,它保存了创建它的作用域的信息。Java并不能显式地支持闭包,但对于非静态内部类而言,它不仅记录了其外部类的详细信息,还保留了一个创建非静态内部类对象的引用,并且可以直接调用外部类的private成员,因此可以把非静态内部类当成面向对象领域的闭包。
(二): 内部类是面向对象的闭包 因为他不仅包含外围类对象的信息 还自动拥有一个指向此外围类对象的引用 在此作用域内 内部类有权操作所有的成员 包括private成员。
(三): 作用
闭包最主要的作用,是为变量提供一个生存环境
十一:一二三方包的区别
一方包(也称一方库)、二方包(也称二方库)、三方包(也称三方库)说明:
一方包:本工程中的各模块的相互依赖
二方包:公司内部的依赖库,一般指公司内部的其他项目发布的jar包
三方包:公司之外的开源库, 比如apache、ibm、google等发布的依赖
十二:MIME类型
定义:
互联网媒体类型,MIME类型就是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。
服务器将MIME标志符放入传送的数据中来告诉浏览器使用哪种插件读取相关文件。
十三:有无状态登录区别
(一):有状态登陆
定义: 服务端需要记录每次会话的客户端信息,从而识别客户端身份,如:Session和Cookie。
缺点:服务端需要保存大量数据,增加了服务端的压力,服务端保存用户状态,不支持集群化部署。
(二): 无状态登陆
定义:微服务集群中的每个服务,对外提供的都使用Restful风格的接口,RestFul风格的一个最重要的规范,服务的无状态性即:服务端不保存任何客户端请求者信息,客户端的每次请求必须具备自描述信息,通过这些信息识别客户端身份
优点:
1、客户端请求不依赖于服务端信息,多次请求不需要必须访问同一台服务器
2、服务段的集群和状态对客户端透明
3、服务段可以任意的迁移和伸缩 - 可以方便的进行集群化部署
4、减小了服务段的存储压力
(三): 无状态登录的步骤
1、客户端发送账户名/密码到服务端进行认证
2、认证通过后,服务端将用户信息加密并编码成一个token,返回给客户端
3、以后每次客户端请求,都需要携带认证的token
4、服务端对客户发送来的token进行解密,判断是否有效,并获取用户登陆信息
十四:JWT数据格式
主要包含以下三部分数据:
1、Header: 头部,通常包含以下消息(对头部进行Base64Url编码,可以得到第一部分数据)
声明类型,如:JWT
加密算法:自定义
2、Payload-载荷,就是有效数据,在RFC7519中,有7个示例信息
iss (issuer):表示签发人
exp (expiration time):表示token过期时间
sub (subject):主题
aud (audience):受众
nbf (Not Before):生效时间
iat (Issued At):签发时间
jti (JWT ID):编号
对头部进行Base64Url编码,可以得到第二部分数据
3、Signature:签名:
整个数据的认证信息,一般根据前两部的数据,加上服务的密钥secret(密钥保存在服务段,不能泄漏给客户端),通过Header配置的加密算法进行加密生成,用于验证整个数据完成和可靠性。三部分的数据之间使用"."分割。
十五:类的加载机制
Java中类的加载是使用”双亲委派机制”。
双亲委派机制:
当一个类加载器接收到类的加载请求时,它不会马上尝试自己加载,而是将这个请求委派给父级类加载器,每一个层级的加载器都是如此,因此所有的类加载器都会传给顶层的启动类加载器,只有当父类加载器无法加载时,子类加载器才会去进行加载,类加载器之间是组合关系而不是继承关系。
特性:
1、委派(delegation):子类加载器委派给父类加载器加载;
2、可见性(visibility):子类加载器可访问父类加载器加载的类,父类不能访问子类加载器加载的类;
3、唯一性(uniqueness):可保证每个类只被加载一次,比如 Object 类是被 Bootstrap ClassLoader 加载的,因为有了双亲委派模型,所有的 Object 类加载请求都委派到了 Bootstrap ClassLoader,所以保证了只被加载一次。
十六:双亲委派机制的作用是什么
1、一个类只能被一个加载器加载,防止类被多个加载器加载
2、保证核心.class不能被篡改。通过委托方式,不会去篡改核心.clas,即使篡改也不会去加载,即使加载也不会是同一个.class对象了。不同的加载器加载同一个.class也不是同一个Class对象。这样保证了Class执行安全。
十七:JAVA中存在哪些类加载器
1、启动类加载器(Bootstrap/Primordial/NULL ClassLoader):
顶层的类加载器,没有父类加载器。负责加载 /lib 目录下的,或者被 -Xbootclasspath 参数所指定路径中的类。
2、扩展类加载器(Extension CLassLoader):
由 sun.misc.Launcher$ExtClassLoader 实现,负责加载/lib/ext 目录下,或被 java.ext.dirs 系统变量所指定的目录下的所有类库。
3、应用程序类加载器(Application/System ClassLoader):
由sun.misc.Launcher$AppClassLoader 实现。它负责加载 classpath 下所指定的类库,如果应用程序没有自定义过自己的类加载器,一般情况下这个就是程序中默认的类加载器。
4、CustomClassLoader(用户自定义类加载器)
java编写,用户自定义的类加载器,可加载指定路径的class文件
十八: Abstract、final、static关键字的区别
1、Abstract表示抽象的,可以用于修饰类、方法,表示抽象类、抽象方法,具体的方法需要子类去重写。Final、static、private关键字不能与abstract关键字共用。
2、Final表示最终的,可以用于修饰类、方法、属性。表示类不可以被继承、方法不能被重写、属性是常量。final不能修饰构造方法
3、Static表示静态的,可以修饰类、方法、变量、代码块。被修饰的方法和变量可以直接通过类名进行访问。父类的静态方法可以被子类的静态方法覆盖。
十九:为什么被Static修饰的方法和属性可以直接通过类名访问
类是保存在字节码文件中的,JAVA中的类加载是指通过I/O流将类的字节码文件加载到JVM中。JVM会通过类的路径来找到字节码,被static修饰的变量、方法在类加载到JVM中时就被创建并初始化了,类的加载只会进行一次,故被static修饰的方法、变量可以直接通过类名进行访问。
二十:抽象类可以继承实体类?
可以,只要实体类有明确的构造方法。在JAVA的API文档中有说到,Object类是所有类的父类,因此抽象类是可以继承实体类的。
二十一:抽象类可以实例化?
不可以直接通过new来进行实例化,但是可以通过多态的方式”间接”实例化,如: 动物 = new 老虎();
延伸: 接口是不可以被实例化的,因为接口没有构造函数;
二十二:为什么main方法要定义成static?
因为在类加载的过程中是无法创建对象的,而静态方法可以直接通过类进行调用,所以在main方法定义成静态的,可以在类加载的时候通过main方法入口区运行程序。
二十三: 类何时被加载
1、创建对象的时候,对应命令:new
2、调用类的静态方法,对应命令:invokeStaic
3、调用类的静态属性 get/setStatic
加载子类的时候会先加载父类,类加载会有延迟加载的原则,只有需要的时候采取加载。
二十四:反射中Class.forName和ClassLoader的区别
1、两者都可以对类进行加载。ClassLoader遵循的是双亲委派模型,最终调用启动类加载器,实现通过一个类的全限定名获取该类的二进制字节流,放入到JVM中。forName最终也是调用ClassLoader来实现。
2、Class.forName对类加载时进行了初始化,而ClassLoader的loadClass并没有对类进行初始化,只是将类添加到了虚拟机中。
3、使用场景:
(1) Spring中的IOC使用了ClassLoader的方式加载。
(2)JDBC中用了Class.forName的方式,因为JDBC规范中明确需要Driver即数据库驱动类必须向DriverManager注册自己。
二十五:类的加载过程
1、加载:
通过类的全限定名获取类的二进制字节流,将它转换成方法区中运行时的数据结构,在内存中形成类对应的Class对象
2、链接
(1) 验证: 检查导入类或者接口的二进制正确性(如文件格式、元数据、字节码验证、符号引用等)
(2) 准备: 将类的静态变量分配并初始化存储空间
(3) 解析: 将常量池中的符号引用转为直接引用
3、初始化: 激活类的静态变量的初始化JAVA代码和静态代码快,并初始化程序员设置的值。
4、使用:
此时的类可以在程序中进行创建对象并使用
5、销毁 在合适的时间点,垃圾回收会对无用的对象回收,程序停止或者异常时,类也会被销毁。
二十六:会话跟踪技术
1、Cookie和Session是常见的会话跟踪技术。
2、Cookie:
一种会话技术,因为http是无状态请求,所以需要借助会话技术来记录客户端的状态。Cookie就是其中的一种,它的默认生命周期是浏览器的一次会话,一般是存储在内存中,如果设置了过期时间,则浏览器会将它持久化到硬盘上。
它具有不可跨域性,存在硬盘上的cookie可以在不同的浏览器进行间共享,同时,它也维护这session的唯一标识。
3、Session
一种会话技术,它是存储在服务器端。当执行HttpServletRequest.getSession(true)时被创建。
4、删除场景:
1、使用HttpSession.inValidate();
2、时间超过设置的session最大有效时间
3、服务器停止
设置有效时间:调用setMaxInactiveInterval(时间),-1表示永不过期
二十七:Session和Cookie的区别
1、Cookie是存储在客户端,Session是存储在服务端
2、Cookie维护着访问Session的SessionId,通过SessionId可以访问到指定的Session
3、因为Cookie是存储在客户端的,所以安全性低,Session是存储在服务端,安全性高
4、Cookie的大小一般是有限制的,但是Session的没有
5、Cookie只能存储String类型的对象,Session则没有限制
二十八:如果禁用了cookie,session还有作用?
有的,通过cookie携带的sessionID访问session只是其中的一种方式。如果浏览器禁止了Cookie,还可以通过以下的方式访问session:
1、URL重写: 将SessionID直接附加在URL路径中
2、表单隐藏域: 添加一个隐藏标签,name为jsessionid, 以便在表单提交时将sessionID传递给服务器
二十九:Session集群化时如何保持一致
1、Session复制:
将一台服务器上的Session复制到集群中的其他机器上。但是在集群规模大时,需要占用大量的资源和带宽,多用户时,还可能导致内存不够使用。
2、会话绑定/黏粘
用户的所有请求都在同一台服务器上处理。可以通过负载均衡的IP Hash地址算法实现。但是、不符合高可用、服务器宕机时则用户无法访问。
3、将Session存储在Cookie中
因为Cookie有大小限制,而且如果Cookie数据很多,每次传输会影响性能,且存在安全风险
4、Session持久化
将Session持久化到数据库或者缓存中,每次请求都去读取判断。如果是在缓存中,可能存在缓存和数据不一致的情况
三十:分布式和集群概念
分布式:
将不同地点、或具有不同功能或者具有不同数据的多台计算机通过网络连接起来,在控制系统的协调下,完成大规模的信息处理。
集群:
同一业务功能,部署在不同的机器上,从而达到高可用。
特点:
集群是物理形态,而分布式是工作方式。
废话不多说,直接上面试题目,如果觉得这些题目可能对你有帮助,欢迎继续阅读文章。
不积跬步,无以至千里;不积小流,无以成江海。今天播种努力的种子,总会有一天发芽!