注:1. 参数列表(参数签名)包含参数类型,个数及顺序,只要一个不同则参数列表不同。
2. 在java中,定义类的对象(类的实例)不会分配内存空间,必须使用new关键字来分配内存空间。
3. 类的成员:属性(变量或成员变量)和方法(函数)。
4. 类可以包含以下变量类型:局部变量,成员变量,类变量。
局部变量作用在方法或语句块中。变量声明和初始化在方法中,方法结束后,变量自动销毁。
成员变量作用在类内,方法体之外,这种变量在创建对象的时候实例化(分配内存)。可被类中方法和特定类的语句访问。
类变量声明在类内,方法体之外,但必须声明为static类型。
5. 构造方法(构造函数/构造器):在类实例化的过程中自动执行的方法叫做构造方法,不需要手动调用。
构造方法的名字与类名相同,但没有返回值,每个类都有构造方法,不能被继承。
6.Java代码先被编译为字节码(不同平台生成的字节码是相同的),再由JVM翻译成机器码运行( 不同平台JVM生成的机器码是不同的)。
1. 面向对象特征
封装、继承、多态。
-
封装
封装:把客观事物封装成抽象的类。把一个对象的属性私有化,同时提供一些可供外界访问类属性的方法。 -
封装的好处
-
[1]良好的封装能够减少耦合
-
[2]类内部的结构可以自由修改
-
[3]可以对成员进行更精确的控制
-
[4]隐藏信息,实现细节
-
继承
继承:它可以实现现有类的所有功能,并在无需编写原来类的情况下,对这些功能进行扩展。
-
[1]子类拥有父类非private的方法
-
[2]子类可以拥有自己的属性和方法,即对父类进行扩展。
-
[3]子类可以用自己的方式实现父类的方法。
-
[4]构造器(只能调用,不能继承)和private属性不能继承。
-
编译器会默认给子类调用父类的构造器。
-
若父类没有构造器,则子类要显示的指定父类的构造器。
-
protected关键字:对于类用户而言,它是private;对于任何继承自此类的子类或任何位于同一个包的类而言,它是可以访问的。
-
向上转型:猫继承自动物,猫是动物的一种,猫看作动物就是一种向上转型。
-
多态
多态的方式:重写(覆盖)override(在运行时决定)和重载overload(在编译时决定)。
- 重写:父类和子类间的多态性,子类和父类的方法同名且参数的个数和类型相同,返回值也一样。
(1)重写方法不能抛出比被重写方法更宽泛的异常。
(2)访问权限不能比被重写方法的访问权限更低。
(3)声明为final的方法不能被重写。
(4)声明为static的方法不能被重写,但能够再次被声明。
静态方法在编译时是将静态方法和类的引用类型进行匹配,若可以重写,则静态方法会与类的引用类型发生冲突。
(5)子类和父类在同一个包中,子类可以复写父类除private和final方法。
(6)在不同包中,子类只可重写父类中protected和public的非final方法。
(7)构造方法不能被重写。
(8)不能集成的方法,不能重写。
(9)父类方法只能被子类方法复写一次。
- 重载:是一个类定义了多个方法名相同,而参数个数不同或者参数个数相同,儿参数类型不同或次序不同。
(1)一个方法可以在所有类中被重载多次。
(2)方法重载在抛出异常和访问权限方面没有特殊要求。
(3)方法重载的参数列表必须不一致。
(4)方法重载用于同一个类中的所有方法,包括从父类继承的方法。
2.final,finally,finalize区别
- final
(1)final声明属性、方法、类。
表示属性不可变,方法不可覆盖、类不可继承(final类中的所有方法会被隐式指定为final方法)
(2)对于final变量,如果是基本数据类型的变量,则其数值一旦初始化后就不可更改。如果是引用型的变量,对其初始化之后不能再指向另一个对象。
(3)使用final方法的原因:把方法锁定,以防止任何继承类修改它的含义;效率。
- finally
异常处理语句结构的一部分,表示总是执行。
- finalize
object类的一个方法,在垃圾回收器执行时会调用被回收对象的此方法,可以覆盖(重写)此方法提供垃圾收集时的其他资源回收,比如关闭文件。
3. equals 和 == 区别
注:(1)Object类位于java.lang包中,是所有java类的祖先,java中的每个类都由它扩展而来。
(2)在java中,只有基本类型不是对象,如数值,字符和布尔型的值。所有的数组类型(对象数组,基本类型数组)都继承自object类。
(3)object类定义了一些有用的方法,由于是根类,这些方法也在其他的类中存在,一般是进行了重载或复写,实现各自具体的功能。
- equals()与 ==
(1)用来检测一个对象是否等于另一个对象。语法为public boolean equals(Object obj),对类File,String,Date及包装类来说,是比较类型及内容,而不考虑引用的实例是否是同一实例。
(2)equals只能用于比较引用类型,==可以用来比较基本类型和引用类型。
(3)equals()比较的两个数据只要是引用类型即可。
用 == 比较的两边数据类型必须一致,否则编译出错。
4. int和integer区别 static,this ,super
-
基本数据类型
boolean,int,long,float,double,char,byte -
引用数据类型
数组,类,接口 -
包装类类型:Boolean,Integer,Long,Floate,Double,Character,Byte
(1)Integer是int的包装类,int是基本数据类型。
(2)Integer必须实例化后才能使用,int不需要。
(3)integer实际是对象的引用,指向此new的Integer对象。
int直接存储数据类型。
Integer变量和Int变量比较时,若两个变量的值相等,则返回True,
两个new的integer变量永远是不相等的,返回False.
(4)Integer的默认值是null,int默认值是0.
注:自动装箱:将基本数据类型重新转化为对象。
自动拆箱:将对象重新转化为基本数据类型。
在-128–127内,数据被装箱为integer对象后,会存在内存中被重用,始终只有一个对象。
(参考链接 https://blog.csdn.net/chenliguan/article/details/53888018)
- static
(1)修饰成员变量和成员方法,被类内所有对象共享。
被static声明的成员变量属于静态成员变量,静态变量存放在java内存区域的方法区。
(2)调用格式:
类名.静态变量名
类名.静态方法名()
(3) 静态代码块:定义在类内方法外,在非静态代码块前执行(静态代码块->非静态代码块->构造方法)。该类不管创建多少对象,静态代码块只执行一次。
(4)静态内部类
(5)静态导包
- this
(1)this可以表示当前对象本身,或当前类的一个实例。
通过this可以调用对象本身的所有属性和方法。
(2)使用this区分同名变量。若在方法内的变量和成员变量同名时,想要在方法内调用成员变量,只能使用this。
public class Demo{
public String name;
public int age;
public Demo(String name, int age){ //构造函数
this.name = name; //调用成员变量name,age
this.age = age;
}
public void say(){
System.out.println("网站的名字是" + name + ",已经成立了" + age + "年"); //成员变量的作用域是整个实例,当然name,age前可以加上this,this.name,this.age
}
public static void main(String[] args) {
Demo obj = new Demo("微学苑", 3);
obj.say();
}
}
(3)作为方法名初始化对象
相当于调用本类的其他构造方法,它必须作为构造方法的第一句。
public class Demo{
public String name;
public int age;
public Demo(){
this("微学苑", 3); //this表示调用下面的构造方法
}
public Demo(String name, int age){
this.name = name; //this表示调用成员变量name,age
this.age = age;
}
public void say(){
System.out.println("网站的名字是" + name + ",已经成立了" + age + "年");
}
public static void main(String[] args) {
Demo obj = new Demo();
obj.say();
}
}
(4)作为参数传递(不懂)
需要在某些完全分离的类中调用一个方法,并将当前对象的一个引用作为参数传递。
匿名对象就是没有名字的对象。如果对象只使用一次,就可以作为匿名对象,代码中的new B(this).print()等价于(new B(this)).print();,先通过new B(this)创建一个匿名对象,再调用其方法。
public class Demo{
public static void main(String[] args){
B b = new B(new A());
}
}
class A{
public A(){
new B(this).print(); // 匿名对象
}
public void print(){
System.out.println("Hello from A!");
}
}
class B{
A a;
public B(A a){
this.a = a;
}
public void print() {
a.print();
System.out.println("Hello from B!");
}
}
运行结果:
Hello from A!
Hello from B!
- super
5.重载和重写的区别
6. 抽象类和接口的区别
OOP抽象的形式:抽象类和接口。
- 抽象类
使用abstract修饰符修饰的类。
定义:如果一个类没有足够多的信息来描述一个具体的对象,这样的类就是抽象类。(抽象类不一定包含抽象方法,但包含抽象方法的类是抽象类。)
(1)抽象类不能实例化(创建对象),因为没有足够的信息来描述一个对象。仍可以在类的实体{}定义成员变量,成员方法和构造方法等。
(2)抽象类中有抽象方法(只能被定义为public或protected)。
抽象方法只声明,不实现。由继承他的子类实现。(子类继承于一个抽象类,则需要实现所有抽象方法。若没有实现,则子类为abstract类。)
抽象方法被abstract修饰,只有方法名,没有方法实现,后面跟一个分号。如public abstract int A(); 具体要由子类实现。
(3)抽象类可以有构造器,而接口不可以有构造器。
- 接口
在Java中是一个抽象类型,是所有抽象方法(只能为public abstract方法)的集合,是一个集合,不是类。
一个类通过继承接口的方式从而继承接口的抽象方法。
接口只包含抽象方法(未实现的方法)。
抽象和接口一样不能实例化。但接口可以使用implements关键字实现。实现某个接口的类必须实现接口的全部方法。
虽然接口内的方法是抽象的,但是不需要abstract实现。
接口中没有构造方法,方法必须是抽象的(没有实现),变量类型只可有static和final。支持多继承(一个类可以实现多个接口)
接口中不可以有静态代码块和静态方法,但抽象类中可以有。
- 区别
(1)抽象类中可以有实现了的方法(即成员方法),接口中只能有抽象方法。
(2)抽象类由extends关键字实现,若子类不能实现所有的抽象方法,则把子类定义为abstract类,再由子类继承实现。
接口由Implements关键字实现,须实现接口中的所有抽象方法。
(3)抽象类可以有构造器,接口不可以。
(4)抽象方法可以有public,protected,default修饰符,接口方法默认是public修饰符,无其他修饰符。
(5)抽象类只能单继承,接口可以多继承。
(6)抽象方法比接口方法快。
(7)向抽象类中添加新方法,可以提供默认的实现,接口中只能存在抽象方法,所有在类中实现接口的所有抽象方法时要改变实现接口的类。
(参考连接 https://www.jianshu.com/p/038f0b356e9a)
7. 反射的用途及实现
反射的核心是JVM在运行时才动态加载类或调用方法或访问属性,它不需要事先知道运行对象是谁。
静态编译:在编译时确定类型,绑定对象。
动态编译:运行时确定类型,绑定对象。
- java反射框架主要提供以下功能:
(1)运行时判断任何一个对象所属的类;构造任意一个类的对象,判断任意一个类所具有的成员变量和方法;运行时调用任意一个对象的方法。
- 主要用途
反射最重要的用途就是开发各种通用框架。
- 反射基本功能的实现(反射相关的类一般在java.lang.reflect包里)
(1)获取class对象
(2)判断是否为某个类的实例
(3)创建实例
(4)获取方法
(5)获取构造器信息
(6)获取类的成员变量信息
(7)调用方法
(8)利用反射创建数组
8. 自定义注解的场景及实现
Java有四种原注解:@Retention, @Inherited,@Documented,@Target
- 场景
(1)类属性自动赋值
(2)验证对象属性完整性
(3)代替配置文件功能,像spring基于注解的配置。
(4)可以生成文档,像java代码注释中的@see,@param等。
- 实现
https://juejin.im/entry/57e496fd7db2a20063a24a3a
硬是看不懂
9. HTTP 请求的 GET 与 POST 方式的区别
(1)GET产生一个TCP数据包,POST产生两个TCP数据包。
对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。
https://learnku.com/articles/25881
(2)get在浏览器退回时是无害的,而post会再次提交请求。
(3)get产生的url会被bookmark(存为书签),而post不可以。
(4)GET请求会被浏览器主动cache,post不会,除非主动设置。
(5)get请求只能进行url编码,而post请求支持多种编码方式。
(6)get请求参数会被完整保留在浏览器历史记录中,而post参数不会。
(7)get请求在url中传送的参数有长度限制,post没有。
(8)get参数通过url传递,post参数在request body 中。
(9)get比post更不安全,参数直接暴露在url上,所有不能用来传递敏感信息。
10. session 与 cookie 区别
1.cookie数据是放在客户的浏览器上,session数据是放在服务器上的。
2.cookie不是很安全, 别人可以分析存放在本地的cookie进行cookie欺骗,考虑到安全应当使用session。
3. session在一定时间内会保存在服务器上,当访问增多的时候会比较占用服务器的性能,考虑到减轻服务器性能方面的考虑,可以使用cookie.
4,单个cookie保存的数据不能超过4k,很多浏览器都限制一个站点最多保存20个cookies.
5.可以考虑将登录信息等重要信息存为session,其他信息如果需要可以存为cookie。
6.cookie是一种发送到客户端浏览器的文本串句柄,并保存在客户机硬盘上,可以用来在某个web站点会话间持久的保持数据。
7,session其实就是一个访问者到达一个特定主页到离开为止的过程,session就是利用cookie进行信息处理的。当用户首先发出请求时,服务端就在用户浏览器上创建了cookie,当session结束,cookie也就过期了。
8.两者都是用来跟踪浏览器用户身份的会话方式。
9.两个都可以保存私密的东西,都有有效期的说法。区别在于session是放在服务器上的,过期与否取决于服务器端的设定,cookie是存在客户端的,过期与否可以在cookie生成的时候设置时期。若考虑减少性能的损失,应使用cookie;考虑安全的话,使用session。
如果web服务器端使用的是seesion,那么所有的数据都保存在服务器上,当浏览器第一次发送请求时,服务器会自动生成一个session和sessionid来唯一标识这个session,并将其通过响应发送给客户端。之后客户端每次请求服务器的时候都会发送当前回话的sessionid,服务器根据当前的sessionid判断相应的用户数据标志,已确定用户时候登陆或者具有某种权限。由于数据时存储在服务器上面,所以不能伪造,但是如果能够获取某个登录用户的sessionid,用特殊的浏览器伪造该用具的请求也是能够成功的。sessionid是服务器和客户端链接时候随机分配的,一般来说不会有重复,但是如果有大量的并发请求,也不是没有重复的可能性
如果浏览器使用的是cookie,那么所有的数据都保存在浏览器端,比如你登陆以后,服务器设置了cookie用户名,那么当你再次请求服务器的时候,浏览器会将用户名一块发送给服务器,这些变量有一定的特殊标记,服务器会解释为cookie变量,所以只要不关闭浏览器,那么cookie变量一直是有效的,所以能够保证长时间不掉线。如果你能够截获某个用户的cookie变量,然后伪造一个数据包发送过去,那么服务器还是认为你是合法的。所以,使用cookie被攻击的可能性比较大,如果设置了有效时间的话,那么它会将cookie保存在客户端的硬盘上,下次再访问该网站的时候,浏览器会先检查有没有cookie,如果有的话,就读取该cookie,然后发送给服务器。
链接:https://www.jianshu.com/p/eaa485b1d9e9
11. session 分布式处理
随着业务量的增长,系统架构需要做出调整,可以使用分布式架构或微服务架构。应用系统的单机部署模式已经不适用,因此需要将系统部署到多台服务器上。用户的请求会通过负载均衡技术转发到具体服务器上。会出现系统A登陆后并创建保存session,再次发起请求,请求被转发至系统B上显示未登录的情况。单机部署下的session机制已不能满足要求。所有,在分布式架构或微服务架构下,必须保证一个应用服务器上保存session后 ,其他服务器可以共享或同步该session。
- 分布式session管理实现方案
1,session复制
2.session粘滞
将用户的每次请求通过某种方式分发到某一指定服务器,只要这个web服务器存储了session数据,就可以实现session 会话跟踪。
3.session集中管理
在单独的服务器或集群上,使用缓存技术,如redis存储session数据,集中管理所有的session,所有的web服务器都从这个存储介质中存取对应的session,实现session共享。
可用开源方案spring session
4.基于cookie管理
12. JDBC 流程
java database connectivity.java数据库连接,是一种用于执行sql语句的API。可以为多种关系型数据库提供统一访问,由一组Java语言编写的类和接口组成。
https://blog.csdn.net/weixin_37139197/article/details/78838091
- JDBC流程
1.加载Driver类,注册数据库驱动。
2.通过DriverManager,使用url,用户名和密码建立连接connection。
3.通过connection,用sql语句打开statement对象。
4.执行语句,将结果返回给resultSet.
5.对结果进行处理。
6.倒序释放资源resultSet->preparedStatement->connection.
见连接 https://blog.csdn.net/weixin_37139197/article/details/78838091
13. MVC 设计思想
model,view,controller模型,视图,控制器
mvc是一种软件架构的思想,将一个软件按照视图,控制器,模型进行划分。
模型来封装业务逻辑,视图实现表现逻辑,控制器协调模型和视图。视图要通过控制器调用模型,模型返回的处理结果要先交给控制器,然后由控制器决定合适的视图显示模型的处理结果。
使用mvc开发web应用(javaee)
java类实现模型,servlet实现控制器,jsp实现视图。
缺点:会增加代码量,相应也会增加软件开发成本。设计难度也会增加。
14. 构造方法和方法的区别
(1)构造方法只有在创建对象时才会调用,且只调用一次。
方法是创建完对象之后才可以调用,可多次调用。
(2)this用法:构造方法使用this表示调用同一类中不同参数列表的另一个构造器。方法中的this指向正在执行方法的类的实例。
public class Platypus {
String name;
Platypus(String input) {
name = input;
}
Platypus() {
this("John/Mary Doe"); //构造器中调用另一个构造器,给成员变量name赋初值(在构造器中使用this必须放在第一行)
}
public static void main(String args[]) {
Platypus p1 = new Platypus("digger");
Platypus p2 = new Platypus();
}
}
(3)super的使用
(1)构造器和方法都用super指向超类。
方法用super指向超类中的被重载的方法。
class Mammal {
void getBirthInfo() { //被重载方法
System.out.println("born alive.");
}
}
class Platypus extends Mammal {
void getBirthInfo() {
System.out.println("hatch from eggs");
System.out.print("a mammal normally is ");
super.getBirthInfo(); //此处super调用父类(超类)中被重载的方法
}
}
构造器中调用super指向父类中的构造器 。且这行代码必须放在第一行。
public class SuperClassDemo {
SuperClassDemo() {}
}
class Child extends SuperClassDemo {
Child() { //Child构造器
super(); //调用父类的构造器。作用是将超类中的构造器SuperClassDemo实例化,并添加到Child类中。
}
}
(4)当写一个类时,没有写构造器,那么编译器会自动加上一个不带参数的构造器。
构造器的第一行没有super,编译器也会自动加上。
public class TestConstructors {
TestConstructors() {}
}
public class TestConstructors {
TestConstructors() {
super; //编译后自动加上super
}
}
(5)子类自动继承父类的方法,但是构造器不能被继承。