class A { public void method() { } } interface B { public abstract void method(); } class C extends A implementsB { //如果不重写method()方法,使用的是A中的method()方法 //如果重写method()方法将同时重写A和接口B中的method()方法 }
static
static 主要修改成员 ,随着类的存在而存在的,多个对象可以共享同一个
调用其他类中的属性和方法:
* ·静态属性或方法直接使用类名.属性 或者 类名.方法名();不需要实例化
* ·非静态属性或方法必须实例化一个对象,对象名.属性 或者 对象名.方法名()
final
final是最终修饰符,可以修饰类、成员方法、变量。
final修饰的类无法被继承。
final修饰的方法无法被重写,但可以被重载
final修饰的变量无法被再次赋值。
我们通常使用public static final来定义静态常量
包
不同包之间类的使用需要导包
同一个包下面的类之间互相使用不需要导包
类使用java.lang包下面的类不需要导包
修饰符作用域
publicprotected空的(default)private同一类中√√√√同一包中(子类与无关类)√√√不同包的子类√√不同包中的无关类√
匿名内部类
-匿名内部类是局部内部类的一种。
过程:
临时定义一个类型的子类
定义后即刻创建刚刚定义的这个类的对象
目的:
匿名内部类是创建某个类型子类对象的快捷方式。
我们为了临时定义一个类的子类,并创建这个子类的对象而使用匿名内部类。
异常
Throwable
Error(错误:一出现就是致命的)
服务器宕机,数据库崩溃等
Exception
RuntimeException(运行时异常,一般都是程序员犯的错误,需要修改源码的.)
编译时异常:在编译时必须进行处理,不处理无法通过编译.
一般情况下,遇到java自身提供的运行时异常,都可以通过逻辑解决,避免异常产生.
常见运行时异常:空指针异常,索引越界异常,类型转换异常
异常处理:
声明抛出处理 在方法上定义throws
捕获处理 在方法中写的,使用try{}catch(){}
catch中的异常不能是后面catch中的超类,比如下面的错误代码:
try{//可能会出现异常的代码
i =10/0;
FileReader fr = new FileReader(“a.txt”);
}catch(Exception e){//捕获异常,处理异常
//e.printStackTrace();
i = 10/1;
} catch (ArithmeticException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (FileNotFoundException e) {
// TODO: handle exception
}
异常注意事项
a:子类重写父类方法时,子类的方法必须抛出相同的异常或父类异常的子类。(父亲坏了,儿子不能比父亲更坏)
b:如果父类抛出了多个异常,子类重写父类时,只能抛出相同的异常或者是他的子集,子类不能抛出父类没有的异常
c:如果被重写的方法没有异常抛出,那么子类的方法绝对不可以抛出异常,如果子类方法内有异常发生,那么子类只能try,不能throws
解释 try catch finally throws
try 需要检测的异常;
catch 捕获异常,异常处理
finally 无论有没有异常,都执行
throws 写在方法上的,捕获方法中的异常,由调用者处理
throw 写在方法中,将方法中的异常抛出,由throws捕获或try catch捕获
final 和 finally
final 最终,修改的属性不可修改,方法不可重写 ,类不可继承
finally: 异常的一部分,表示无论有没有异常,都执行
装箱和拆箱
//装箱 :基本数据类型转包装类
int i =10;
Integer i2=20;
i2 = i;
//拆箱 :包装类转基本数据类型
i=i2;
ArrayList和LinkedList的异同
两个属于线性表。而ArrayList在底层是一个顺序表,采用数组的方式进行数据的存储,物理地址是连续的。LinkedList在底层是一个双向链表,物理存储结构是非连续的,数据元素的逻辑顺序是通过链表中的引用链接次序实现的
ArrayList继承了AbstractList抽象类,
AbstractSequentialList extends AbstractList
LinkedList继承了AbstractSequentialList抽象类,
ArrayList和LinkedList 实现了List,List继承了Connection,Connection继承 了Iterable接口;
List表示有先后顺序的, 所以两个都保证了数据的顺序读写。通过都可以存Null值、重复的数据
ArrayList底层是一个数组,在没有指定大小的情况下,数组默认的初始容量是10,当超过容量会触发1.5倍的扩容,旧的数组会被拷贝到新的数组中,新数组大小为原来的1.5倍。这样一定程度会造成空间的浪费。LinkedList底层是双向链表,大小是动态变化的,没有增容问题,插入一个开辟一个空间。可以看做是无限大。
数组实现的特点:查询快,增删慢
原因:
查询快:由于数组的索引支持,那么可以通过索引直接计算出元素的地址值,因此就可以直接通过元素的地址值获取到指定的元素
增删慢:由于在添加元素的时候,实际上底层会先创建一个新数组(新数组的长度为原数组的长度+1),那么在添加新元素的时候,先需要对数组中原有的数据进行拷贝,其次在末尾进行添加新的元素
因此,这样操作的效率的极低的(删除元素 刚好和添加的操作相反)
链表结构:查询慢,增删快
查询慢:由于不能直接找到元素的地址,需要上一个元素推导出下一个元素的地址,
这种查询速度较慢
增删快:在添加的时候,只需要更改元素所记录的地址值即可
使用场景
ArrayList:当操作是在一列数据的后面添加或者删除数据,而不是在前面或中间,并且需要随机地访问其中的元素时
LinkedList:当你的操作是在一列数据的前面或中间添加或删除数据,并且按照顺序访问其中的元素时
List和Set、Map区别?
List和Set、Map都是接口,不能直接实例化,需要通过实现类使用
List和Set父接口是Collection
Map父类是Object
Set :无序不重复(不包含重复元素相同元素,且无序)。
List :有序可重复
Map:双列集合是每个元素都有键与值两部分组成的集合,记录的是键值对对应关系。即通过键可以找到值。
如HashMap集合的键不得重复,值可以重复。
Collection和Collections
Collection 是一个接口,必须被实现才可使用
Collections是一个类
字节流和字符流?
字节流
抽象类:OutputStream InputStream
抽象类的实现类:FileOutputStream FileInputStream
字节缓冲流: BufferedOutputStream BufferedInputStream
字符流
抽象类:Writer Reader
抽象类的实现类:FileWriter FileReader
字符缓冲流: BufferedWriter BufferedReader
字符流只能操作字符,无法操作其他数据,如声音、视频等。
转换流:OutputStreamWriter InputStreamReader
序列化与反序列化
序列化:向流中写入对象
反序列化:从流中读对象
ObjectOutputStream序列化流
ObjectInputStream反序列化流
继承Thread类和实现Runnable接口
继承Thread类,线程对象和线程任务耦合在一起。一旦创建Thread类的子类对象,既是线程对象,有又有线程任务。
实现Runnable接口,将线程任务单独分离出来封装成对象,类型就是Runnable接口类型。
Runnable接口对线程对象和线程任务进行解耦。
A:第二种方式实现Runnable接口避免了单继承的局限性,所以较为常用。
B:实现Runnable接口的方式,更加的符合面向对象,线程分为两部分,一部分线程对象,一部分线程任务。
sleep wait notify notifyAll
sleep(s):暂停s毫秒
wait():等待,将正在执行的线程释放其执行资格和执行权,并存储到线程池中。
notify():唤醒,唤醒线程池中被wait()的线程,一次唤醒一个,而且是任意的。
notifyAll():唤醒全部,可以将线程池中的所有wait()线程都唤醒。
死锁产生的4个必要条件
1、互斥: 某种资源一次只允许一个进程访问,即该资源一旦分配给某个进程,其他进程就不能再访问,直到该进程访问结束。
2、占有且等待: 一个进程本身占有资源(一种或多种),同时还有资源未得到满足,正在等待其他进程释放该资源。
3、不可抢占: 别人已经占有了某项资源,你不能因为自己也需要该资源,就去把别人的资源抢过来。
4、循环等待: 存在一个进程链,使得每个进程都占有下一个进程所需的至少一种资源。
当以上四个条件均满足,必然会造成死锁,发生死锁的进程无法进行下去,它们所持有的资源也无法释放。这样会导致CPU的吞吐量下降。所以死锁情况是会浪费系统资源和影响计算机的使用性能的。那么,解决死锁问题就是相当有必要的了。
线程变化的几种状态
1、新建状态(New):新创建了一个线程对象。 Thread tPutIn = new Thread(putIn);
2、就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于“可运行线程池”中,变得可运行,只等待获取CPU的使用权。即在就绪状态的进程除CPU之外,其它的运行所需资源都已全部获得。 tPutIn.start();
3、运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。
4、阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。
5、终止状态
阻塞的情况分三种:
(1)、等待阻塞:运行的线程执行wait()方法,该线程会释放占用的所有资源,JVM会把该线程放入“等待池”中。进入这个状态后,是不能自动唤醒的,必须依靠其他线程调用notify()或notifyAll()方法才能被唤醒,
(2)、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入“锁池”中。
(3)、其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
反射
Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
数据库连接
mysql -uroot -p
mysql -uroot -p12345
删除表中所有记录使用DELETE from 表名; 还是用truncate table 表名;
删除方式:DELETE 一条一条删除,不清空auto_increment记录数。
truncate直接将表删除,重新建表,auto_increment将置为零,从新开始。
having与where的区别:
n having是在分组后对数据进行过滤.
where是在分组前对数据进行过滤
n having后面可以使用分组函数(统计函数)
where后面不可以使用分组函数。
左连接和右连接
左连接 (left join)
select * from table1 left join tbale2 on table1.id=table2.id
这条sql语句返回结果 table1表中的数据全部返回 table2表中的数据只返回满足where条件的
右连接 (right join)
select * from table1 right join table2 on table1.id=table2.id
这条sql语句返回结果 table2表中的数据全部返回 table1表中的数据只返回满足where条件的
内连接 (inner join)
select * from table1 inner join table2 on table1.id = table2.id
这条sql语句返回结果 显示满足条件的数据 并不以谁为主表
JDBC开发步骤?
注册驱动.
获得连接.
获得语句执行平台
执行sql语句
处理结果
释放资源.
PreparedStatement和Statement区别
联系
PreparedStatement和Statement都是用来执行SQL查询语句的API之一
PreparedStatement接口继承了Statement接口
区别
PreparedStatement和Statement的sql语句放置的位置不同
preparedStatement = connection.prepareStatement(sql);
resultSet = statement.executeQuery(sql);
Statement不对sql语句作处理,直接交给数据库;而PreparedStatement支持预编译,会将编译好的sql语句放在数据库端,相当于缓存。对于多次重复执行的sql语句,使用PreparedStatement可以使得代码的执行效率更高。
Statement的sql语句使用字符串拼接的方式,容易导致出错,且存在sql注入的风险;PreparedStatement使用“?”占位符提升代码的可读性和可维护性,并且这种绑定参数的方式,可以有效的防止sql注入。
DBCP、C3P0
Druid
阿里出品,淘宝和支付宝的专用数据库连接池,然而他不仅仅是一个数据库连接池,它还包括一个ProxyDriver,一系列内置的JDBC组件库,一个SQL Parser.支持所有的JDBC兼容的数据库(包括:Oracle,MySql,Derby,Postgresql,SQL Server,H2等等),而且Druid针对Oracle和MySql做了特别优化(比如Oracle的PS Cache内存占用优化,MySql的ping检测优化),Druid提供了MySql,Oracle,Postgresql,SQL-92的SQL的完整支持,这是一个手写高性能SQL Parser,支持Visitor模式,使得分析SQL的抽象语法树很方便,简单SQL语句用时10微秒以内,复杂SQL用时30微秒.通过Druid提供的Parser可以在JDBC层拦截SQL做相应处理(比如:分库分表,审计等).
c3p0与dbcp的区别(Druid的优点已经在上面做了详细叙述)
①dbcp没有自动回收空闲连接功能,c3p0有自动回收空闲连接功能
②两者对数据连接处理方式不同,c3p0提供最大空闲时间,dbcp提供最大连接数
③c3p0连接超过最大连接时间时,当前连接会断掉,dbcp当连接数数超过最大连接数时,所有连接都会被断开
④dbcp它的原理是维护多个连接对象Connection,在web项目要连接数据库时直接使用它维护对象进行连接,省去每次都要创建对象的麻烦,提高平效率和减少内存使用
⑤c3p0可以自动回收连接,dbcp需要自己手动释放资源返回,不过dbcp效率比较高
hibernate开发组推荐使用c3p0;
spring开发组推荐使用dbcp (dbcp连接池有weblogic连接池同样的问题,就是强行关闭连接或数据库重启后,无法reconnect ,告诉连接被重置,这个设置可以解决),apache的 dbcp数据源配置
ssm spring springmvc mybatis
sprintboot
Tomcat介绍:
bin:脚本目录
启动脚本:startup.bat
停止脚本:shutdown.bat
conf:配置文件目录 (config /configuration)
核心配置文件:server.xml
用户权限配置文件:tomcat-users.xml
所有web项目默认配置文件:web.xml
lib:依赖库,tomcat和web项目中需要使用的jar包
logs:日志文件.
temp:临时文件目录,文件夹内内容可以任意删除。
webapps:默认情况下发布WEB项目所存放的目录。
work:tomcat处理JSP的工作目录。
MVC 三层架构
M:model 模型 实体类 entity/domain
V:view 视图 JSP
C:controller 控制层 servlet
三层架构 :视图层 业务逻辑层 数据访问层
视图层:MVC
业务逻辑层: service
数据访问层:dao
jsp–>controller/servlet —>service —>dao -->service—controller–>jsp
response 和request?
post和get?
重定向和请求转发的区别点:
请求转发的url地址没有改变,重定向会改变url地址
请求转发没法访问外网资源,但是可以访问到内部的WEB-INF的资源;重定向可以访问外网资源,但是不能访问WEB-INF的资源
请求转发,客户端只发起了1次请求;重定向发起了2次请求
jsp内置/隐式对象(9个)----- 笔试
jsp和servlet的区别和联系:
1.jsp经编译后就变成了Servlet.
(JSP的本质就是Servlet,JVM只能识别java的类,不能识别JSP的代码,Web容器将JSP的代码编译成JVM能够识别的java类)
2.jsp更擅长表现于页面显示,servlet更擅长于逻辑控制.
3.Servlet中没有内置对象,Jsp中的内置对象都是必须通过HttpServletRequest对象,HttpServletResponse对象以及HttpServlet对象得到.
Jsp是Servlet的一种简化,使用Jsp只需要完成程序员需要输出到客户端的内容,Jsp中的Java脚本如何镶嵌到一个类中,由Jsp容器完成。
而Servlet则是个完整的Java类,这个类的Service方法用于生成对客户端的响应。
联系:
JSP是Servlet技术的扩展,本质上就是Servlet的简易方式。JSP编译后是“类servlet”。
Servlet和JSP最主要的不同点在于:
Servlet的应用逻辑是在Java文件中,并且完全从表示层中的HTML里分离开来。
而JSP的情况是Java和HTML可以组合成一个扩展名为.jsp的文件。
JSP侧重于视图,Servlet主要用于控制逻辑
Servlet更多的是类似于一个Controller,用来做控制。