因为马上开始2019秋招、平时的学习比较琐碎、JAVA后端博大精深,想在暑假这段时间从头开始整理JAVA知识点查缺补漏,迎战2019秋招。主要参考(微信公众号)JAVA团长与(博客园)五月的仓颉的知识点复习线,对其列出的每一个的知识点再一次的咀嚼并谈谈自己的理解。(平时从这两位学到很多,也非常感谢身边同行的人)
JAVA基础
1、面向对象的四个特征
封装:封装给对象提供了隐藏内部特性的行为和行为的能力。对象提供一些能被其他对象访问的方法来改变他内部的数据。在java中有如下几个public private protect三种修饰符每一种修饰符都有不同的访问权限,还有一种是不加修饰符。
public--所有外部类都可以访问(公有)
private--本类可以访问(私有)
protected--包内和子类可访问(保护)
不写(default)--包内可访问 (默认)
封装有以下几个好处1、通过隐藏对象的属性来保护对象内部的状态2、提高了代码的可维护性,因为对象的行为可以被单独的改变或者是扩展。禁止对象之间的不良交互提高模块化。
继承:继承给对象提供了从基类获取字段和方法的能力。继承提供了代码的可重用性,也可以在不修改类的情况下给现存的类添加新特性。
多态:多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。因为在程序运行时才确定具体的类,这样,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上,从而导致该引用调用的具体方法随之改变,即不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性。
抽象:抽象是吧想法从具体的实例中分离出来的步骤,因此,要根据他们的功能而不是实现细节来创建类。java支持创建只暴露接口而不包含方法实现的抽象的。(dubbo的服务生产者和消费者,就是通过接口的暴露)
2、final、finally、finalize的区别
final 关键字如果一个类被声明为final,意味着他不能在派生出新的类,final对java而言就是perfect 认为这是一个完美的东西才会使用。因此一个既不能被声明成abstract有被声明成final的。将变量或方法声明final 可以保证他们在使用这不被改变。被声明的final的变量、若是基本类型,会是一个定值就不能被再次复制。若为对象则是传引用,引用不可修改,而引用的值可以修改。(java的传值与传引用问题可以关注一下)这里还值得一提的是匿名内部类的形参一定要final。因为首先我们知道内部类编译后也会有一个class文件这个并不与外部类是同一个class文件,仅仅对外部类传入的参数需要被内部调用的话。希望它使用一个其外部定义的参数那么编译会要求改参数是final。在内部类中的属性和外部方法的参数两者从外表上看是同一个东西,但实际上却不是,所以他们两者是可以任意变化的,也就是说在内部类中我对属性的改变并不会影响到外部的形参,而然这从程序员的角度来看这是不可行的,毕竟站在程序的角度来看这两个根本就是同一个,如果内部类该变了,而外部方法的形参却没有改变这是难以理解和不可接受的,所以为了保持参数的一致性,就规定使用final来避免形参的不改变。
finally 在异常处理时提供finally块来执行任何操作,这个try catch finally 三步走,finally中是最后执行的步骤,一般用于资源的释放。
finalize:与上面两个不同这个是一种方法名,java允许使用finalize方法在垃圾收集器将对象从内存中清除之前做必要的清理工作。这个方法是由垃圾收集在确定这个对象没有被引用时对这个对象调用的,它是在Object类中定义的,因此所有的类都将继承于它。子类覆盖了Object中finalize方法中将可以写整理系统支援和执行其他清理工作。finalize方法在垃圾收集器删除对象之前对这个对象的调用。
3、int与Integer
int是基本数据类型,Integer是一个类对象,作为int类型的包装类型。这个种包装类型为int类型提供很多简便的操作,比如最常用的类型转换。但是响应的他做为一个类的对象他的内存占用也会发生改变,不再像原生数据类型boolean 1bytes、byte 1bytes、short 2bytes、char 2bytes、int 4bytes、float 4bytes、long 8bytes、double 8 bytes。对象有着自己的内存布局分为对象头、实例数据和对齐补充。其大小与运行的环境有关是32位还是64位、以及是否启用压缩。
4、重载与重写
重写:1、方法名、参数、返回值相同。2、子类方法不能缩小父类方法的访问权限。3子类方法不能抛出比父类方法更多的异常。4、方法被定义了final后不能重写(@override 注解用于判断)5发生在继承类中,是子类对父类的关系。
重载:1、参数类型、个数、顺序至少有一个不相同。2、不能重载只有返回值不同的方法,重载允许返回类型不同,但如果仅仅是返回类型不同是不允许的。3、既可以是子类对父类的关系、也可以存在同一个类中。
5、抽象类与接口的区别
接口interface关键字,他是公开的,里面方法与变量不可以是私有的,接口的存在就是被其他类去使用,抽象类可以拥有自己私有方法和私有变量。接口的出现解决了java不能多重继承的问题。1、我们可以这么认为抽象类是对类的抽象,接口是行为的抽象,所以接口相较更为抽象。2、设计层次不同,抽象类是一种自下而上的设计,先有子类才能提取出公共的属性与行为,抽象出父类。接口是一种自上而下的设计,先规定行为方法,只要可以实现这些行为,就可以成为接口的实现类。3、派生关系的不同,抽象类与其派生类是一种“is-a”,说明其父类子类本质是相同的。接口与其实现类是一种“like-a”即父类与派生子类的关系只是实现了定义的行为,而并无本质上的联系。
6、反射的用途与实现
Java放射主要提供一下功能:1、在运行时构造一个类的对象在运行时候才会有这个类的名字、确定一个对象的类、2判断一个类所具有的的成员变量和方法、3运行时调用一个动态对象的方法等很多框架中都会用到反射:著名的sprint IOC的实现就是反射的实现。我们都只pathon、PHP这些动态语言,java是一门静态类型语言。而静态语言的类型判断存在运行前会有编译阶段,其优点明显结构规范、便于调试、方便安全。但他也有着自己的缺点,相关的类型代码过多、命名不规范时候导致不易阅读。反射的反射机制就是JAVA成为准动态语言的一个关键性质,他允许程序运行时通过反射获得任何一个已知名称的class内部信息,包括正在运行中的类的属性信息,正在运行中的类的方法信息,正在运行中的累的构造信息,正在运行中类的访问修饰符等。但是大量的反射会影响系统的的性能大打折扣,如何平衡系统的架构的性能与反射应用的关系需要自己考虑。
附:java反射的invoke过程,method的invoke是委托给sun.reflect.MethodAccessor来处理。
7、说说自定义注解的场景及实现
注解的本质是继承Annotation的特殊接口,其具体的实现类是java运行生成的动态代理类,我们是通过反射是获取注解,返回的是JAVA运行时生成的动态代理对象。通过代理对象调用自定义注解的接口的方法,会最终调用AnnotationInvocationHandler中invoke方法,该方法会从memberValue这个Map中索引出对应的值,这个memberValue来源于java常量池,可以理解成字符串是hashmap中key键值,hashmap中value就是这个对象的信息。
注解又有四个元注解 1、@Documented –注解是否将包含在JavaDoc中 2、@Retention –什么时候使用该注解 3、@Target –注解用于什么地方4、@Inherited – 是否允许子类继承该注解
自定义注解类编写的一些规则:
1. Annotation型定义为@interface, 所有的Annotation会自动继承java.lang.Annotation这一接口,并且不能再去继承别的类或是接口.
2. 参数成员只能用public或默认(default)这两个访问权修饰
3. 参数成员只能用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和String、Enum、Class、annotations等数据类型,以及这一些类型的数组.
4. 要获取类方法和字段的注解信息,必须通过Java的反射技术来获取 Annotation对象,因为你除此之外没有别的获取注解对象的方法
5. 注解也可以没有定义成员, 不过这样注解就没啥用了
8、HTTP请求GET与POST的方式区别
GET方法会把名值对追加在请求的URL后面。因为URL对字符数目有限制,进而限制了用在客户端请求的参数值的数目。并且请求中的参数值是可见的,因此,敏感信息不能用这种方式传递。
POST方法通过吧请求参数值放在请求体中来克服GET方法的限制,因此,可以发送的参数的数目是没有限制的。最后POST请求传递敏感信息对外部客户端不可以见。
9、session与cookie
HTTP是一种无状态协议,为了分别谁发起,就需要我们自己去解决这个问题,不然有些情况下即使同一个网站我们每打开一个页面都要登陆一下,这样显然不太合理。而Session和Cookie就是为了解决这个问题提出的两个机制。通俗说,Cookie是访问某些网站以后再本地存储一些网站的相关信息,下次访问时候可以减少一些步骤。准确的说的话就是Cookies是服务器在本地机器上存储的小段文本并随每一个请求发送到同一个服务器,是一种客户端保持在线的方案。Session是存储在服务器的一种用来存放用户数据类的hashTable的结构,但这个值一般会有一个时间有效性。关于区别有两种理解:1 Session是服务端保存的一个数据结构,用来追踪用户的状态,这个数据可以保存集群、数据库、文件中,Cookie是客户端保存用户信息的一种机制,用来记录用户的一些信息,也是实现Session的一种方式。2 session是一种更抽象概念,开发者为了实现中断、继续等操作、抽象出“会话”进而衍生到“会话状态”,这也就是session的概念。cookie是一个实际存在东西,http协议中定义在header字段中,可以认为是sesion在后端无状态的实现。目前较好的通用实现方案就是讲session id借助cookie去显示。(前者服务端后者在客户端)
10、JDBC的加载
1、连接数据库首先要将驱动加载到JVM上,一般用常见的mysql ,Class.forName(“”com.mysql.jdbc.Driver“”),成功加载后会将实例注册到DriverManager类中。
2、提供JDBC的URL,jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=gbk;useUnicode=true;(MySql的连接URL)表示使用Unicode字符集。如果characterEncoding设置为 gb2312或GBK,本参数必须设置为true 。characterEncoding=gbk:字符编码方式。还需要用户名 密码
3、要连接数据DriverManager请求并获得Connection对象,该对象就是数据的连接 加载数据库,加载2中的信息。
4、创建一个statement(事务)(1)执行静态SQL语句。通常通过Statement实例实现。(2)执行动态SQL语句。通常通过PreparedStatement实例实现。(3)执行数据库存储过程。通常通过CallableStatement实例实现。
5、执行sql语句 INSERT UPDATE DELETE 等
6、处理结果可能是RESULTSET(结果集)也可能是影响的行数。
7、关闭对象、释放资源。
11、equal与==的区别
值类型(int、char、long等)都可以用==判断其相等性,对象引用的话,==判断引用所指的对象是否视同一个。equal是Object的成员函数,有些类会覆盖这个方法,用于判断对象的等价性,例如String类,两个引用所指String都是“abc”,但是可能出现他们实际对应的对象并不是同一个,(和JVM的实现方式有关系),因此==判断他们可能不相等,但用equals判断一定是相等的因为等价。这里补充举例一下,对于JDK1.6 String str1 = “abc”编译成字节码后,实际相当于String str1 = “abc".intern()。对于JDK1.6 intern方法是这样的 如果“abc”首次遇到 那么“abc”本身会被复制到字符串常量池中,且以后如果再遇到“abc”直接返回常量池的引用。JDK1.6常量池存在JVM的永久带中,对于hotspot虚拟机实现,永久代事实对应虚拟机规范中的方法区。对于JDK1.7而言 intern()方法不对字符串实例进行复制了,而只是字符串常量池中记录首次的实例引用。 最重要的是JDK1.7中字符串常量池是在堆中的。 具体参考“深入理解java虚拟机 ”42页和57页的讨论。