抽象类:
1.抽象类可以实现接口,且抽象类可以继承自抽象类;
2.抽象类指abstract修饰的类,可以包含也可不包含抽象方法;
3.抽象类和接口都不能实例化。
接口:
1.接口声明和外部类是一致的,都只能是public或default,注:default默认为public;
2.接口可以继承接口;
3.接口不能被实例化;
4.接口必须为public abstract,因为接口是高度抽象的类,它的存在就是被其他类实现,没有方法体;
5.接口中声明的变量必须为 public static final;
6.jdk1.8新特性,接口中的方法可以用static,default修饰,且二者修饰的方法要求有方法体。
接口和抽象类的区别:
1.一个子类只能继承一个抽象类(虚类),但能实现多个接口;
2.一个抽象类可以有构造方法,接口没有构造方法;
3.一个抽象类中的方法不一定是抽象方法,即其中的方法可以有实现(有方法体),接口中的方法都是抽象方法,不能有方法体,只有声明;
4.一个抽象类可以是public、private、protected、default, 接口只有public;
5.一个抽象类中的方法可以是public、private、protected、default, 接口中的方法只能是public和default.
类型转换:
1.类型转换发生精度丢失发生在大范围转换到小范围;
2.如double 到 int int a = (int) 8846.0;
3.byte 1字节 char 2字节
short 2字节 int 4字节
float 4字节 long 8字节
double 8字节 boolean 没有;
4.java中如果碰到char、byte和short参与运算时,会自动将这些值转换为int类型然后再进行运算;
5.低级向高级是隐式类型转换,高级向低级必须强制类型转换,byte<char<short<int<long<float<double。
Collection与Collections:
1.java.util.Collection 是一个集合接口,提供了对集合对象进行基本操作的通用接口方法;
2.Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式;
3.java.util.Collections 是一个包装类,包含有各种有关集合操作的静态多态方法,不能实例化,就像一个工具类,服务于Java的Collection框架。
重写和重载:
1.重写是父类与子类之间多态性的一种体现,实现同方法名,同参数,同返回类型,不同的实现,重写类权限要大与父类;
2.重写两同:方法名、形参列表相同,两小:返回值类型、抛出异常更小,这里的“小”指的是继承关系的子父类,不是像高赞所谓的float和int的大小之分,一大:访问修饰符;
3.重载是一个类中多态性的体现,方法名相同,参数个数不同,返回类型也可以不同,与修饰符无关;
4. 如果子类构造器没有显示地调用超类的构造器,则将自动地调用超类默认(没有参数)的构造器。如果超类没有不带参数的构造器,并且在子类的构造器中有没有显示地调用超类的其他构造器,则Java编译器将报告错误。使用super调用构造器的语句必须是子类构造器的第一条语句。
volatile:
1.保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的;
2.由于有些时候对 volatile的操作,不会被保存,所以不会造成阻塞,它不可用于多线程环境下的计数器。
加载jdbc驱动:
1.Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
2.DriverManager.registerDriver(new com.mysql.jdbc.Driver());
3.System.setProperty("jdbc.drivers","com.mysql.jdbc.Driver");
socket编程:
进程区域:
一条进程的栈区、堆区、数据区和代码区在内存中的映射
1>栈区:主要用来存放局部变量, 传递参数, 存放函数的返回地址。.esp 始终指向栈顶, 栈中的数据越多, esp的值越小;
2>堆区:用于存放动态分配的对象, 当你使用 malloc和new 等进行分配时,所得到的空间就在堆中。动态分配得到的内存区域附带有分配信息, 所以你 能够 free和delete它们;
3>数据区:全局,静态和常量是分配在数据区中的,数据区包括bss(未初始化数据区)和初始化数据区。;
注意:
1)堆向高内存地址生长;
2)栈向低内存地址生长;
3)堆和栈相向而生,堆和栈之间有个临界点,称为stkbrk。
特殊赋值符号:
1.<<=左移位赋值;
2.>>=带符号右移位;
3.>>>=无符号右移位。
线程:
1.start()用来启动线程,使其进入可运行状态,等待获取cpu使用权;
2.CyclicBarrier让一组线程等待其他线程;CountDownLatch让一组线程等待某个事件发生;
3. Callable能够抛出checked exception。
Java编译:
1.javac 将源程序编译为字节码;
2.java将字节码解释为机器码.exe。
代码执行顺序:
父类静态变量->父类静态块->子类静态变量->子类静态块->父类非静态成员变量->父类构造代码块->父类构造函数->子类非静态变量->子类构造代码块->子类构造函数。
函数或命名相关:
1.super.getClass().getName(),返回:包名+类名;
2.ArrayList list=new ArrayList(); 这种是默认创建大小为10的数组,每次扩容大小为1.5倍;
ArrayList list=new ArrayList(20); 这种是指定数组大小的创建,没有扩充;
3.Math.floor()取目标数轴左边的最近整数。
Session:
1.session用来表示用户会话,session对象在服务端维护,一般tomcat设定session生命周期为30分钟,超时将失效,也可以主动设置无效;
2.cookie存放在客户端,可以分为内存cookie和磁盘cookie。内存cookie在浏览器关闭后消失,磁盘cookie超时后消失。当浏览器发送请求时,将自动发送对应cookie信息,前提是请求url满足cookie路径;
3.可以将sessionId存放在cookie中,也可以通过重写url将sessionId拼接在url。因此可以查看浏览器cookie或地址栏url看到sessionId;
4.请求到服务端时,将根据请求中的sessionId查找session,如果可以获取到则返回,否则返回null或者返回新构建的session,老的session依旧存在。
引用传递和值传递:
1.引用数据类型是引用传递(call by reference),基本数据类型是值传递(call by value);
2.值传递不可以改变原变量的内容和地址---》原因是java方法的形参传递都是传递原变量的副本,在方法中改变的是副本的值,而不适合原变量的;
3.引用传递不可以改变原变量的地址,但可以改变原变量的内容---》原因是当副本的引用改变时,原变量 的引用并没有发生变化,当副本改变内容时,由于副本引用指向的是原变量的地址空间,所以,原变量的内容发生变化。
DBMS四个特性:
1.原子性:实现完整性管理子系统;
2.一致性:实现并发控制子系统;
3.持久性:实现恢复管理子系统;
4.隔离性:实现安全控制管理子系统。
叙述正误:
1.vector是线程安全的ArrayList,在内存中占用连续的空间。初始时有一个初始大小,当数据条数大于这个初始大小后会重写分配一个更大的连续空间。如果Vector定义为保存Object则可以存放任意类型;
2..try{}catch{}会增加额外的开销;
3..接口中声明的'变量'必须为public final static,所以为常量;
4.子类可以访问父类受保护的成员,但不能访问私有成员;
5.static 和 final共同修饰的类为静态不可重写类,而abstract 和 final不能共同修饰类,抽象类必须重写;
6.final修饰的变量为基本数据类型时,赋值后无法改变,当final修饰引用类型变量时,在赋值后其指向地址无法改变,但对象内容还是可以改变;
7.final修饰的成员变量在赋值时有三种方式:声明时赋值,在构造器中赋值,在初始代码块中赋值;
8.静态变量只能在类主体中定义,不能在方法中定义;
9.Java的静态方法属于类的成员,实例方法属于对象的成员。
牛油总结:
1.抽象方法只能定义在抽象类中,抽象方法和抽象类必须由abstract修饰,abstract关键字只能描述类和方法,不能描述变量。抽象方法只定义方法声明,不定义方法实现。抽象类不可以被实例化(创建对象),只有通过子类继承抽象类并覆盖抽象类中的所有抽象方法后,该子类才可以被实例化,否则该子类还是一个抽象类。抽象类中有构造函数用于给子类对象进行初始化,同时抽象类中可以含有非抽象方法。abstract关键字不可以与final,private,static关键字共存,因为被final修饰的方法不可以被重写,意味着子类不可以重写该方法,如果abstract和final共同修饰父类中的方法,子类要实现抽象方法(abstract的作用),而final又不让该方法重写,这相互矛盾。如果private和abstract共同修饰父类中的方法,private修饰则该方法不可以被子类访问,但是abstract修饰需要子类去实现,两者产生矛盾。如果static和abstract共同修饰父类中的方法,static表示是静态的方法,随着类的加载而加载,则该方法不需要在子类中去实现,这与abstract关键字矛盾;
2.static用于修饰成员变量和成员函数,想要实现对象中的共性数据的对象共享,可以将这个数据进行静态修饰,被静态修饰的成员可以直接被类名调用,静态随着类的加载而加载,而且优先于对象存在。静态方法只能访问静态成员(静态方法和静态变量),不可以访问非静态成员,这是因为静态方法加载时,优先于对象存在,所以没有办法访问对象中的成员。静态方法中不能使用this和super关键字,因为this代表本类对象,super代表父类对象,而静态时,有可能没有对象存在,所以this和super无法使用;
3.final关键字可以修饰类,方法,变量(成员变量内,局部变量,静态变量),被final修饰的类是一个最终类,不可以被继承,被final修饰的方法是一个最终方法,不可以被覆盖,但是可以被继承。被final修饰的变量只能是一个常量,只能赋值一次。内部类被定义在类中的局部位置上时,只能访问局部被final修饰的局部变量。
异常捕获和抛出:
1.在异常处理中,若try中的代码可能产生多种异常则可以对应多个catch语句,若catch中的参数类型有父类子类关系,此时应该将父类放在后面,子类放在前面;
2.throws用于在方法上声明该方法不需要处理的异常类型,用在方法上后面跟异常类名 可以是多个异常类;
3.throw用于抛出具体异常类的对象,用在方法内 后面跟异常对象只能是一个异常类型实体;
4.抛InterruptedException的代表方法有:
- java.lang.Object 类的 wait 方法
- java.lang.Thread 类的 sleep 方法
- java.lang.Thread 类的 join 方法。
ArrayList和LinkedList:
1.ArrayList基于数组实现的,查找快,增删慢;
2.LinkedList基于链表实现的,查找慢,增删快。
访问控制修饰符:
forward和redirect的区别:
1.从地址栏显示来说:
forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器.浏览器根本不知道服务器发送的内容从哪里来的,所以它的地址栏还是原来的地址.
redirect是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址.所以地址栏显示的是新的URL;
2.从数据共享来说:
forward:转发页面和转发到的页面可以共享request里面的数据.
redirect:不能共享数据;
3.从运用地方来说:
forward:一般用于用户登陆的时候,根据角色转发到相应的模块.
redirect:一般用于用户注销登陆时返回主页面和跳转到其它的网站等;
4.从效率来说:
forward:高.
redirect:低;
5.Forward和Redirect代表了两种请求转发方式:直接转发和间接转发。对应到代码里,分别是RequestDispatcher类的forward()方法和HttpServletRequest类的sendRedirect()方法;
对于间接方式,服务器端在响应第一次请求的时候,让浏览器再向另外一个URL发出请求,从而达到转发的目的。它本质上是两次HTTP请求,对应两个request对象;
对于直接方式,客户端浏览器只发出一次请求,Servlet把请求转发给Servlet、HTML、JSP或其它信息资源,由第2个信息资源响应该请求,两个信息资源共享同一个request对象。
类加载:
1. 什么是类加载器?
把类加载的过程放到Java虚拟机外部去实现,让应用程序决定如何去获取所需要的类。实现这个动作的代码模块称为“类加载器”。
2. 有哪些类加载器,分别加载哪些类
类加载器按照层次,从顶层到底层,分为以下三种:
(1)启动类加载器 : 它用来加载 Java 的核心库,比如String、System这些类
(2)扩展类加载器 : 它用来加载 Java 的扩展库。
(3) 应用程序类加载器 : 负责加载用户类路径上所指定的类库,一般来说,Java 应用的类都是由它来完成加载的。
3. 双亲委派模型
我们应用程序都是由以上三种类加载器互相配合进行加载的,还可以加入自己定义的类加载器。称为 类加载器的双亲委派模型 ,这里类加载器之间的父子关系一般不会以继承的关系来实现,而是都使用 组合关系 来复用父加载器的。
4. 双亲委托模型的工作原理
是当一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的类加载都是如此,因此所有的加载请求最终都应该传送到顶层的启动类加载器中,只有当父加载器反馈自己无法加载这个加载请求的时候,子加载器才会尝试自己去加载。
5. 使用双亲委派模型好处?(原因)
第一:可以避免重复加载,当父亲已经加载了该类的时候,子类不需要再次加载。
第二:考虑到安全因素,如果不使用这种委托模式,那我们就可以随时使用自定义的String来动态替代java核心api中定义类型,这样会存在非常大的安全隐患,而双亲委托的方式,就可以避免这种情况,因为String已经在启动时被加载,所以用户自定义类是无法加载一个自定义的类装载器。
6.JVM在判定两个class是否相同时,不仅要判断两个类名是否相同,而且要判断是否由同一个类加载器实例加载的。
JVM:
1.Java 运行时数据区可以分成 方法区、 堆、 栈、 程序计数器、 本地方法栈
2.堆:Java 对象, 线程之间共享的
3.栈:方法运行,每一个方法对应一个栈帧,每一个线程对应一个栈,每个栈帧包括 操作数、局部变量表、指向运行时常量池的引用,方法返回地址、附加位区 所以是线程不共享
4.方法区(静态区):被虚拟机加载的类信息、静态(static)变量,常量(final),即时编译器编译后的代码等数据。运行常量池是方法区的一部分,class文件除了有类的版本、字段、接口、方法等描述信息之外,还有一项信息常量池保存编译期生成的字面量和符号引用。 线程之间共享的
5.程序计数器:指出某一个时候执行某一个指令、执行完毕之后要返回的位置,当执行的Java方法的时候,这里保存的当前执行的地址,如果执行的是本地方法的时候,那么程序计数器为空。线程不共享。
request:
1.request.getAttribute()方法返回request范围内存在的对象,而request.getParameter()方法是获取http提交过来的数据;
2.getAttribute是返回对象,getParameter返回字符串。
Java并发:
1.CopyOnWriteArrayList适用于写少读多的并发场景;
2.ReadWriteLock即为读写锁,他要求写与写之间互斥,读与写之间互斥, 读与读之间可以并发执行。在读多写少的情况下可以提高效率;
3.ConcurrentHashMap是同步的HashMap,读写都加锁;
4.volatile只保证多线程操作的可见性,不保证原子性。
集合:
Servlet周期:
1.init()--> 初始化;
2.service() --> 处理请求;
3.destory () --> 销毁(停止)。
Java易错知识点:
1.静态内部类才可以声明静态方法;
2.静态方法不可以使用非静态变量;
3.抽象方法不可以有函数体。
int类型转化问题:
1.intValue()是把Integer对象类型变成int的基础数据类型;
2.parseInt()是把String 变成int的基础数据类型;
3.Valueof()是把String 转化成Integer对象类型;(现在JDK版本支持自动装箱拆箱了。)
JavaScript中typeof运算符结果可能为:
1.typeof Symbol() //"symbol"
2.typeof Number() //"number"
3.typeof String() //"string"
4.typeof Function() //"function"
5.typeof Object() //"object"
6.typeof Boolean() //"boolean"
7.typeof null //"object"
8.typeof undefined //"undefined"
死锁原因及产生必要条件:
原因:
(1) 因为系统资源不足;
(2) 进程运行推进的顺序不合适;
(3) 资源分配不当等。
必要条件:
(1) 互斥条件:一个资源每次只能被一个进程使用;
(2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放;
(3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺;
(4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
Socket编程:
1.客户端通过new Socket(IP地址,端口号)方法创建通信的Socket对象;
2.服务器端通过new ServerSocket(端口号)创建TCP连接对象 accept接纳客户端请求。
sleep和wait的区别:
1.这两个方法来自不同的类分别是Thread和Object;
2.最主要是sleep方法没有释放锁,而wait方法释放了锁,使得敏感词线程可以使用同步控制块或者方法;
3.wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用;
4.而sleep可以在 任何地方使用 synchronized(x){ x.notify() //或者wait() };
5.sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常。
HttpServlet容器响应Web客户请求流程:
1)Web客户向Servlet容器发出Http请求;
2)Servlet容器解析Web客户的Http请求;
3)Servlet容器创建一个HttpRequest对象,在这个对象中封装Http请求信息;
4)Servlet容器创建一个HttpResponse对象;
5)Servlet容器调用HttpServlet的service方法,这个方法中会根据request的Method来判断具体是执行doGet还是doPost,把HttpRequest和HttpResponse对象作为service方法的参数传给HttpServlet对象;
6)HttpServlet调用HttpRequest的有关方法,获取HTTP请求信息;
7)HttpServlet调用HttpResponse的有关方法,生成响应数据;
8)Servlet容器把HttpServlet的响应结果传给Web客户。
doGet() 或 doPost() 是创建HttpServlet时需要覆盖的方法。
运算优先级:
口诀:淡云一笔安洛三福 单目>算数运算符>移位>比较>按位>逻辑>三目>赋值
单目运算符:+,-,++,--,~(注~n=-n-1)
算数运算符:+,-,*,/,%
移位运算符:<<,>>
关系运算符:>,<,>=,<=,==,!=
位运算符:&,|,~,^,
逻辑运算符:&&,||
三目运算符:表达式1?表达式2:表达式3
赋值运算符:=等。
Java与C++的差别:
匿名内部类:
匿名内部类的创建格式为: new 父类构造器(参数列表)|实现接口(){
//匿名内部类的类体实现
}
- 使用匿名内部类时,必须继承一个类或实现一个接口;
- 匿名内部类由于没有名字,因此不能定义构造函数;
- 匿名内部类中不能含有静态成员变量和静态方法。