基础篇
一、JAVA:
Java是面向对象的,跨平台的,它通过java虚拟机来进行跨平台操作,它可以进行自动垃圾回收的【c语言是通过人工进行垃圾回收】,java还会进行自动分配内存。【c语言是通过指定进行分配内存的】,只需要new一个对象,这个对象占用了多少空间,不需要我们来管,java虚拟机负责管这些,用完之后也不需要我们来释放,java虚拟机会自动释放
二、JDK JRE JVM的区别:
Jdk【Java Development ToolKit】就是java开发工具箱, JDK是整个JAVA的核心里边包含了jre,它除了包含jre之外还包含了一些javac的工具类,把java源文件编译成class文件,java文件是用来运行这个程序的,除此之外,里边还包含了java源生的API,java.lang.integer在rt的jar包里边【可以在项目中看到】,通过rt这个jar包来调用我们的这些io流写入写出等
JDK有以下三种版本:
J2SE,standard edition,标准版,是我们通常用的一个版本
J2EE,enterpsise edtion,企业版,使用这种JDK开发J2EE应用程序
J2ME,micro edtion,主要用于移动设备、嵌入式设备上的java应用程序
Jre【Java Runtime Enviromental】是java运行时环境,那么所谓的java运行时环境,就是为了保证java程序能够运行时,所必备的一基础环境,也就是它只是保证java程序运行的,不能用来开发,而jdk才是用来开发的,所有的Java程序都要在JRE下才能运行。
包括JVM和JAVA核心类库和支持文件。与JDK相比,它不包含开发工具——编译器、调试器和其它工具。
Jre里边包含jvm
Jvm:【Java Virtual Mechinal】因为jre是java运行时环境,java运行靠什么运行,而底层就是依赖于jvm,即java虚拟机,java虚拟机用来加载类文件,java中之所以有跨平台的作用,就是因为我们的jvm
关系:
J2se是基于jdk和jre,
JDK是整个JAVA的核心里边包含了jre,
Jre里边包含jvm
三、java的基本数据类型
数据类型 大小
byte(字节) 1(8位)
shot(短整型) 2(16位)
int(整型) 4(32位)
long(长整型) 8(64位)
float(浮点型) 4(32位)
double(双精度) 8(64位)
char(字符型) 2(16位)
boolean(布尔型) 1位
附加:
String是基本数据类型吗?(String不是基本数据类型)
String的长度是多少,有限制?(长度受内存大小的影响)
四、switch默认接受的几种数据类型
1.7 Short, int, byte, char
1.8 byte,short,int,char,枚举,字符串
五、修饰符的作用
修饰符的作用范围:
private default protected public
同一个类中 可以 可以 可以 可以
同一个包的类中 可以 可以 可以
不同包的子类中 可以 可以
不同包的类中 可以
六、Static修饰符
1、Static修饰的变量和方法都是类的,被称为静态成员,在类被加载到内存中时就开辟了空间;
2、static修饰的方法只能访问同类中的其他静态方法和静态变量,不能访问非静态成员;
3、static修饰的代码段被称为静态代码块,当类被加载时他只被执行一次。
七、final,finally,finalize 三者区别
Final是一个修饰符:
当final修饰局部变量的时候,只能被赋值一次;
当final修饰类变量时,必须在声明这个变量的时候赋值或者构造时赋值;
当final修饰方法时,该方法不能被重写;
当final修饰类时,该类不能被继承;
Finally:
Finally只能与try/catch语句结合使用,finally语句块中的语句一定会执行, 并且会在return,continue,break关键字之前执行
finalize:
Finalize是一个方法,属于java.lang.Object类,finalize()方法是GC (garbage collector垃圾回收)运行机制的一部分,finalize()方法是在 GC清理它所从 属的对象时被调用的
八、StringBuffer StringBuilder String 区别
1.StringBuilder执行效率高于StringBuffer高于String.
2.String是不可变的,所以对于每一次+=赋值都会创建一个新的对象,StringBuffer和StringBuilder都是可变的,当进行字符串拼接时采用append方法,在原来的基础上进行追加,地址不变,所以性能比String要高,又因为StringBuffer是线程安全的而StringBuilder是线程非安全的,所以StringBuilder的效率高于StringBuffer.
3.对于大数据量的字符串的拼接,采用StringBuffer,StringBuilder.
4.String与StringBuffer都是被final修饰的,不可被继承。
九、String的常用方法
Concat,equals,format,hasCode,indexOf,isEmpty,length,split,subString,valuesOf;
十、Java面向对象的特征
面向对象编程有三个特征:封装,继承,多态。
封装:1使用private关键字来实现封装;2讲类的属性私有化,提供公开的方法实现对属性的操作;3便于修改,增强代码的可维护性;
继承:1关键字是extend;2Java只能单继承;3子类继承了父类非私有的属性和方法;4构造方法不能继承;
多态:子类可以替代父类使用,接口可以替代实现类使用;
重载:1在同一个类中;2方法名相同;3参数类型或者数量不同;
重写:1发生在子类与父类之间;2方法名、返回值类型、参数类型都相同;3重写的修饰符权限要大于被重写的权限;
十一、抽象类与接口的区别
1.一个类只能进行单继承,但可以实现多个接口。
2.有抽象方法的类一定是抽象类,但是抽象类里面不一定有抽象方法;抽象类可以有构造方法,但不能被实例化,只能被继承;
接口里面所有的方法的默认修饰符为public abstract,接口里的成员变量默认的修饰符为 pulbic static final。
关系
接口和接口 继承
接口和抽象类 抽象类实现接口
类和抽象类 类继承抽象类
类和类 继承
十二、List,Set,Collection,Collections
1.List,Set,map都是接口,他们都继承于接口Collection,List是一个有序的可重复的集合,而Set的无序的不可重复的集合。Collection是集合的顶层接口,Collections是一个封装了众多关于集合操作的静态方法的工具类,因为构造方法是私有的,所以不能实例化。
2.List是以有序可重复数据存储的接口,实现类有ArrayList,LinkedList,Vector。ArrayList和Vector是基于数组实现的,所以查询的时候速度快,而在进行增加和删除的时候速度较慢LinkedList是基于链式存储结构,所以在进行查询的时候速度较慢但在进行增加和删除的时候速度较快。又因为Vector是线程安全的,所以他和ArrayList相比而言,查询效率要低。
3.set是以无序不可重复数据存储的接口,实现类有hasSet,treeSet。
4.Map是一个以键值对存储的接口。Map下有两个具体的实现,分别是HashMap和HashTable,HashMap是线程非安全的,HashTable是线程安全的,所以HashMap的效率高于HashTable,HashMap允许键空,而HashTable不允许键为空;map读取key值得方法是map.keySet,读取value值得方法map.values
十三、Io流
从流的方向
输入流 输出流
从流的类型上
字符流
Reader和Writer
字节流
inputstream和outputstream
两者的区别就是读写的时候一个是按字节读写,一个是按字符。在读写文件需要对内容按行处理,比如比较特定字符,处理某一行数据的时候一般会选择字符流。只是读写文件,和文件内容无关的,一般选择字节流。
十四、java Exception体系结构
java 异常是程序运行过程中出现的错误。Java把异常当作对象来处理,并定义一个基类java.lang.Throwable作为所有异常的超类。在Java API中定义了许多异常类,分为两大类,错误Error和异常Exception。其中异常类Exception又分为运行时异常(RuntimeException)和非运行时异常(非runtimeException),也称之为不检查异常(Unchecked Exception)和检查异常(Checked Exception)。
1、Error与Exception
Error是程序无法处理的错误,比如OutOfMemoryError、ThreadDeath等。
这些异常发生时,Java虚拟机(JVM)一般会选择线程终止。
Exception是程序本身可以处理的异常,这种异常分两大类运行时异常和非运行时异常。程序中应当尽可能去处理这些异常。
2、运行时异常和非运行时异常
运行时异常: 都是RuntimeException类及其子类异常: IndexOutOfBoundsException 索引越界异常
ArithmeticException:数学计算异常
NullPointerException:空指针异常
ArrayOutOfBoundsException:数组索引越界异常
ClassNotFoundException:类文件未找到异常
ClassCastException:类型转换异常
这些异常是不检查异常(Unchecked Exception),程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的。
非运行时异常:是RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如:
IOException、文件读写异常
FileNotFoundException:文件未找到异常
EOFException:读写文件尾异常
MalformedURLException:URL格式错误异常
SocketException:Socket异常
SQLException:SQL数据库异常
十五、线程和进程的区别
1.线程(Thread)与进程(Process):一个进程可以包括若干个线程;
2.实现线程的两种方式:继承Thread类,实现Runable接口;
3.线程的五种状态:创建状态,就绪状态,执行状态,阻塞状态,结束状态。
4.Synchronized关键字:确保共享对象在同一时刻只能被一个线程访问,这种处理机制称为“线程同步”或“线程互斥”。修饰的方法被称为同步方法,修饰部分代码被称为同步块,作用与同步方法相同,只是作用范围不同。
5.wait与sleep的区别:都可以使线程等待。在等待时wait会释放资源(锁),而sleep一直持有锁,不会释放资源。Wait通常被用于线程间交互,sleep通常被用于暂停执行。
十六、冒泡排序
for (int i = 0; i < sort.length - 1; i++) {
for (int j = 0; j < sort.length - i - 1; j++){
if (arr[j] < arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
十七、二分查找法
十八、时间类型转换
十九、阶乘
二十、单例
单例就是该类只能返回一个实例。
单例所具备的特点:
1.私有化的构造函数
2.私有的静态的全局变量
3.公有的静态的方法
单例分为懒汉式、饿汉式和双层锁式
饿汉式:
public class Singleton1 {
private Singleton1() {};
private static Singleton1 single = new Singleton1();
public static Singleton1 getInstance() {
return single;
}
}
懒汉式:
public class Singleton2 {
private Singleton2() {}
private static Singleton2 single=null;
public tatic Singleton2 getInstance() {
if (single == null) {
single = new Singleton2();
}
return single;
}
}
线程安全:
public class Singleton3 {
private Singleton3() {}
private static Singleton3 single ;
public static Singleton3 getInstance() {
if(null == single){
synchronized(single ){
if(null == single){
single = new Singleton3();
}
}
}
return single;
}
}
参考:
通过双重判断来保证单列设计模式在多线程中的安全性,
并且它在性能方面提高了很多。
synchronized在方法上加锁 (同步锁)
synchronized在代码块内部加锁 (同步代码块)
synchronized(同步锁)
使用synchronized如何解决线程安全的问题?
1.synchronized在方法上加锁
2.synchronized在代码块内部加锁
1.懒汉 2.饿汉 3.双重判断
二十一、jvm的内存结构
java虚拟机的内存结构分为堆(heap)和栈(stack),堆里面存放是对象实例也就是new出来的对象。栈里面存放的是基本数据类型以及引用数据类型的地址。
对于所谓的常量是存储在方法区的常量池里面。
数据库
一、where与having
WHERE用于行过滤。
SQL 中增加 HAVING 子句原因是,WHERE 关键字无法与聚合函数一起使用。
二、字符串与日期,数字之间相互转化
到字符串:to_char();到日期:to_date();到数字:To_number(char,'format');
三、in与exsits区别
In:跟在WHERE 子句后面规定多个筛选值(where 列名 in (值1,值2,值3));
(确定给定的值是否与子查询或列表中的值相匹配。in在查询的时候,首先查询子查询的表,然后将内表和外表做一个笛卡尔积,然后按照条件进行筛选)
Exsits:将外查询表的每一行,代入内查询作为检验,如果内查询返回的结果取非空值,则EXISTS子句返回TRUE,这一行行可作为外查询的结果行,否则不能作为结果。
(指定一个子查询,检测行的存在。遍历循环外表,然后看外表中的记录有没有和内表的数据一样的。匹配上就将结果放入结果集中。)
IN适合于外表大而内表小的情况;EXISTS适合于外表小而内表大的情况。
四、like模糊查询
通配符:%代替0到多个字符,_代替一个字符
五、nvl函数
Nvl(e1,e2):如果e1的值为null,返回e2,否则返回e1本身;
Nvl2(e1,e2,e3):如果e1的值为null,返回e3,否则返回e2;
六、排序oder by
升序asc,降序desc,默认为升序;多列排序:oder by 列名,列名
七、快速建表,复制数据
1复制表中的数据到新建的表中,表不存在
create table tableName1 as select * from tableName2
2复制表中的数据
insert into tableName select * from tableName
八、大数据量
九、提高查询效率
1优化SQL查询,去掉不必要的列;2建立查询条件索引;
十、UNION, UNION ALL
UNION 操作符用于合并两个或多个 SELECT 语句的结果集;UNION 内部的 SELECT 语句必须拥有相同数量的列,列也必须拥有相似的数据类型,每条 SELECT 语句中的列的顺序必须相同。
UNION 操作符选取不同的值,UNION ALL可以选取重复的数值;
十一、常用函数
Dual,伪表;
CASCADE,级联删除;
||,连接字符串;
SUBSTR (char, n, len),取子字符串,选取n位开始,长度为len的子串;
LENGTH(char),找出一个字符串的长度;
INSTR (char, substr),查找子串位置,
LPAD | RPAD (str,len,padstr),返回字符串str,左/右填充至len长度,长度大于len则缩减;
TRIM(),移除掉一个字串中的字头或字尾,最常见的用途是移除字首或字尾的空白;
REPLACE (char, str1, str2),字符串替换,将子串str1替换为str2;
LOWER(char),变为小写;
UPPER(char),变为大写
INITCAP(char),首字母变为大写;
Floor(),向下取整;
Ceil(),向上取整;
Round(),四舍五入;
十二、日期相关的函数
SYSDATE,返回当前日期;
ADD_MONTHS(date,n)函数可以得到date之前或之后n个月的新日期;
LAST_DAY(date),返回当前月的最后一天;
MONTHS_BETWEEN (date1, date2),用于计算date1和date2之间有几个月;
NEXT_DAY(date,week),返回下周某一天的日期;
TO_CHAR(date,'day'),返回日期date是周几;
返回两个日期之间的天数:
select floor(sysdate - to_date('20161018','yyyymmdd')) from dual;
十三、Case when与DECODE
Case函数一旦满足了某一个WHEN ,则这一条数据就会退出CASE WHEN,而不再考虑其他CASE;
decode(列名,值1,翻译值1,值2,翻译值2,...值n,翻译值n,缺省值);
十四、数据库三范式
1所有字段值都是不可分解的原子值;
2一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中;
3每一列数据都和主键直接相关,而不能间接相关;
十五、左连接、右连接、内连接
内连接:INNER JOIN返回两个表中联结字段相等的行;
左连接:LEFT JOIN返回包括左表中的所有记录和右表中联结字段相等的记录;
右连接:RIGHT JOIN返回包括右表中的所有记录和左表中联结字段相等的记录;
十六、having与聚合函数
GROUP BY 语句可结合一些聚合函数来使用,HAVING语句在GROUP BY语句后筛选数据。
SELECT column_name, aggregate_function(column_name)
FROM table_name
WHERE column_name operator value
GROUP BY column_name;
常用的聚合函数
AVG():返回数值列的平均值;
SELECT AVG(column_name) FROM table_name
COUNT():返回匹配指定条件的行数;
SELECT COUNT(column_name) FROM table_name;
FIRST()/LAST() :返回指定的列中第一个/最后一个记录的值;
SELECT FIRST/LAST (column_name) FROM table_name;
MAX()/MIN() :返回指定列的最大值/最小值;
SELECT MIN/MAX(column_name) FROM table_name;
SUM() :返回数值列的总数;
SELECT SUM(column_name) FROM table_name;
十七、视图
视图是基于 SQL 语句的结果集的可视化的表;视图中的字段就是来自一个或多个数据库中的真实的表中的字段。
CREATE VIEW view_name AS
SELECT column_name(s)
FROM table_name
WHERE condition
十八、存储过程
存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL语句集,存储在数据库中,经过第一次编译后再次调用不需要再次编译,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象。
--1、一组为了完成特定功能的SQL语句集
--2、第一次编译后再次调用不需要再次编译(高效)
--3、不同的数据库存储过程定义的方式不同,思路是相同的,语法不同
CREATE OR REPLACE Procedure myProcedure(Name Varchar2)
Is
--定义各种变量
ename2 Varchar2(32);
job2 Varchar2(32);
Begin
--写业务逻辑处理
Select ename,job Into ename2,job2 From emp Where ename = Name;
dbms_output.put_line(ename2);
End myProcedure;
十九、触发器
触发器对表进行插入、更新、删除的时候会自动执行的特殊存储过程。触发器可以分为两类:DML触发器和DDL触发器,DDL触发器它们会影响多种数据定义语言语句而激发,这些语句有create、alter、drop语句,DML触发器分为:after触发器(之后触发),insert触发器,update触发器,delete触发器。
二十、约束类型
NOT NULL(非空)、UNIQUE(唯一)、主键、外键、CHECK
二十一、序列
序列是一种数据库对象,用来自动产生一组唯一的序号;
CREATE SEQUENCE sequencename
[INCREMENT BY n] 定义序列增长步长,省略为1
[START WITH m] 序列起始值,省略为1,一经创建不能修改
[{MAXVALUE n | NOMAXVALUE}] 序列最大值,
[{MINVALUE n | NOMINVALUE}] 序列最小值
[{CYCLE | NOCYCLE}] 到达最大值或最小值后,继续产生序列(默认NOCYCLE)
[{CACHE n | NOCACHE}]; CACHE默认是20
二十一、理解rownum
rownum用于标记结果集中结果顺序的一个字段,它的特点是按顺序标记,而且是连续的,换句话说就是只有有rownum=1的记录,才可能有rownum=2的记录。rownum关键字只能和<或者<=直接关联,如果是>或者=则需要给他起个别名。
二十二、oracle分页
select * from (
select * from (
select s.*,rownum rn from student s
) where rn<=5)
where rn>0
二十三、Oracle数据库体系
1 .Oracle数据库的基本类型:char,varchar2,number,date,clob;
2 .Oracle的物理结构:数据文件,控制文件和日志文件;
3 .Oracle的逻辑结构:
表空间--最大的逻辑存储结构,与物理上的数据文件相对应;
段--数据库终端用户将处理的最小单位;
区--磁盘空间分配的最小单位;
块--管理存储空间的最基本单位;
必背的sql语句
1:oracle 分页
select * from (select t.*, rownum rn from (select * from menu order by id desc) t where rownum < 10) where rn >=5
2: mysql 分页
select * from music where id limit 5,5
3:oracle中如何快速将一张表的数据复制到另外一张表中(另外一张表不存在,另外一张 表存在,但数据为空)
.不存在另一张表时:
create table 新表 as select * from 将要复制的表
存在另一张表时:
insert into 新表名 select 字段 from 将要复制的表名
4:音乐专辑
查询出special
Select s.id , min(s.sname),count(m.mid) from special s inner
join ms m on s.id=m.id group by s.id
5:快速删除一张表(不可事物回滚,也就是没有日志记录)
TRUNCATE from 表名
6:inner join
select 查找信息 from 表名 1 inner join 表名2 on 表名1.列名 = 表名2.列名
7:left join
左外连接 select 查找信息 from 表名1 left join 表名2 on 表名1.列名 = 表名2.列名
8:right join
右外连接 select 查找信息 from 表名1 right join 表名2 on 表名1.列名 = 表名2.列名
9:oracle中查询遍历树形结构(start with)
select * from extmenu
start with pid=1
connect by prior id = pid
快速删除父节点以及父节点下的所有节点:
Delete from extmenu where id in (
elect * from extmenu
start with pid=1
connect by prior id = pid
)
10:查询出来60-70,80-90,95-100学生的信息
60 and 70 or between 80 and 90 or between 95 and 100
select * from stu where chengji > 60 and chengji < 70 or chengji > 80 and chengji < 90 or chengji > 95 and chengji < 100
11:用exists替换in------进行联表查询
select * from dept where exists(select * from emp where emp.deptno=dept.deptno);
或
select * from dept d inner join emp e on d.deptno = e.deptno(只查询出两表共同拥有的字段数据)
12:删除表中的重复数据:
delete from xin a where a.rowid != (
select max(b.rowid) from xin b
where a.name = b.name
);
13:row_number(),rank() over ,dense_rank() over 按工资排序
select sal,
row_number() over(order by sal desc) rank1,
rank() over(order by sal desc) rank,
dense_rank() over(order by sal desc) drank
from emp
14:select * from (select emp.* from(
dense_rank() over(partition by departNo order by sal desc)
rk from emp )
Where rk=4
Tomcat
一、 Tomcat的目录
bin------存放启动和关闭的tomcat脚本
conf-----包含不同的配置文件
work----存放jsp编译后产生的class文件
webapp存放应用程序的目录
temp----存放临时文件
log-----存放日志文件
lib------存放tomcat所需要的jar文件
doc-----存放各种Tomcat文档
二、默认端口及修改默认端口
1、Tomcat的默认端口:8080
2、修改默认端口是在conf/server.xml文件中
三、修改URL编码格式:
修改编码格式是在conf/server.xml文件中
四、修改配置虚拟目录:
在tomcat文件夹的 conf\catalina\localhost增加project .xml文件
文件内容:
contex指上下文,实际上就是一个web项目;
docBase是网页在硬盘上的实际存放位置的根目录,映射为path虚拟目录;
path是虚拟目录,用于浏览器防问的URL,访问的时候用localhost:8080/web/*.jsp访问网页;
debug的值表示是否调试;
reloadable="true"表示你修改了jsp文件后不需要重启就可以实现显示的同步;
crosscontext="true"表示配置的不同context共享一个session。
五、修改Tomcat内存大小:
进入tomcat/bin目录下,找到catalina.bat文件在文件首行中插入下面这段配置即可:
set JAVA_OPTS=-Xms1024m -Xmx4096m -XX:PermSize=128m -XX:MaxPermSize=256m
六、配置JNDI连接池
1、在tomcat服务器的lib目录下加入数据库连接的驱动jar包;
2、修改tomcat服务器的conf目录下server.xml配置文件;
name="jdbc/mysql"
auth="Container" |- auth:由容器进行授权及管理,指的用户名和密码是否可以在容器上生效
type="javax.sql.DataSource" |- type:此名称所代表的类型,现在为javax.sql.DataSource
maxActive="100"
maxIdle="30"
maxWait="10000"
username="root"
password="root"
driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://192.168.1.144:3306/leadtest?useUnicode=true&characterEncoding=utf-8"/>
七、Tomcat版本6/7/8
八、项目的部署方式
1、如果项目单独部署到tomcat中的时候,应该看tomcat中的server.xml;
2、如果和eclipse结合使用进行项目部署的时候,应该看eclipse里面的server.xml.
JDBC
一、常用操作类:
DriverManager
Connection
Statement
prepareStatement
ResultSet
二、JDBC连接数据库步骤(以MYSQL为例)
1、加载JDBC驱动程序:
通过Class类的forName方法实现,并将驱动地址放进去
成功加载后,会将Driver类的实例注册到DriverManager类中。
2、提供JDBC连接的URL 、创建数据库的连接
要连接数据库,需要向java.sql.DriverManager请求并获得Connection对象,
该对象就代表一个数据库的连接。
使用DriverManager的getConnection()方法传入指定的欲连接的数据库的路径、数 据库的用户名和密码。
Connection con=DriverManager.getConnection(url , username , password);
&&&:"jdbc:mysql://localhost/test?user=root&password=123&useUnicode=true&characterEncoding=utf-8”;
3、创建一个Statement
要执行SQL语句,必须获得java.sql.Statement实例
执行静态SQL语句。通常通过Statement实例实现。
执行动态SQL语句。通常通过PreparedStatement实例实现。
String sql = “”;
Statement st = con.createStatement() ;
PreparedStatement pst = con.prepareStatement(sql) ;
4、执行SQL语句
Statement接口提供了executeQuery、executeUpdate、execute三种方法
executeQuery:执行select语句,返回ResultSet结果集
ResultSet rst = pst.executeQuery();
executeUpdate:执行insert、update、delete语句
pst.executeUpdate();
5、关闭JDBC对象
操作完成以后要把所有使用的JDBC对象全都关闭,以释放JDBC资源。
三、数据源的理解
1 DataSource 对象所表示的物理数据源的连接。作为 DriverManager 工具的替代项,DataSource 对象是获取连接的首选方法。
2 DataSource接口由驱动程序供应商实现,共有三种类型的实现:
基本实现,生成标准的 Connection 对象;连接池实现,生成自动参与连接池的 Connection 对象。此实现与中间层连接池管理器一起使用;分布式事务实现,生成一个 Connection 对象,该对象可用于分布式事务,大多数情况下总是参与连接池。此实现与中间层事务管理器一起使用,大多数情况下总是与连接池管理器一起使用。
四、数据库连接池
1程序启动时建立足够的数据库连接,并将这些连接组成一个连接池,由程序动态地对池中的连接进行申请,使用,释放。
2数据库连接池的运行机制:1)程序初始化时创建连接池;2)使用时向连接池申请可用连接;3)使用完毕,将连接返还给连接池;4)程序退出时,断开所有连接,并释放资源。
3常用的连接池:DBCP:比较稳定;C3P0: 性能比较高;
五、Preparedstatement和statement的区别
1、Statemnet 发送完整的SQL 语句到数据库不是直接执行而是由数据库先编译,再运行。PreparedStatement继承于Statement 接口,除了具备Statement所有功能,还可以对SQL 语句进行预编译,也就是是先发送带参数的SQL 语句,再发送一组参数值。
2、PreparedStatement 较Statement 而言:
同构的SQL语句,PreparedStatement 的效率要比Statement 高;
对于程序员而言,代码比较容易维护;
有较好的安全性,如:可以在一定程度上防止SQL 注入(SQL Injection)。
同构:两个SQL 语句可编译部分是相同的,只有参数值不同。
异构:整个SQL 语句的格式是不同的。
六、ResultSet
ResultSet接口是查询结果集接口,它对返回的结果集进行处理。
使用Connection对象获得一个Statement,Statement中的executeQuery(String sql)方法可以使用select 语句查询,并且返回一个结果集ResultSet,通过遍历这个结果集,可以获得select语句的查寻结果,ResultSet的next()方法会操作一个游标从第一条记录的前面开始读取,直到最后一条记录。
七、JDBC调用存储过程
CallableStatement用于执行 SQL 存储过程的接口。通过Connection.prepareCall(java.lang.String) 创建一个 CallableStatement 对象来调用数据库存储过程。CallableStatement 对象提供了设置其 IN 和 OUT 参数的方法,以及用来执行调用存储过程的方法。使用返回的 CallableStatement 对象创建的结果集在默认情况下类型为 TYPE_FORWARD_ONLY,并带有 CONCUR_READ_ONLY 并发级别。
八、JDBC插入、查询时间类型的处理
1、Java中使用的时间类型为java.util.Date,数据库中的时间类型为java.sql.Date,,java.sql包下有三个与数据库相关的日期时间类型,分别是:
Date:表示日期,只有年月日,没有时分秒;
Time:表示时间,只有时分秒,没有年月日;
Timestamp:表示时间戳,有年月日时分秒,以及毫秒。
2、把数据库的三种时间类型赋给java.util.Date,不用转换,因为java.sql.Date是java.util.Date的子类;
3、java.util.Date转换成数据库的三种时间类型时,需要先通过getTime()方法将java.util.Date转化为long类型再转换为java.sql.Date;
java.sql.Date date=new java.sql.Date(new Date().getTime());
九、事务概述
在数据库中,所谓事务是指一组逻辑操作单元即一组sql语句。当这个单元中的一部分操作失败,整个事务回滚,只有全部正确才完成提交。
事务的ACID属性
1. 原子性(Atomicity)
原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
2. 一致性(Consistency)
事务必须使数据库从一个一致性状态变换到另外一个一致性状态。(数据不被破坏)
3. 隔离性(Isolation)
事务的隔离性是指一个事务的执行不能被其他事务干扰.
4. 持久性(Durability)
持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的.即使系统重启数据也不会丢失;
在JDBC中,事务默认是自动提交的,每次执行一个 SQL 语句时,如果执行成功,就会向数据库自动提交,而不能回滚,为了让多个 SQL 语句作为一个事务执行:
(1)执行语句前调用 Connection 对象的 setAutoCommit(false)以取消自动提交事务;
(2)在所有的 SQL 语句都成功执行后,调用 commit()方法提交事务;
(3)在出现异常时,调用 rollback()方法回滚事务。
十、jdbc分段批量提交的时候出现异常怎么处理?
通过Map来解决性能问题。首先在分段批量提交的时候,我们不采用事务,这样就保证了合法的数据就自动提交,不合法的数据就自己自动进行回滚,为了避免不合法数据影响后续合法数据的提交,采用定义业务规则字典表,实现对数据的验证,将不合法的数据记录下来,供用户进行后续处理,而合法的数据就全部提交。
十一、jdbc批量处理数据
批量处理数据:(代码优化:提高程序执行性能)
降低了java程序代码(客户端)和数据库之间的 网络通信的次数。
在jdbc中进行批量插入的核心API为 addBatch,executeBatch
大数据量的插入问题:(jdbc,hibernate,ibatis)
1.每次只插入一条和数据库交互多次(很耗时间)
2.批量插入和数据库只交互一次(内存溢出)
3.分段批量插入(推荐)
jdbc批量处理数据是通过PreparedStatement对象的 addbatch(), executebatch() clearbatch()进行和数据库的交互。通常我们使用分段批量处理的方式 这样可以提高程序的性能 ,防止内存溢出。
1.每个sql语句都和数据库交互一次(非批量操作)
2.只和数据库交互一次(批量操作)(内存溢出)
当数据达到一定额度的时候就和数据库进行交互,分多次进行(分段批量操作)
(500或者1000)
pst.addBatch();
if (i > 0 && i%1000 == 0) {
pst.executeBatch();
pst.clearBatch();
}
WEB基础及扩展
一、C/S概念、B/S概念
1、C/S(Client/Server)是客户端/服务器模式,客户端需要安装专用的客户端软件。
2、B/S(Brower/Server)又称为浏览器/服务器模式,使用浏览器通过Web Server同数据库进行数据交互。
二、协议以及默认的端口号
ftp 21 文件传输协议
Pop3 110
http 80 超文本传输协议
https 443
oracle 默认端口号1521
mysql默认端口号 3306
三、JavaScript的AJAX原理及实例
1、AJAX = 异步 JavaScript 和 XML。通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
2、原理:当发生一个事件,浏览器创建一个XMLHttpRequest对象并发送该对象到服务端,服务端对HttpRequest进行处理,然后创建一个response响应并发送数据返回到浏览器,浏览器使用JavaScript对返回的数据进行处理,最后更新局部页面。
3、实例
function loadXMLDoc()
{
var xmlhttp=new XMLHttpRequest();
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("...ID...").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","...文件地址...",true);
xmlhttp.send();
}
四、jQuery的Ajax方法和实例
1、jQuery的Ajax方法:
jQuery load(),$(selector).load(URL,data,callback);
jQuery get()/post(),$.get(URL,callback); $.post(URL,data,callback);
必需的 URL 参数规定您希望加载/请求的 URL。
可选的 data 参数规定与请求一同发送的查询字符串键/值对集合。
可选的 callback 参数是load()方法/请求完成后所执行的函数名称。
2、实例
jQuery load()
$(document).ready(function(){
$("button").click(function(){
$("#div1").load("/try/ajax/demo_test.txt",function(responseTxt,statusTxt,xhr){
if(statusTxt=="success")
alert("外部内容加载成功!");
if(statusTxt=="error")
alert("Error: "+xhr.status+": "+xhr.statusText);
});
});
});
jQuery get()/post()
$(document).ready(function(){
$("button").click(function(){
$.post("/try/ajax/demo_test_post.php",{
name:"菜鸟教程",
url:"http://www.runoob.com"
},
function(data,status){
alert("数据: \n" + data + "\n状态: " + status);
});
});
});
五、jQuery选择器
1、元素选择器:$("元素名")
2、#id选择器:$("#id名")
3、.class选择器:$(".class名")
六、JavaScript获取Id和Name
1、通过getElementById()获取元素对象;
2、通过getElementsByName()获取对象数组;
七、JSON解析
1>Java解析Json
1、JsonObject:JSONObject json = JSONObject.fromObject(jsonString);
2、JsonArray:JSONArray jsonArray = JSONArray.fromObject(json);
2>JavaScript解析Json
1、eval() 函数:var obj = eval ("(" + txt + ")"), eval()函数存在安全性问题几乎不用;
2、JSON 解析器:obj = JSON.parse(txt);不支持的浏览器可以安装JavaScript库来实现。
八、Java解析XML格式文件
Java解析XML文件的四种方式:DOM、SAX、JDOM、DOM4j。
1.dom4j
dom4j是一个Java的XML API,类似于jdom,用来读写XML文件的。dom4j是一个非常优秀的Java XML API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件。
2.sax
SAX(simple API for XML)是一种XML解析的替代方法。相比于DOM,SAX是一种速度更快,更有效的方法。它逐行扫描文档,一边扫描一边解析。而且相比于DOM,SAX可以在解析文档的任意时刻停止解析,但任何事物都有其相反的一面,对于SAX来说就是操作复杂。
dom4j 与 sax 之间的对比:【注:必须掌握!】
dom4j不适合大文件的解析,因为它是一下子将文件加载到内存中,所以有可能出现内存溢出,
sax是基于事件来对xml进行解析的,所以他可以解析大文件的xml
也正是因为如此,所以dom4j可以对xml进行灵活的增删改查和导航,而sax没有这么强的灵活性
所以sax经常是用来解析大型xml文件,而要对xml文件进行一些灵活(crud)操作就用dom4j
九、文件上传
十、http的状态
200 OK,成功;
301 Moved Permanently,资源(网页等)被永久转移到其它URL;
400 Bad Request,当前请求无法解析;
403
404 Not Found,无法找到页面;
408 Request Timeout,请求超时;
500 Internal Server Error,内部服务器错误;
503
十一、Web Services技术
Web services是建立可互操作的分布式应用程序的新平台。
1、基础的 Web Services 平台是 XML + HTTP。Web Services 拥有三种基本的元素:SOAP、WSDL 以及 UDDI。
2、Web Services开发可以分为服务器端开发和客户端开发;服务端开发,借助一些WebService框架,Java方面的axis,xfire,cxf等,J2EE的Jboss;客户端开发使用厂商的WSDL2Java之类的工具生成静态调用的代理类代码,使用厂商提供的客户端编程API类,使用SUN公司最新标准的jax-ws开发包。RESTful(理解)
十二、缓存(memcached、oscache、EhCache、map)
1、Memcached是一个自由开源的,高性能,分布式内存对象缓存系统。特点:协议简单;基于libevent的事件处理;内置内存存储方式;memcached不互相通信的分布式。支持的语言以Perl、PHP为主。
2、oscache曾经是广泛采用的高性能的J2EE缓存框架,提供了在现有JSP页面之内实现快速内存缓冲的功能。
3、EhCache是最流行的纯Java开源缓存框架,配置简单、结构清晰、功能强大。
4、map
十三、任务调度quartz
JSP相关
一、JSP的内置对象
输入、输出对象:request,response,out;
作用域通信对象:session,application,pageContext;
Servlet对象: page,config;
错误对象: exception;
四个作用域(信息共享的范围)从大到小:appliaction>session>request>page
application:全局作用范围,整个应用程序共享.生命周期为:应用程序启动到停止。
session:会话作用域,当用户首次访问时,产生一个新的会话,以后服务器就可以记住这个会话状态。
request:请求作用域,就是客户端的一次请求。
page:一个JSP页面。
二、request,response,session常用方法:
1、Request
getCookies();getMethod();getRequestURI(); getSession();getAttribute();setAttribute();getParameter();setCharacterEncoding();getRequestDispatcher();
2、Response
sendRedirect();
3、Session
getAttribute();getCreationTime();getId();getLastAccessedTime();wait();invalidate();removeAttribute();
三、get和post区别
1get是从服务器上获取数据,post是向服务器传送数据;
2get传送的数据量较小,post传送的数据量较大;
3get安全性较低,post安全性较高,但是执行效率不如get;
4在进行文件上传时只能使用post;
四、JSP的两种跳转方式
1JSP的跳转方式Forward(转发)和Redirect(重定向);
2从数据共享上Forward是一个请求的延续,可以共享request的数据,Redirect开启一个新的请求,不共享request的数据;
3从地址栏Forward地址栏不发生变化,Redirect地址栏发生变化;
五、session和cookie的区别
1.session是存储在服务器端,cookie是存储在客户端的,所以安全来讲session的安全性要比cookie高,然后我们获取session里的信息是通过存放在会话cookie里的sessionid获取的。
2由于session是存放在服务器的内存中,所以session里的东西不断增加会造成服务器的负担,所以会把很重要的信息存储在session中,而把一些次要东西存储在客户端的cookie里,然后cookie确切的说分为两大类分为会话cookie和持久化cookie。
3会话cookie是存放在客户端浏览器的内存中,他的生命周期和浏览器是一致的,浏览器关了会话cookie也就消失了,然而持久化cookie是存放在客户端硬盘中,而持久化cookie的生命周期就是我们在设置cookie时候设置的那个保存时间;sessio是在服务器关闭的时候,或者是sessio过期,再或者调用了invalidate()的或者是我们想要session中的某一条数据消失调用session.removeAttribute()方法,最后session是通过调用session.getsession来创建,这就是session与cookie的区别
六、Application及统计在线人数
application对象直接包装了servlet的ServletContext类的对象,是javax.servlet.ServletContext 类的实例。
这个对象在JSP页面的整个生命周期中都代表着这个JSP页面。这个对象在JSP页面初始化时被创建,随着jspDestroy()方法的调用而被移除。
protected void Application_Start(){
Application["OnLineUserCount"] = 0;
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
protected void Session_Start(object sender, EventArgs e){
Application.Lock();
Application["OnLineUserCount"] = Convert.ToInt32(Application["OnLineUserCount"]) + 1;
Application.UnLock();
}
protected void Session_End(object sender, EventArgs e){
Application.Lock();
Application["OnLineUserCount"] = Convert.ToInt32(Application["OnLineUserCount"]) - 1;
Application.UnLock();
}
七、servlet及 生命周期
1、Servlet是用Java编写的运行在服务器端的小程序,主要用来处理和转发请求的。
2、生命周期
1>Servlet 通过调用 init () 方法进行初始化。
2>Servlet 调用 service() 方法来处理客户端的请求。
3>Servlet 通过调用 destroy() 方法终止(结束)。
4>Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。
八、使用Servlet实现转发及重定向
转发:
request.getRequestDispatcher("…").forward(request, response);
重定向:
response.sendRedirect("…");
九、Servlet API的常用接口和类
接口:
Filter;RequestDispatcher;HttpServletRequest;HttpServletResponse;HttpSession;
类:
Cookie ;HttpServlet;HttpUtils;ServletInputStream;ServletOutputStream
十、jsp与servlet的关系——jsp编译运行原理;
当服务器上的一个JSP第一次请求执行时服务器上的JSP 引擎首先将JSP页面文件转译成一个JAVA文件再将这个JAVA文件编译生成字节码文件然后通过执行这个字节码文件响应客户。
十一、配置Servlet
<servlet>
<servlet-name>ServletDemoservlet-name> // servlet名字
<servlet-class>day_052102.ServletDemoservlet-class> // servlet实现类类名
<load-on-startup>1load-on-startup> // 取值表示servlet优先级
servlet>
<servlet-mapping>
<servlet-name>ServletDemoservlet-name> // 与servlet名字相同
<url-pattern>/ServletDemourl-pattern> // servlet的关联URL
servlet-mapping>
十二、Servlet接收Checkbox参数
前端
阅读
旅游
运动
Servlet
String[] values = request.getParameterValues("love") ;
十三、Servlet的继承关系
十四、Servlet过滤器
1、filter的概述:
filter是一个过滤器,用来在请求前和响应后进行数据的处理。
2、filter的生命周期是:
实例化--->初始化(init)-->进行过滤(doFilter)--->销毁(destroy)-->释放资源
3、一个Filter必须实现javax.servlet.Filter接口
在项目中我们通常通过filter进行编码转换,进行安全验证,进行重复提交的判断。
4、配置过滤器
十五、Servlet监听器
1、监听器的概述:
Listener用于监听 java web程序中的事件,当创建、修改、删除Session、request、context等时,会自动触发该事件对应的Listeer。
2、监听器的分类:
1>监听 Session、request、context 的创建于销毁,分别为
HttpSessionLister、ServletContextListener、ServletRequestListener
2>监听对象属性变化,分别为:
HttpSessionAttributeLister、ServletContextAttributeListener、ServletRequestAttributeListener
3>监听Session 内的对象,分别为:
HttpSessionBindingListener 和 HttpSessionActivationListener。
3、监听器的配置:
web.xml中
十六、常用的JSTL标签
1、核心标签
2、格式化标签
3、SQL标签
4、XML标签
5、JSTL函数
fn:contains(),
十七、JSP的指令
1、Jsp包含三个编译指令和七个动作指令。
2、三个编译指令为:page、include、taglib。
3、七个动作指令为:jsp:forward、jsp:param、jsp:include、jsp:plugin、jsp:useBean、jsp:setProperty、jsp:getProperty
十八、request.getSession()、reqeust.getSession(false)和 request.getSession(true)
getSession()/getSession(true):当session存在时返回该session,否则新建一个 session并返回该对象
getSession(false):当session存在时返回该session,否则返回null
Page和PageContext的区别
Page是servlet对象;使用this关键字,它的作用范围是在同一页面。
PageContext是作用域通信对象;通常使用setAttribute()和getAttribute()来设置和获取存放对象的值。
十九、onready和onload的区别
1.onready比onload先执行
2.onready是在页面解析完成之后执行,而onload是在页面所有元素加载后执行
3.onload只执行最后一个而onready可以执行多个。
二十、项目的生命周期
1.需求分析
2.概要设计
3.详细设计(用例图,流程图,类图)
4.数据库设计(powerdesigner)
5.代码开发(编写)
6.单元测试(junit 白盒测试)(开发人员)
svn版本管理工具(提交,更新代码,文档)
7.集成测试 (黑盒测试,loadrunner(编写测试脚本)(高级测试))
8.上线试运行 (用户自己体验)
9.压力测试(loadrunner)
10.正式上线
11.维护
二十一、经常访问的技术网站
1.csdn(详细步骤的描述)
2.iteye(详细步骤的描述)
3.oschina(开源中国获取java开源方面的信息技术)
4.java开源大全 www.open-open.com(获取java开源方面的信息技术)
5.infoq(对java,php,.net等这些语言的一些最新消息的报道)
二十二、osi七层模型
第一层:物理层
第二层:数据链路层
第三层:网络层
第四层:传输层
第五层:会话层
第六层:表示层
第七层:应用层
二十三、找到解决svn冲突方法
对于svn冲突,可以采用手工处理将冲突的部分进行整合,
之后备份最新整合后的文件,采用覆盖更新的方式处理完
冲突之后,再把最新整合后的文件进行提交。
二十四、反射的描述
通过字符串可以动态创建java对象,并且可以动态访问方法,属性等。
我们在项目中的时候封装过数据库jdbc的持久层,其中就利用反射这项技术来达到通用和灵活的目的。
二十五、防止表单重复提交
针对于重复提交的整体解决方案:
1.用redirect来解决重复提交的问题
2.点击一次之后,按钮失效
3.通过loading
4.自定义重复提交过滤器
5.解决struts2重复提交
可以结合s:token标签来解决重复提交问题
利用token的原理:
1.在前端的jsp页面中加入s:token标签,在访问该页面时就会生成隐藏域,该隐藏域中包含一个随机生成的字符串,并把该字符串存入session中
2.在struts2的配置文件中加入token拦截器后,当正常访问action的时候,会从session中取出该字符串,然后和页面隐藏域中提交字符串做对比,如果一致则正常执行并删除session中存储的字符串。
二十六、Spring融入框架
我们通过在web.xml中配置ContextLoaderListener这个监听器也加载spring的配置文件,从而融入到项目框架中。
框架--Spring
一、Spring概述
1、什么是Spring
Spring是一个开源的Java EE开发框架。Spring框架的核心功能可以应用在任何Java应用程序中,但对Java EE平台上的Web应用程序有更好的扩展性。Spring框架的目标是使得Java EE应用程序的开发更加简捷,通过使用POJO为基础的编程模型促进良好的编程风格。
2、Spring的特征
轻量级:Spring在大小和透明性方面绝对属于轻量级的,基础版本的Spring框架大约只有2MB。
控制反转(IOC):Spring使用控制反转技术实现了松耦合。依赖被注入到对象,而不是创建或寻找依赖对象。
面向切面编程(AOP): Spring支持面向切面编程,同时把应用的业务逻辑与系统的服务分离开来。
容器:Spring包含并管理应用程序对象的配置及生命周期。
MVC框架:Spring的web框架是一个设计优良的web MVC框架,很好的取代了一些web框架。
事务管理:Spring对下至本地业务上至全局业务(JAT)提供了统一的事务管理接口。
异常处理:Spring提供一个方便的API将特定技术的异常(由JDBC, Hibernate, 或JDO抛出)转化为一致的、Unchecked异常。
3、Spring框架的模块
核心容器,Spring上下文,Spring AOP,Spring Dao,Spring ORM,Spring Web,Spring MVC;
4、Spring Core与Spring 上下文
核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFacotory是IoC容器的核心接口,负责实例化,定位,配置应用程序中的对象及建立这些对象间的依赖。
Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。
5、BeanFactory – BeanFactory 实例
BeanFactory是工厂模式的一种实现,它使用控制反转将应用的配置和依赖与实际的应用代码分离开来。
6、XmlBeanFactory
XmlBeanFacotory实现BeanFactory接口,它根据XML文件中定义的内容加载beans,组成应用对象及对象间的依赖关系。
7、AOP模块
通过配置管理特性,Spring AOP 模块直接将面向切面的编程功能集成到了 Spring 框架中。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。
8、Dao模块
Spring提供了还异常层次结构,可用来管理异常处理和不同数据库供应商抛出的错误消息;降低了需要编写的异常代码数量。
9、ORM模块
Spring框架插入了若干个ORM框架,从而提供了ORM的对象关系工具,其中包括Hibernate和MyBatis。
10、Web模块
Web上下文模块建立在应用程序上下文模块之上,为基于Web的应用程序提供了上下文。
11、MVC模块
Spring Web MVC是一种基于Java的实现了Web MVC设计模式的轻量级Web框架,也就是使用了MVC架构模式的思想,通过控制反转将控制逻辑和业务对象完全分离开来。
12、Spring的配置文件
Spring的配置文件是一个XML文件,文件包含了类信息并描述了这些类是如何配置和互相调用的。
13、IOC容器
就是一个大的抽象工厂,通过依赖注入的方式,负责创建和管理对象以及之间的关系(对象之间的依赖)。
14、IOC的特点
减少了应用程序的代码量;实现了松耦合;
15、Spring中的依赖注入(DI)与控制反转(IOC)
依赖注入和控制反转是对同一件事情的不同描述,依赖注入是从应用程序的角度在描述,可以把依赖注入描述完整点:应用程序依赖容器创建并注入它所需要的外部资源;而控制反转是从容器的角度在描述,描述完整点:容器控制应用程序,由容器反向的向应用程序注入应用程序所需要的外部资源。
16、有哪些不同类型的IOC(依赖注入),如何选择?
1)接口注入;setter方法注入;构造方法注入;
2)使用构造器参数实现强制依赖注入,使用setter方法实现可选的依赖关系。
17、应用上下文是如何实现
1)ClassPathXmlApplicationContext:从classpath处获取xml文件来加载一个上下文。
2)FileSystemXmlApplicationContext:从文件系统中获取xml文件来加载一个上下文。
3)XmlWebApplicationContext:从web应用获取xml文件来加载一个上下文。
18、Bean Factory和ApplicationContext有什么区别?
ApplicationContext继承自BeanFactory接口,除了包含BeanFactory的所有功能之外,在国际化支持、资源访问(如URL和文件)、事件传播等方面进行了良好的支持。
19、什么是Spring Beans?
Spring Beans是构成Spring应用核心的Java对象。这些对象由Spring IOC容器实例化、组装、管理。spring框架中所有的bean都默认为单例bean。
20、Spring Bean中定义了什么内容?
定义了所有的配置元数据,这些配置信息告知容器如何创建它,它的生命周期是什么以及它的依赖关系。
21、向Spring 容器提供配置元数据的三种方法
XML配置文件;基于注解配置;基于Java的配置
22、如何定义bean的作用域
只需要在bean定义的时候通过'scope'属性定义即可。singleton返回一个实例,prototype每次产生一个新实例。
23、Spring中支持的bean作用域
•singleton:在Spring IOC容器中仅存在一个Bean实例,Bean以单实例的方式存在。默认
•prototype:一个bean可以定义多个实例。
•request:每次HTTP请求都会创建一个新的Bean。该作用域仅适用于WebApplicationContext环境。
•session:一个HTTP Session定义一个Bean。该作用域仅适用于WebApplicationContext环境.
•globalSession:同一个全局HTTP Session定义一个Bean。该作用域同样仅适用于WebApplicationContext环境.
24、Spring框架中单例beans是线程安全的吗?
不是
25、Spring框架中bean的生命周期
•Spring容器读取XML文件中bean的定义并实例化bean。
•Spring根据bean的定义设置属性值。
•如果该Bean实现了BeanNameAware接口,Spring将bean的id传递给setBeanName()方法。
•如果该Bean实现了BeanFactoryAware接口,Spring将beanfactory传递给setBeanFactory()方法。
•如果任何bean BeanPostProcessors 和该bean相关,Spring调用postProcessBeforeInitialization()方法。
•如果该Bean实现了InitializingBean接口,调用Bean中的afterPropertiesSet方法。如果bean有初始化函数声明,调用相应的初始化方法。
•如果任何bean BeanPostProcessors 和该bean相关,调用postProcessAfterInitialization()方法。
•如果该bean实现了DisposableBean,调用destroy()方法。
26、哪些是最重要的bean生命周期方法?能重写它们吗?
有两个重要的bean生命周期方法。第一个是setup方法,该方法在容器加载bean的时候被调用。第二个是teardown方法,该方法在bean从容器中移除的时候调用。
bean标签有两个重要的属性(init-method 和 destroy-method),你可以通过这两个属性定义自己的初始化方法和析构方法。Spring也有相应的注解:@PostConstruct 和 @PreDestroy。
27、什么是Spring的内部bean?
当一个bean被用作另一个bean的属性时,这个bean可以被声明为内部bean。在基于XML的配置元数据中,可以通过把元素定义在 或元素内部实现定义内部bean。内部bean总是匿名的并且它们的scope总是prototype。
28、如何在Spring中注入Java集合类?
•list元素用来注入一系列的值,允许有相同的值。
•set元素用来注入一些列的值,不允许有相同的值。
•map用来注入一组”键-值”对,键、值可以是任何类型的。
•props也可以用来注入一组”键-值”对,这里的键、值都字符串类型。
29、什么是bean wiring?
bean Wiring也叫自动装配,就是将一个Bean注入到其他Bean的Property中结合在一起的情况。
30、自动装配的五种模式
no——默认情况下,不自动装配,通过“ref”attribute手动设定。
buName——根据Property的Name自动装配,如果一个bean的name,和另一个bean中的Property的name相同,则自动装配这个bean到Property中。
byType——根据Property的数据类型(Type)自动装配,如果一个bean的数据类型,兼容另一个bean中Property的数据类型,则自动装配。
constructor——根据构造函数参数的数据类型,进行byType模式的自动装配。
autodetect——如果发现默认的构造函数,用constructor模式,否则,用byType模式。
31、自动装配的局限性
•重写:你仍然需要使用 和< property>设置指明依赖,这意味着总要重写自动装配。
•原生数据类型:你不能自动装配简单的属性,如原生类型、字符串和类。
•模糊特性:自动装配总是没有自定义装配精确,因此,如果可能尽量使用自定义装配。
32、你可以在Spring中注入null或空字符串吗?
可以
二、Spring注解
1、什么是Spring基于Java的配置?
基于Java的配置允许你使用Java的注解进行Spring的大部分配置而非通过传统的XML文件配置。
2、什么是基于注解的容器配置?
直接在类中进行配置,通过注解标记相关的类、方法或字段声明。
3、如何开启注解装配?
注解装配默认情况下在Spring容器中是不开启的;
开启基于注解的装配需在Spring配置文件中配置 <context:annotation-config/>
4、@Required 注解
表明bean的属性必须在配置时设置,可以在bean的定义中明确指定也可通过自动装配设置。如果bean的属性未设置,则抛出BeanInitializationException异常。
5、@Autowired 注解
通过匹配数据类型自动装配Bean,提供更加精细的控制,包括自动装配在何处完成以及如何完成。
6、@Qualifier 注解
当有多个相同类型的bean而只有其中的一个需要自动装配时,将@Qualifier 注解和@Autowire 注解结合使用消除这种混淆,指明需要装配的bean。
三、Spring数据访问
1、在Spring框架中如何更有效的使用JDBC?
Spring框架中可以使用JdbcTemplate能更有效的使用JDBC,通过statements和queries语句从数据库中存取数据。
2、JdbcTemplate
JdbcTemplate是Spring框架自带的对JDBC操作的封装,目的是提供统一的模板方法使对数据库的操作更加方便、友好,效率也不错。在实际应用中还需要和hibernate、mybaties等框架混合使用。
3、Spring对DAO的支持
Spring对数据访问对象(DAO)的支持旨在使它可以与数据访问技术方便的结合起来工作,并且提供了一套抽象DAO类进行扩展,这可以很轻松在的不同的持久层技术间切换,编码时也无需担心会抛出特定技术的异常。
4、使用Spring可以通过什么方式访问Hibernate?
1)使用Hibernate Template的反转控制以及回调方法
2)继承HibernateDAOSupport,并申请一个AOP拦截器节点
5、Spring支持的ORM
Hibernate,Mybatis,SQL server
6、如何通过HibernateDaoSupport将Spring和Hibernate结合起来?
使用Spring的SessionFactory 调用LocalSessionFactory。具体步骤:
1)配置Hibernate SessionFactory;
2)继承HibernateDaoSupport实现一个DAO;
3)使用AOP装载事务支持。
7、Spring支持的事务管理类型
1)编程式事务管理:这意味着你可以通过编程的方式管理事务,这种方式带来了很大的灵活性,但很难维护;
2)声明式事务管理:这种方式意味着你可以将事务管理和业务代码分离。你只需要通过注解或者XML配置管理事务。
8、Spring框架的事务管理有哪些优点?
•它为不同的事务API(如JTA, JDBC, Hibernate, JPA, 和JDO)提供了统一的编程模型。
•它为编程式事务管理提供了一个简单的API而非一系列复杂的事务API(如JTA).
•它支持声明式事务管理。
•它可以和Spring 的多种数据访问技术很好的融合。
9、你更推荐那种类型的事务管理?
许多Spring框架的用户选择声明式事务管理,因为这种方式和应用程序的关联较少,因此更加符合轻量级容器的概念。声明式事务管理要优于编程式事务管理,尽管在灵活性方面它弱于编程式事务管理(这种方式允许你通过代码控制业务)。
四、Spring 面向切面编程
1、AOP
面向切面编程,采用动态代理的方式,
允许程序员模块化横向业务逻辑,或定义核心部分的功能,例如日志管理和事务管理。
2、切面(Aspect)
AOP的核心就是切面,它将多个类的通用行为封装为可重用的模块。该模块含有一组API提供 cross-cutting功能。例如,日志模块称为日志的AOP切面。根据需求的不同,一个应用程序可以有若干切面。在Spring AOP中,切面通过带有@Aspect注解的类实现。
3、在Spring AOP中concern和 cross-cutting concern的区别是什么?
Concern(核心逻辑):表示在应用程序中一个模块的行为。Concern可以定义为我们想要实现的功能。
Cross-cutting concern(横向的通用逻辑):指的是整个应用程序都会用到的功能,它影响整个应用程序。例如,日志管理(Logging)、安全管理(Security)以及数据交互是应用程序的每个模块都要涉及到的,因此这些都属于Cross-cutting concern。
4、连接点(Join point)
连接点代表应用程序中插入AOP切面的地点。它实际上是Spring AOP框架在应用程序中执行动作的地点。
5、通知(Advice)
通知表示在方法执行前后需要执行的动作。实际上它是Spring AOP框架在程序执行过程中触发的一些代码。Spring切面可以执行一下五种类型的通知:
1)before(前置通知):在一个方法之前执行的通知。
2)after(最终通知):当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)。
3)after-returning(后置通知):在某连接点正常完成后执行的通知。
4)after-throwing(异常通知):在方法抛出异常退出时执行的通知。
5)around(环绕通知):在方法调用前后触发的通知。
6、切入点(Pointcut)
切入点是一个或一组连接点,通知将在这些位置执行。可以通过表达式或匹配的方式指明切入点。
7、什么是引入?
引入允许我们在已有的类上添加新的方法或属性。
8、什么是目标对象?
被一个或者多个切面所通知的对象。它通常是一个代理对象。也被称做被通知(advised)对象。
9、什么是代理?
代理是将通知应用到目标对象后创建的对象。从客户端的角度看,代理对象和目标对象是一样的。
10、有几种不同类型的自动代理?
•BeanNameAutoProxyCreator:bean名称自动代理创建器
•DefaultAdvisorAutoProxyCreator:默认通知者自动代理创建器
•Metadata autoproxying:元数据自动代理
11、什么是织入?什么是织入应用的不同点?
织入是将切面和其他应用类型或对象连接起来创建一个通知对象的过程。织入可以在编译、加载或运行时完成。
12、解释基于XML Schema方式的切面实现
在这种情况下,切面由使用XML文件配置的类实现。
13、解释基于注解方式(基于@AspectJ)的切面实现
在这种情况下(基于@AspectJ的实现),指的是切面的对应的类使用Java 5注解的声明方式。
五、Spring的MVC框架
1、什么是Spring的MVC框架?
Spring Web MVC是一种基于Java的实现了Web MVC设计模式的轻量级Web框架,也就是使用了MVC架构模式的思想,通过控制反转将控制逻辑和业务对象完全分离开来。
2、Spring MVC运行原理
整个处理过程从一个HTTP请求开始:
1)客户端发出一个http请求给web服务器,web服务器对请求进行解析,如果匹配DispatcherServlet的请求映射路径,web容器将请求转交给DispatcherServlet;
2)DispatcherServlet接收到客户端请求,根据URL映射规则及HandlerMapping的配置,找到对应的处理器(Handler),再由DispatcherServlet将处理权交给HandlerAdapter对Handler进行具体调用;
3) 处理该请求后,会返回一个ModelAndView;
4)DispatcherServlet根据得到的ModelAndView中的视图对象,找到一个合适的ViewResolver(视图解析器),DispatcherServlet根据视图解析器的配置将要显示的数据传给对应的视图,最后显示给用户。
3 、DispatcherServlet
Spring的MVC框架围绕DispatcherServlet来设计的,它用来处理所有的HTTP请求和响应。
4、WebApplicationContext
WebApplicationContext继承了ApplicationContext,并添加了一些web应用程序需要的功能。和普通的ApplicationContext 不同,WebApplicationContext可以用来处理主题样式,它也知道如何找到相应的servlet。
5、什么是Spring MVC框架的控制器?
控制器提供对应用程序行为的访问,通常通过服务接口实现。控制器解析用户的输入,并将其转换为一个由视图呈现给用户的模型。Spring 通过一种极其抽象的方式实现控制器,它允许用户创建多种类型的控制器。
6、@Controller annotation
@Controller注解表示该类扮演控制器的角色。Spring不需要继承任何控制器基类或应用Servlet API。
7、@RequestMapping annotation
@RequestMapping注解用于将URL映射到任何一个类或者一个特定的处理方法上。
8、Spring MVC整合
1)首先,要在web.xml里面配置SpringMVC的核心控制器,DispatcherServlet,对指定的后缀请求进行拦截。
2)Controller层要加 @Controller注解,表明该类是MVC的控制层。
3)创建Service接口,给接口加上注解 @Component或者 @Service 表明这是Service业务处理层
4)在Controller层声明Service变量(属性),给变量(属性) 加上 @Autowired注解,通过自动绑定机制将Service注入到Controller。 (注:@Autowired默认是ByType,如果想根据属性名注入,那么就再加上注解 @Resource(name="属性名"))
5)在Controller层的方法上加上注解 @RequestMapping("requestAddress") 表明该方法的请求地址
6)Dao层要加上注解 @Repository 表明这是数据库持久层
7)同样将dao实例注入到service层中。
8)配置视图解析器 "InternalResourceViewResolver",对处理后的跳转进行统一配置。
框架-- Hibernate
一、Hibernate 中get 和 load的区别
1、加载方式:
load为延迟加载(返回的是一个只有id属性的代理,只有使用该对象属性时,才发出sql语句);
get为立即加载(执行时,会立即向数据库发出sql语句)
2、返回结果:
load检索不到记录时,会抛ObjectNotFoundException异常
get检索不到记录时,会返回null
二、Hibernate、Ibatis、Jdbc三者的区别
Hibernate属于全自动,Mybatis属于半自动,Jdbc属于手动,从开发效率上讲hibernate较高,Mybatis居中,jdbc较低,从执行效率上讲hibernate较低,Mybatis居中,jdbc较高,因为jdbc是手工写sql语句,程序员对sql的控制能力更大,可以根据业务需要进行优化,而Mybatis虽然也可以对sql进行优化,但是他里面将resultset封装为实体的过程中采用了反射机制所以一定程度上影响了性能,而hibernate因为高度封装所以开发效率相对较高,但正因为这个原因,所以程序员在对sql语句的控制和优化方面相对比较弱,而且在将resultset封装成实体的过程中也采用了反射机制,所以在性能方面较低。
三、Hibernate的运行原理
首先通过configuration去加载hibernate.cfg.xml这个配置文件,根据配置文件的信息去创建sessionFactory,sessionFactory是线程安全的,是一个session工厂,用来创建session,session是线程不安全的,相当于jdbc的connection,最后通过session去进行数据库的各种操作,在进行操作的时候通过transaction进行事务的控制。
四、Hibernate五大核心(类/接口)简述
1 .Configuration接口的作用是对Hibernate进行配置,以及对它进行启动。(加载hibernate.cfg.xml)并创建一个SessionFactory对象。
2 .SessionFactory接口
SessionFactory接口负责初始化Hibernate。它充当数据存储源的代理,并负责创建Session对象。SessionFactory是线程安全的。
3 .Session接口
Session(会话)接口是Hibernate应用使用的主要接口。Session接口负责执行被持久化对象的CRUD操作(增删改查)。Session对象是非线程安全的。Session 相当于jdbc的connection
4 .Query与Criteria接口
总之Query和Criteria接口负责执行各种数据库查询。
5 .Transaction接口
Transaction(事务)负责操作相关的事务。
五、Hibernate与JDBC的区别
1.hibernate和jdbc主要区别就是,hibernate先检索缓存中的映射对象( 即hibernate操作的是对象),而jdbc则是直接操作数据库.
2.Hibernate是JDBC的轻量级的对象封装,它是一个独立的对象持久层框架。Hibernate可以用在任何JDBC可以使用的场合
3.Hibernate是一个和JDBC密切关联的框架,所以Hibernate的兼容性和JDBC驱动,和数据库都有一定的关系,但是和使用它的Java程序,和App Server没有任何关系,也不存在兼容性问题。
4、如果正确的使用JDBC技术,它的执行效率一定比hibernate要好,因为hibernate是基于jdbc的技术.
5、JDBC使用的是SQL语句,Hibernate使用的是HQL语句,但是HQL语句最终还会隐式转换成SQL语句执行。
六、Hibernate中的两大配置文件
*.hbm.xml:主键生成策略,映射关系,一对多,一对一的关系。
Hibernate.cfg.xml:方言(用哪个数据库),数据库连接信息,包含*.hbm.xml内容,映射 文件,也可以配事务。
七、Hibernate事务处理
开启事务 session.beginTransaction();
执行相关的操作,如果成功则session.getTransaction().commit();
执行操作失败则 session.getTransaction.rollback();
八、Hibernate的三种状态以及状态的转换
Transient(临时)
new 一个初始化对象后,并没有在数据库里保存数据,处于临时状态;
Persistent(持久化)
当执行save()方法,调用session.close()方法之前,内存中的对象与数据库有 对应关系处于持久化状态;
Detached(托管/游离)
当执行session.close()之后,处于托管状态;
状态的转换
处于托管状态下,调用update()方法后,转换为持久化状态;
在持久化状态下,执行delete()方法后,转换为临时状态;
在未初始化对象之前,调用get(),load(),find(),iterate()之后,直接进入持久化状态。
框架--Mybatis
一、# 与 $区别
1) #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号;$将传入的数据直接显示生成在sql中;
2) #方式能够很大程度防止sql注入;
3) $方式一般用于传入数据库对象;
二、Mybatis分页
1、内存分页,利用自动生成的example类,加入mybatis的RowBounds类,在调用的接口中添加给类的参数;
2、物理分页,在自动生成的example对象中,加入两个成员变量start、和limit,在对应的xml的方法中添加刚刚加入的条件,直接添加在自动生成的orderByClause后面;
三、Mybatis配置文件
四、collection、assications
1、association通常用来映射一对一的关系
2、collection 用来出来一对多的关系
五、Mybatis打印日志
1、在mybatis-config.xml文件中配置如下:
2、在spring-core.xml文件中配置如下
3、创建文件log4j.properties。
六、mybatis配置缓存
业务场景篇
Spring的概述
Spring 是完全面向接口的设计,降低程序耦合性,主要是事务控制并创建bean实例对象。在ssh整合时,充当黏合剂的作用。IOC(Inversion of Control) 控制反转/依赖注入,又称DI(Dependency Injection) (依赖注入)
IOC的作用:产生对象实例,所以它是基于工厂设计模式的
Spring IOC的注入
通过属性进行注入,通过构造函数进行注入,
注入对象数组 注入List集合
注入Map集合 注入Properties类型
Spring IOC 自动绑定模式:
可以设置autowire按以下方式进行绑定
按byType只要类型一致会自动寻找,
按byName自动按属性名称进行自动查找匹配.
AOP 面向方面(切面)编程
AOP是OOP的延续,是Aspect Oriented Programming的缩写,
意思是面向方面(切面)编程。
注:OOP(Object-Oriented Programming ) 面向对象编程
AOP 主要应用于日志记录,性能统计,安全控制,事务处理(项目中使用的)等方面。
Spring中实现AOP技术:
在Spring中可以通过代理模式来实现AOP
代理模式分为
静态代理:一个接口,分别有一个真实实现和一个代理实现。
动态代理:通过代理类的代理,接口和实现类之间可以不直接发生联系,而可以在运行期(Runtime)实现动态关联。
动态代理有两种实现方式,可以通过jdk的动态代理实现也可以通过cglib来实现而AOP默认是通过jdk的动态代理来实现的。jdk的动态代理必须要有接口的支持,而cglib不需要,它是基于类的。
Spring AOP事务的描述:
在spring-common.xml里通过
Spring实现ioc控制反转描述:
原来需要我们自己进行bean的创建以及注入,而现在交给spring容器去完成bean的创建以及注入。所谓的“控制反转”就是 对象控制权的转移,从程序代码本身转移到了外部容器。
官方解释:
控制反转即IoC (Inversion of Control),它把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理。所谓的“控制反转”概念就是对组件对象控制权的转移,从程序代码本身转移到了外部容器。
权限概述
权限涉及到5张表:
用户表,角色表,权限表(菜单表),用户角色关联表,角色权限关联表
当用户登录时,根据用户名和密码到用户表验证信息是否合法,如果合法则获取用户信息,之后根据用户id再到用户角色关联表中得到相关连的角色id集合,之后根据角色id再到角色权限关联表中获取该角色所拥有的权限id集合,然后再根据权限id集合到权限表(菜单表)中获取具体的菜单,展现给当前登录用户,从而达到不同用用户看到不同的菜单权限。我们通过ZTree来给角色赋权并且通过ZTree来展示菜单,以及通过ZTree来管 理菜单即增加和编辑菜单。
我们做的权限控制到url级别,为了防止用户不登录直接输入url访问的这个弊端,通过拦截器进行拦截验证。
OSCache概述
oscache是一个高性能的j2ee框架,可以和任何java代码进行集成,并且还可以通过标签对页面内容进行缓存,还以缓存请求。
我们通常将那些频繁访问但是又不是经常改变的数据进行缓存。为了保证缓存数据的有效性,在数据发生改变的时候,我们要刷新缓存,避免脏数据的出现。刷新缓存的策略有两种,一种是定时刷新,一种手动刷新。
缓存数据的时机通常也分为两种,即在tomcat(web容器)启动时候加载数据进行缓存,另外也可以在用户第一次访问数据的时候进行缓存,这个相当于缓存的立即加载和按需加载。
缓存的层次如下:jsp-->action-->service-->dao,缓存越靠前对性能的提升越大
一个action里面可以有多个service,一个service中可以有多个dao或者多个service
任何类之间都可以进行相互调用,可以通过构造函数传参,set,get传参或者是方法传 参将相关的类连接起来。
OSCache+autocomplete+单例业务场景
在我以前做某项目的过程中,其中我们在做产品列表的查询的时候为了提高用户的体验度,我们使用了autocomplete插件来代替select进行品牌的选择,才开始的时候每次都要根据用户输入的信息去查询数据库进行模糊匹配返回结果,后来我们考虑到系统的性能,因此我们采用了oscache缓存,才开始这个功能是交给我们项目组中的另外一个同事来做的,但是他做完后,我们在使用这个工具类的时候,发现有时缓存中明明已经有时我们需要的数据,但是从缓存里面取的时候,发现没有,之后项目经理让我去帮这个同事看看这个问题,我经过阅读他的代码发现,它里面在使用缓存的时候,针对于每次方法的调用都产生一个新的实例,结果导致了上面的问题,这个时候我想起了可以使用设计模式中的单例模式来解决这个问题,才开始我直接采用了普通的单列模式,但是后来在测试的过程中,发现当用户并发量大的时候还是会出现上面的问题,之后我再次考虑了代码,最后发现是因为没有给单列模式加锁的原因,从而导致了大用户并发的时候,线程安全的问题,之后我便在方法上加上了synchronized关键字,解决上述的问题,但是后来测试人员反馈,觉的这段的性能有问题,我考虑之后便采用在方法体内加锁并结合双重判定的方式解决了上面的问题。我们是将数据在tomcat启动的时候加载到缓存中,之后用户进行查询的时候直接从缓存中获取数据,根据前缀匹配进行查询,将结果返回给用户。这样在提高用户体验度的同时也提高性能。
缓存概述
应用程序为了提高性能,可以通过使用缓存来达到目的,缓存的存储介质可以内存或者硬盘,通常将数据存储在内存里,确切的说是jvm的内存中,缓存是基于Map这种思想构建的,以键值对的方式进行存取,之所以还可以将缓存的数据存储在硬盘中,是因为内存资源相当有限和宝贵,所以当内存资源不足的时候,就可以将其存储到硬盘中,虽然硬盘的存取速度比内存要慢,但是因为减少了网络通信量,所以还是提高程序的性能。缓存可以分为客户端缓存和服务器端缓存,所谓的客户端缓存通常指的是IE浏览器的缓存,服务器端缓存指的web服务器的缓存,通常可以通过第三方组件实现,如oscache,memcache我们通常将那些频繁访问但是又不是经常改变的数据进行缓存。为了保证缓存数据的有效性,在数据发生改变的时候,我们要刷新缓存,避免脏数据的出现。刷新缓存的策略有两种,一种是定时刷新,一种手动刷新。
缓存的层次如下:jsp-->action-->service(通常放置在service)-->dao,缓存越靠前对性能的提升越大
缓存的策略:(缓存空间不足需要进行清理的时候使用)
LRU:最近最少使用原则.(理解:存储书)
FIFO:先进先出的缓存策略.(理解:排队)
你来说说缓存?说说你对缓存的理解(如果遇到重复的,就可以省略)
我们在项目中使用缓存的目的是为了提高应用程序的性能,减少访问数据库的次数,从而提高应用程序的吞吐量。我们通常将权限,菜单,组织机构这些频繁访问但是不经常改变的基础数据进行缓存,其中我在做()某某项目的时候就通过oscache对ZTree的树形菜单进行了缓存,并且在做的时候和单列设计模式进行结合,考虑到多线程下的安全问题,还对单例模式加入了双重判定锁的检查方式。
实现页面静态化业务场景
我们在做某项目时,涉及到程序访问的性能问题,这时候我们想到可以通过静态化来提高用户访问时候的性能,所以我们就采用了freemarker模板引擎,考虑到页面也是要有动态的变化的,所以我们采用spring定时器在每天晚上2点钟的时候定时再次生成html静态页面,考虑发布时候的性能问题,我们又采取线程池技术,让多个线程同时发布,从而缩减发布时间。
servlet线程安全描述
servlet是单列的,对于所有请求都使用一个实例,所以如果有全局变量被多
线程使用的时候,就会出现线程安全问题。
解决这个问题有三种方案:
1.实现singleThreadModel接口,这样对于每次请求都会创建一个新的servlet实例,这样就会消耗服务端内存,降低性能,但是这个接口已经过时,不推荐使用。
2.可以通过加锁(synchroniezd关键字)来避免线程安全问题。这个时候虽然还是单列,但是对于多线程的访问,每次只能有一个请求进行方法体内执行,只有执行完毕后,其他线程才允许访问,降低吞吐量。
3.避免使用全局变量,使用局部变量可以避免线程安全问题,强烈推荐使用此方法来解决servlet线程安全的问题。
Ant描述
Ant是apache旗下的对项目进行自动打包、编译、部署的构建工具,他主要具有轻量级并且跨平台的特性,而且基于jvm,默认文件名为build.xml
Ant主要的标签:
Project 根标签,
target 任务标签,
property 属性标签,自定义键/值 供多次使用,
java 执行编译后的java文件
javac 编译java文件
war 打成war包
其它标签:copy,delete,mkdir,move,echo等。
FreeMarker描述
FreeMarker是一个用Java语言编写的模板引擎,它是基于模板来生成文本输出的通用工具。Freemarker可以生成HTML, XML,JSP或Java等多种文本输出。
工作原理:定义模板文件,嵌入数据源,通过模板显示准备的数据
(数据+模板=输出)
我们在使用模板中发现freemarker具有许多优点,它彻底的分离表现层和业务逻辑,模板只负责数据在页面中的表现,不涉及任何的逻辑代码,所以使得开发过程中的人员分工更加明确,作为界面开发人员,只需专心创建HTML文件、图像以及Web页面的其他可视化方面,不用理会数据;而程序开发人员则专注于系统实现,负责为页面准备要显示的数据。
如果使用jsp来展示,开发阶段进行功能调适时,需要频繁的修改JSP,每次修改都要编译和转换,浪费了大量时间,FreeMarker模板技术不存在编译和转换的问题,在开发过程中,我们在不必在等待界面设计开发人员完成页面原型后再来开发程序。由此使用freemarker还可以大大提高开发效率。
webService描述
(主动说)
webservice是SOA(面向服务编程)的一种实现,主要是用来实现异构平台通信也就是不同平台不同项目之间的数据传输,从而避免了信息孤岛的问题,它之所以能够进行异构平台通信是因为它是完全基于xml的,所以说,webService是跨平台,跨语言,跨框架的,在java中通常有三种技术框架分别是xfire,cxf,axis2。
我们为了保证webservice的安全性,采用了基于WS-Security标准的安全验证(使用回调函数)。(没必要主动说)webservice的三要素分别是:
wsdl(webservice description language 描述语言)用来描述发布的接口(服务);
soap(simple object access protocol 简单对象连接协议)是xml和http的结合,是webservice数据通信的协议;
uddi 用来管理,查询webService的服务(没必要主动说);
webservice的具体三种实现方式(框架)或者三种实现框架的区别
1. Axis2:可以用多种语言开发,是一个重量级框架,功能非常强大,但是它的性能比较低。
2. Xfire:它相比Axis2来说是一个轻量级框架,它的性能要比Axis2高。
3. cxf:是Xfire的升级版,就好比是,struts2是webwork的升级,然后cxf和spring集成起来非常方便,简易,性能方面也要比Xfire高。
【注】jdk6 自带的webservice jws
(主动说)
业务场景
我在以前做项目的时候,其中遇到一个功能,需要进行两个项目之间的数据的传输,项目经理让我去完成这个任务,我根据以往的项目经验,想到两种解决方案,第一种就是开放另外一个项目的数据库的权限给我,然后我直接通过访问另外一个项目的数据库,来得到需要的信息,但后来我分析了下,觉的这种方式不安全,而且因为当时这个项目是另外一家公司负责在做,所以数据库里面的表结构,以及以后牵涉到的责任问题都很多,所以我就采用了第二种方案,即通过webservices的方式,进行异构系统之间数据信息的传递,webservices的具体实现,有xfire,cxf,axis2,我根据以往的项目经验,了解到cxf是xfire的升级版本,适用于java语言,xfire/cxf 性能比axis2要高,并且和spring整合起来也比较方便,而axis2支持更多的语言,性能相对于cxf要低,通过上面分析,结合我们目前的两个项目都是基于java语言的,所以我采用cxf这种方式实现了两个项目之间数据的传递,我们为了保证webservice的安全性我们采用了基于WS-Security标准的安全验证(使用CXF回调函数)。
(没必要主动说)webservice服务端配置流程
首先在web.xml中引入cxfServlet核心类,指定对以/cxf开头的url路径提供webservice服务,之后我们在要发布成webservice接口上添加@Webservice 注解,而且还要在实现类上添加同样的webservice注解并且要说明实现了哪个接口,之后在spring-webservice.xml中发布webservice服务,通过jaxws:endpoint这个标签,并且在标签配置implementor和address来表明实现服务的类,以及发布的地址.最后在浏览器中输入相关的webservice地址?wsdl来验证服务是否发布成功。
(没必要主动说)webservice客户端的配置
首先通过wsdl2java根据发布的webservice服务端地址的wsdl生成客户端调用的中间桥梁java类,将生成的java类拷贝到客户端项目中,配置spring-client.xml文件,通过jaxws:client定义一个bean,并通过address属性指明要访问的webservice的服务地址,通过serviceClass指明充当中间桥梁的服务类,之后获取该bean,就可以通过它来访问发布的webservice接口中的方法。
二十二、Ant业务场景
Ant是基于java语言编写的,因此具有跨平台的特性,此外还具有简洁方便,灵活
配置的特性,因此我就在XX项目中使用ant进行项目的编译,打包,部署操作。使用ant
之后,如果我们在客户那里修改代码后,就可以直接使用ant进行编译,打包,部署,而不需要为了编译,打包,部署专门在客户那里安装eclipse.此外使用ant也可以直接和svn进行交互,下载源码的同时进行编译,打包,部署。
二十三、Junit 业务场景
在我们开发项目的时候为了提高代码的性能和保证逻辑正确性,在我们编写代码后往往都要进行单元测试,来验证代码,当时我们公司开发人员全部使用的main方法来进行验证,但是使用mian的最大缺点就是不能将多个类同时进行验证,验证的结果不直观,测试复杂(每个类都要写main方法,单个运行),一定程度上浪费时间,所有我和项目经理提议使用专业测试工具Junit来进行测试,因为Junit是一个Java语言的单元测试框架 ,测试简单,不仅可以提供工作效率和代码的质量,也提高团队的合作能力,我提议后我们进行了Junit的培训使用Junit4加注解的方式来测试。
二十四、Apache+Tomcat 实现负载均衡及seesion复制
当我们tomcat访问量大,线程连接数不够时,我们考虑到了tomcat的负载均衡来分担过多的访问.性能方面负载均衡也能利用多台tomcat来增大内存量,
流程,准备工作apache,Jk_mod,tomcat,在apache的conf/httpd.conf文件中 使用include 标签引入我们自定义的一个mood_jl.conf,在modules中引入下载的k_mod-apache-X.X.XX.so文件,在其中引入我们的.so,及work.properties文件,及指定负载分配控制器controller,在work.properties文件中worker.list=controller,tomcat1,tomcat2指定service,worker.tomcat1.port Ajp端口号,type 是ajp,host为指定ip,lbfactor 指定分配权重值越大分担请求越多,worker.controller.type=lbworker.controller.balanced_workers=tomcat1,tomcat2 指定分担请求的tomcat Session的复制在tomcat中service.xml中Engine标签加入 jvmRoute 值为work,properties中指定的tomcat名称,然后打开
我们在做这个项目时,我们考虑到服务器性能的问题,我们最开始想到使用纵向扩展,来增加硬件的配置提高其性能,但这样做比较耗费资金,而且服务器内存空间也是有限的;所以后来就想到使用横向扩展来达到这一目的
当时我们的apache是通过jk借助于ajp协议与tomcat进行通信的,在我们不进行负载均衡之前,那所有的请求都由一台tomcat进行处理,这样会使我们的tomcat所承受的压力增大,而我们进行负载均衡之后,同样数量的请求经过apache和jk将其分发到多台tomcat进行处理,从而降低每台tomcat所承受的压力,而且当其中一台机器宕机时,其他机器还可以继续提供服务,保证服务不间断。
在这个过程中,我们遇到了session问题,然后我此昂到用session复制来解决这个问题;
在apache的配置文件中增加session粘带特性:
worker.lb.sticky_session=1
worker.lb.sticky_session_force=0
Tomcat的配置
修改server.xml文件:
增加jvmRoute=”tomcat2” *. jvmRoute赋的值为worker.properties中配置的相应的server名一致
修改应用的web.xml文件
在应用中的web.xml文件中增加
如果这样做,当第一次访问的时候,会把所以数据全部缓存到第一台服务器上,通过web配置文件,会把第一台缓存的数据全部复制到第二胎服务器上,这样做就加大网路通信量,导致阻塞,所以我们就想到了可以通过memcached分布式缓存来存取session从而解决上述问题。
二十五、maven业务场景
maven业务场景
前段时间在研究maven,知道maven是一个项目管理工具,其核心特点就是通过maven可以进行包的依赖管理,保证jar包版本的一致性,以及可以使多个项目共享jar包,从而能够在开发大型j2ee应用的时候,减小项目的大小,并且和ant比起来,maven根据“约定优于配置”的特性,可以对其项目的编译打包部署进行了更为抽象的封装,使得自己不需要像ant那样进行详细配置文件的编写,直接使用系统预定好的mvn clean,compile,test,package等命令进行项目的操作。于是我就在XX项目中采用了maven,为了保证团队中的成员能够节省下载jar包所需要的时间,于是我就采用nexus搭建了在局域网内的maven私服,然后通过配置settings.xml中建立mirror镜像,将所有下载jar包的请求都转发到maven私服上,之后通过在pom.xml即(project object model)中配置项目所依赖的jar包,从而达到在构建项目的时候,先从本地仓库中查找,如果不存在从内部私服查找,如果不存在最后再从外网central服务器查找的机制,达到了节省下载带宽,提高开发效率,以及jar包重用的目的。
maven的常用命令
mvn eclipse:clean eclipse:eclipse -Dwtpversion=2.0
mvn clean package
maven的生命周期是独立的,但是生命周期下的阶段是相互关联并且延续的。
maven的生命周期
clean(清理):clean;default(默认):compile,test,packageinstall;site(站点)
二十六、bugfree的操作步骤
我们在使用bugfree的时候我们首先登陆的时候是以测试员的身份登陆的,也就是系统管理员用户;测试员在登陆后首先应该给要测试的项目的相关负责人,每人创建一个账号(也就是在登陆后的页面的后台管理中创建用户),用户都新建完成之后就新建组,把要测试的项目的用户添加到组中。最后就新建项目并且新建该项目的模块。新建完项目之后就是开始测试程序,在程序中遇到bug以后就把错误截图,在到bugfree中新建bug填写相关的信息和要指派的人(出错模块的负责人)和把刚才的错误截图作为附件一并传送过去。
开发人员每天早上上班的第一件事就是用自己的用户登录bugfree,然后输入查询条件看看前一天有没有指派给自己的bug需要解决的如果有就进行解决。
开发人员把对应的bug解决之后就去bugfree上把bug对应的状态改成已解决状态,然后进行保存提交,这样bug的状态就变成已解决状态。测试人员上线查看已解决状态的bug并再次进行测试,如果经过测试bug的问题已解决,就可以把bug关闭;如果经过测试,发现仍然存在bug,就把bug激活;这样等开发人员再次登录的时候就可以再次看到这个未解决的bug,再次进行解决,如此反复直到bug全部解决,因为bugfree对bug的修改都有保留,所有我们可以看到bug的一步步的完善,直到最后把bug关闭。
Bug的三种状态:未解决(Active)(测试人员)、已解决(Resolved)(开发人员)、关闭(Closed)(测试人员)
二十七、spring定时器
每隔固定的时间执行
1.建立一个triggers触发器集合
2.建立SimpleTriggerBean并且指定每次间隔的时间以及执行的次数以及要执行的目标
3.通过 targetObject以及targetMethod找到要执行的具体类的具体方法目标对象是一个普通的java类每到指定的时间执行
1.建立一个triggers触发器集合.
2.建立CronTriggerBean指定cron表达式以及要执行的目标
3.通过 targetObject以及targetMethod找到要执行的具体类的具体方法目标对象是一个普通的java类
二十八、Ext概述
据我了解Ext是一个用js编写RIA框架,它可以和各种后台语言结合使用。我在项目中用Ext来完成的模块大概情况是这个样子,首先我通过layout等于border的这种方式来进行布局,分为上下左右中,然后在左边用exttree来进行菜单的展示,之后在中间区域通过tabs来加入选项卡,而在选项卡中就是一个个的grid以及form,其中我在做grid的时候,首先通过store来存取后台返回的符合model格式数据集,store是通过proxy和后台的contoller进行交互,之后把store赋值给grid的store属性并且通过renderTO在指定的位置进行渲染展示。
Grid问题:
当时我在做grid的时候,发现数据没有展示出来,我通过f12进行跟踪,发现压根就没有发送请求,后来我分析了下,发现因为没有调用store的loadPage方法,所以导致了这个问题。除此之外在我们做项目的过程中,我手底下带的一个人同样在负责grid的时候,数据可以正常展示,但分页信息没有展示,通过跟踪他的代码发现是因为他没有把store属性赋值给分页工具条,所以才导致了这个问题。
tabs选项卡:
当我在做tab选项卡这一模块的时候,我首先在加载页面的时候用TabPanel创建了一个tab页面,让它展示在中间位置,然后点击左边Tree菜单调用add方法动态添加一个个的tab选项卡,但是做的过程中出现了相同的选项卡会重复添加的问题,我查了一些相关资料,最后通过tab的id或者一个唯一标识判断tab是否选中,如果选中则调用setActiveTab来激活该选项卡,让它选中,否则就添加一个tab。最后达到了tab不存在就添加,存在就选中的效果。
了解:
Ext4.0也支持前端的MVC开发模式.
为啥没采用mvc的开发模式?我们当时因为时间方面的原因,项目经理就决定用普通的这种开发模式进行开发,并没有采用Ext4.0这种mvc模式的特性。但我认为他们的核心操作流程是一致的所以对我来说去学习和使用这种方式并没有什么难度。
二十九、lucene的概述
lucene是一个全文检索引擎,在进行模糊匹配的时候,他可以用来替代数据库中的like,从而在匹配准确性以及性能进行大幅度的提高。我在做XX项目的XX模块的时候,就是用lucene来进行全文检索用IK分词器来进行分词。从而实现了高亮显示关键词,分页,排序,多字段,多条件的高性能搜索。在从数据中取数据生成索引的时候,因为表中的数据量比较大,防止一次取出所导致内存溢出问题,我采用了分段批量提取的方式进行,除此之外我们对后续增加的数据根据优先级的不同采取不同的策略,对于那些需要及时显示的数据我们通过spring定时器 在短时间内(30分钟)进行增量索引的生成,对于那些不需要及时展示的数据,我们通过spring定时器在每天晚上凌晨的时候进行索引的重新生成。
三十、线程池作用
1.减少了创建和销毁线程的次数,每个线程都可以被重复利用,可执行多个任务。
2.可以根据系统的承受能力,调整线程池中线程的数目,防止因为消耗过多的内存,而导致服务器宕机(每个线程需要大约1MB内存,线程开的越多,消耗的内存也就越大,最后宕机)。通常我们使用的线程池是实现了ExecutorService的ThreadPoolExecutor。
三十一、Tomcat优化
增大内存(堆,持久代)并开启server模式
我在做XXX项目时,用到了poi导入和导出数据,由于公司的业务比较繁多,数据量很大,测试时报内存溢出,经过我的分析再结合上网查阅资料,发现可能是tomcat内存不足,需要增大,修改配置文件后测试不再报错.
tomcat增大内存的方式通过修改tomcat配置文件
window下, 在bin/catalina.bat文件中最前面添加:
set JAVA_OPTS=-XX:PermSize=64M -XX:MaxPermSize=128m –Xms1024m -Xmx1024m
linux下,在catalina.sh最前面增加:
JAVA_OPTS="-XX:PermSize=64M -XX:MaxPermSize=128m –Xms1024m -Xmx1024m "
-client –service
当我们在cmd中运行-java时,黑窗口会出现-client -service这两参数.其作用是设置虚拟机运行模式;client模式启动比较快,但运行时性能和内存管理效率不如server模式,通常用于客户端应用程序。server模式启动比client慢,但可获得更高的运行性能。Windows默认为client,如果要使用server模式,就需要在启动虚拟机时加-server参数,以获得更高性能,对服务器端应用,推荐采用server模式,尤其是多个CPU的系统。在Linux,Solaris上,默认值为server模式.
JDK版本
影响虚拟机还有JDK的版本,JDK分为32位,64位两种版本,32位装在32位系统,64位系统可以装32位和64位JDK.64位JDK性能优于32位JDK.
测试的命令 java -xmx数值m –version 报错配置大小失败,反之成功
增加Tomcat最大连接数
使用场景
我在做完一个XXX项目后,测试时发现并发数量增加到一定程度就会很卡,于是我想到了是不是tomcat最大连接数设置有限制.果不其然,配置文件中最大值才500,于是我更改了最大连接数,根据业务我修改了连接数为2000,完美的解决了这个问题;
修改方法在conf/service.xml中默认值
minSpareThreads="30" maxSpareThreads="75" enableLookups="false" redirectPort="8443" acceptCount="100" connectionTimeout="20000" disableUploadTimeout="true" />,修改maxthreads的值即可 tomcat进行gzip压缩从而降低网络传输量 tomcat 压缩设置tomcat压缩gzip启用 HTTP 压缩可以大大提高浏览网站的速度,它的原理是, 在客户端请求服务器对应资源后,从服务器端将资源文件压缩, 再输出到客户端,由客户端的浏览器负责解压缩并浏览。 相对于普通的浏览过程HTML ,CSS,Javascript , Text , 它可以节省60%左右的流量。更为重要的是,它可以对动态生成的, 包括CGI、PHP , JSP , ASP , Servlet,SHTML等输出的网页也能进行压缩, 压缩效率也很高。 启用tomcat 的gzip压缩 要使用gzip压缩功能,你需要在Connector节点中加上如下属性 记住来源:http://www.qi788.com/info-42.html compression="on" 打开压缩功能 compressionMinSize="50" 启用压缩的输出内容大小,默认为2KB noCompressionUserAgents="gozilla, traviata" 对于以下的浏览器,不启用压缩 compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain" 哪些资源类型需要压缩 connectionTimeout="20000" redirectPort="8443" executor="tomcatThreadPool" URIEncoding="utf-8" compression="on" compressionMinSize="50" noCompressionUserAgents="gozilla, traviata" compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain" /> memcached是一个用C语言开发的分布式的缓存,内部基于类似hashMap的结构。它的优点是协议简单,内置内存存储,并且他的分布式算法是在客户端完成的,不需要服务器端进行通信,我们当时在做项目的时候因为考虑到项目的高可用性高扩展性,因此在服务器部署方面采用了apache+jk+tomcat这种负载均衡的方式,但是也带来了一个问题就是session共享的问题,虽然可以通过session复制来解决这个问题,但是在性能方面存在缺陷,所以最后我们采用了用memcached来存储session,这样既解决了session共享问题,也解决了session复制那种方式所产生的性能问题。 了解(不必主动说,但别人问的话一定要知道) memcached是以KEY-VALUE的方式进行数据存储的, KEY的大小限制:Key(max)<=250个字符; VALUE在存储时有限制:Value(max)<= 1M; 根据最近最少使用原则删除对象即LRU. memcached默认过期时间:ExpiresTime(max)= 30(days) 代码结构层次的优化(目的:更加方便代码的维护--可维护性,可读性) 1.代码注释(代码规范) 2.工具类的封装(方便代码的维护,使代码结构更加清晰不臃肿,保证团队里代码质量一致性) 3.公共部分的提取 代码性能的优化(目的:使程序的性能最优化) 1.使用一些性能比较高的类(bufferInputStream) 2.缓冲区块的大小(4k或者8k) 3.公共部分的提取 4.通常要用stringbuffer替代string加号拼接 我们做项目的时候业务优化这方面最主要是从用户体验度角度进行考虑,减少用户操作的步骤提高工作效率,通常有以下几种: 1.可以通过tabindex属性来改变tab键盘的操作顺序 2.可以通过回车键来进行搜索或者提交操作 3.对于单选按钮和复选按钮可以通过操作后面的文本来选择前面的单选按钮以及复选按钮 4.添加的信息要按照id倒序进行排列 5.进行搜索操作时加入js loading操作(不仅告诉用户所进行的请求正在被处理,而且防止用户多次点击提交操作) 6.当进行删除操作的时候要弹出提示框,警告用户要进行删除操作,是否确认。 7.根据returnURL在用户登录成功后直接跳到想要访问的资源。 8.进行删除操作时通过confirm提示用户是否确认删除操作,操作完后提示操作是否成功。 9.减少用户操作的步骤 10.使用autocomplete插件快速进行搜索 必背,必做: 1.可以通过回车键来进行搜索或者提交操作 2.添加的信息要按照id倒序进行排列 3.进行搜索操作时加入js loading操作(不仅告诉用户所进行的请求正在被处理,而且防止用户多次点击提交操作) 4.当进行删除操作的时候要弹出提示框,警告用户要进行删除操作,是否确认,如果删除成功则弹出提示框告诉用户。 5.减少用户操作的步骤 6.通过ztree,以及kindeiditor来提高用户的体验度 1、SELECT子句中避免使用 *, 尽量应该根据业务需求按字段进行查询 2、尽量多使用COMMIT如对大数据量的分段批量提交释放了资源,减轻了服务器压力 3、在写sql语句的话,尽量保持每次查询的sql语句字段用大写,因为oracle总是先解析 sql语句,把小写的字母转换成大写的再执行 4、用UNION-ALL 替换UNION,因为UNION-ALL不会过滤重复数据,所执行效率 要快于UNION,并且UNION可以自动排序,而UNION-ALL不会 5、避免在索引列上使用计算和函数,这样索引就不能使用 Sql优化精简版: 1.(重点)(必须说) SELECT语句中避免使用 *, 尽量应该根据业务需求按字段进行查询 举例:如果表中有个字段用的是clob或者是blob这种大数据字段的话, 他们的查询应该根据业务需要来进行指定字段的查询,切记勿直接用* 2.(重点) 删除重复记录(oracle): 最高效的删除重复记录方法 ( 因为使用了ROWID)例子: DELETE FROM EMP E WHERE E.ROWID > (SELECT MIN(X.ROWID) FROM EMP X WHERE X.EMP_NO = E.EMP_NO); 3. 用>=替换> 如一个表有100万记录,一个数值型字段A, A=0时,有30万条; A=1时,有30万条; A=2时,有39万条; A=3时,有1万记录。 那么执行 A>2 与 A>=3 的效果就有很大的区别了,因为 A>2 时, ORACLE会先找出为2的记录索引再进行比较, 而A>=3时ORACLE则直接找到=3的记录索引。 4.(重点)尽量多使用COMMIT 如对大数据量的分段批量提交 5. (重点)用NOT EXISTS 或(外连接+判断为空)方案 替换 NOT IN操作符 此操作是强列推荐不使用的,因为它不能应用表的索引。 推荐方案:用NOT EXISTS 或(外连接+判断为空)方案代替 6.(重点 必须说)LIKE操作符(大数据的全文检索使用luncene)(solr) 因为使用like不当,会导致性能问题,原因是like在左右两边都有 %的时候,不会使用索引。 如LIKE '%5400%' 这种查询不会引用索引, 而LIKE 'X5400%' 则会引用范围索引。 一个实际例子: 查询营业编号 YY_BH LIKE '%5400%' 这个条件会产生全表扫描, 如果改成 YY_BH LIKE 'X5400%' OR YY_BH LIKE 'B5400%' 则会利用 YY_BH 的索引进行两个范围的查询,性能肯定大大提高。 7.(重点,必须说)避免在索引列上使用计算和函数,这样索引就不能使用 举例: 低效: SELECT … FROM DEPT WHERE SAL * 12 > 25000; 高效: SELECT … FROM DEPT WHERE SAL > 25000/12; 8.(重点 必须说)用UNION-ALL 替换UNION, 因为UNION-ALL不会过滤重复数据而且不会自动排序, 所执行效率要快于UNION。 9. (优化,重点,3个方面 a.缓存 b.分段批量 c.存储过程)减少访问数据库的次数 举例:如果批量删除多条数据,可以用 delete from tableName where id in (1,2,3) 而不要用多条delete语句进行删除 10.(重点 必须说)用TRUNCATE替代DELETE TRUNCATE不记录日志,DELETE记录日志,所以TRUNCATE要快于DELETE但是一旦用TRUNCATE进行删除就不能进行恢复,TRUNCATE是删除整张表的数据不能加where条件。 ================================================================== mysql,sqlserver中如果id为自增类型,那么如果用TRUNCATE删除,则id字段再插入数据时从1开始,如果delete删除的话,则从删除之前的id的值继续增长。 针对防sql注入,我们通常是这样做的: 首先在前台页面对用户输入信息进行js验证,对一些特殊字符进行屏蔽,比如:or ,单引号,--,= ,还有就是限制用户名输入的长度,我们一般将其限制在6---13位。另外,对于用户的敏感信息我们进行Md5加密,还有,为了增加用户体验度和用户友好度,为了不使用户看到一些详细的异常信息我们会进行错误信息页面的定制,像404,500错误。另一个我层面讲,这样做也是为了保护我们的一些重要信息。此外,我们会给特定的人分配定定的权限,而不是给其分配管理员权限! 所谓SQL注入,就是通过一些含有特殊字符的sql语句发送到服务器欺骗服务器并进行攻击。(特殊字符:or, 单引号,--,空格) 1.永远不要信任用户的输入。对用户的输入进行校验,可以通过正则表达式(js正则或者java后台正则),或限制长度;对单引号和双"-"进行转换等。 2.永远不要使用动态拼装sql,使用参数化的sql。(永远不要使用+号拼接sql字符串,而是使用?传参的方式进行) 3.不要给用户太高的权限而根据需求进行赋权 4.对敏感信息进行加密 如md5(单向加密不可逆转)。 5.自定义错误页面。目的是为了不把我们的程序的bug暴露在别有用心的人的面前。而去不会让用户看到报错的页面,也提高了用户的体验度。 SQL注入防范 使用参数化的过滤性语句 要防御SQL注入,用户的输入就绝对不能直接被嵌入到SQL语句中。恰恰相反,用户的输入必须进行过滤,或者使用参数化的语句。参数化的语句使用参数而不是将用户输入嵌入到语句中。在多数情况中,SQL语句就得以修正。然后,用户输入就被限于一个参数。 输入验证 检查用户输入的合法性,确信输入的内容只包含合法的数据。数据检查应当在客户端和服务器端(java代码)都执行之所以要执行服务器端验证,是为了弥补客户端验证机制脆弱的安全性。 在客户端,攻击者完全有可能获得网页的源代码,修改验证合法性的脚本(或者直接删除脚本),然后将非法内容通过修改后的表单提交给服务器。因此,要保证验证操作确实已经执行,唯一的办法就是在服务器端也执行验证。你可以使用许多内建的验证对象,例如Regular Expression Validator,它们能够自动生成验证用的客户端脚本,当然你也可以插入服务器端的方法调用。如果找不到现成的验证对象,你可以通过Custom Validator自己创建一个。 错误消息处理 防范SQL注入,还要避免出现一些详细的错误消息,因为黑客们可以利用这些消息。要使用一种标准的输入确认机制来验证所有的输入数据的长度、类型、语句、企业规则等。 加密处理 将用户登录名称、密码等数据加密保存。加密用户输入的数据,然后再将它与数据库中保存的数据比较,这相当于对用户输入的数据进行了“消毒”处理,用户输入的数据不再对数据库有任何特殊的意义,从而也就防止了攻击者注入SQL命令。 存储过程来执行所有的查询 SQL参数的传递方式将防止攻击者利用单引号和连字符实施攻击。此外,它还使得数据库权限可以限制到只允许特定的存储过程执行,所有的用户输入必须遵从被调用的存储过程的安全上下文,这样就很难再发生注入式攻击了。 使用专业的漏洞扫描工具 攻击者们目前正在自动搜索攻击目标并实施攻击,其技术甚至可以轻易地被应用于其它的Web架构中的漏洞。企业应当投资于一些专业的漏洞扫描工具,如大名鼎鼎的Acunetix的Web漏洞扫描程序等。一个完善的漏洞扫描程序不同于网络扫描程序,它专门查找网站上的SQL注入式漏洞。最新的漏洞扫描程序可以查找最新发现的漏洞。 确保数据库安全 锁定你的数据库的安全,只给访问数据库的web应用功能所需的最低的权限,撤销不必要的公共许可,使用强大的加密技术来保护敏感数据并维护审查跟踪。如果web应用不需要访问某些表,那么确认它没有访问这些表的权限。如果web应用只需要只读的权限,那么就禁止它对此表的 drop 、insert、update、delete 的权限,并确保数据库打了最新补丁。 安全审评 在部署应用系统前,始终要做安全审评。建立一个正式的安全过程,并且每次做更新时,要对所有的编码做审评。开发队伍在正式上线前会做很详细的安全审评,然后在几周或几个月之后他们做一些很小的更新时,他们会跳过安全审评这关, “就是一个小小的更新,我们以后再做编码审评好了”。请始终坚持做安全审评。 ddl:数据定义语言 Create Drop Alter dml:数据操纵语言 insert update delete select dcl:数据控制语言 grant revoke tcl:事务控制语言 commit rollback 1.jvm的相关概念 当List放了大量的数据超过jvm中所能容纳的内存后,就会发生堆溢出。 当递归调用没有临界退出条件就会出现 栈溢出。 当批量导入大量数据或者用dom4j解析大的xml文件的时候,会出现 堆溢出,这个时候可以通过分段批量提交以及用 sax代替dom4j来解决问题。 heap(堆),stack(栈) jvm的结构细分及其概述? Java 虚拟机有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配。堆是在 Java 虚拟机启动时创建的。”“在JVM中堆之外的内存称为非堆内存(Non-heap memory)”。可以看出JVM主要管理两种类型的内存:堆和非堆。 简单来说堆就是Java代码可及的内存,是留给开发人员使用的;非堆就是JVM留给自己用的。 jvm 内存结构? 堆: 逻辑上是连续,物理上可以处于不连续的内存空间中,里面存储的是对象实例以及数组。可以细分为新生代,老生代。通过-Xmx和-Xms控制大小。 虚拟机栈:基本数据类型,对象引用(地址,指针)。 本地方法栈(了解):它与虚拟机栈发挥的作用差不多,区别在于虚拟机栈为java方法的执行提供服务,而本地方法栈为虚拟机使用到的Native(本地)方法服务。 方法区:放了所加载的类的信息(名称、修饰符等)、类中的静态变量、类中定义为final类型的常量、类中的Field信息、类中的方法信息在Sun JDK中这块区域对应的为PermanetGeneration,又称为持久代,默认为64M,可通过-XX:PermSize以及-XX:MaxPermSize来指定其大小 在服务器启动的时候报内存溢出是因为方法区太小,也就相当于持久代的内存太小。 通过-XX:PermSize以及-XX:MaxPermSize来指定其大小,可以解决这个问题。 常量池是方法区的一部分,用来存储常量信息。如String就存储在常量池中。 计数器(了解):通过该计数器的值来选取下一条要执行的字节码指令。 GC是什么,为什么要有GC? GC就是垃圾回收,java这种语言是动态分配内存大小的,并且依靠垃圾回收机制来完成对分配内存空间的回收,从而来避免内存溢出的问题,也在一定程度上降低了程序员工作的复杂度。jvm中的GC采用了generation(分代回收)算法,因为大多数的对象存活的时间比较短,而少部分的对象才能够长时间存活。因此,jvm将堆内存划分为年轻代(young generation)和年老代(old generation)。年轻代中的对象通常建立时间不久,且大部分生命周期也很短;年老代中的对象则已经创建比较久了,其声明周期也相对年轻代比较长。按照上面的划分,jvm在做GC时也进行了区别对待,对年轻代GC会相对比较频繁,且采用了copying(复制)算法;年老代的GC相对比较少,且采用的是tracing算法的一种,是标记-清除-压缩。 JVM内存限制(最大值) JVM内存的最大值跟操作系统有很大的关系。简单的说就32位处理器虽然 可控内存空间有4GB,但是具体的操作系统会给一个限制,这个限制一般是2GB-3GB(一般来说Windows系统下为1.5G-2G,Linux系统 下为2G-3G),而64bit以上的处理器就不会有限制了。 Java 监视和管理控制台: JConsole 使您能够在运行时监视各种 JVM 资源统计信息。这种特性特别适用于检测死锁、内存泄漏。它可以连接到一个本地或远程 JVM 并可用来进行监视: 线程状态(包括相关的锁) 内存使用情况 垃圾收集 运行时信息 JVM 信息 jvm的调优? 开启-Server模式,增大堆的大小,以及持久代的大小,从而提高程序的运行效率,并且将初始堆大小和最大堆大小设置为一样的值从而避免了堆增长会带来额外压力。持久代大小的设置同理,也设置为初始大小和最大大小一样大。 jvm的类加载机制? jvm中类的生命周期? 生命周期:加载、连接、初始化,使用,卸载 对象基本上都是在jvm的堆区中创建,在创建对象之前,会触发类加载(加载、连接、初始化),当类初始化完成后,根据类信息在堆中实例化类对象,初始化非静态变量、非静态代码以及默认构造方法,当对象使用完之后会在合适的时候被jvm垃圾收集器回收。要经过三步:加载(Load),链接(Link),初始化(Initializ)。其中链接又可分为校验(Verify),准备(Prepare),解析(Resolve)三步。ClassLoader就是用来装载的。通过指定的className,找到二进制码,生成Class实例,放到JVM中。 ClassLoader从顶向下分为 : Bootstrap ClassLoader:引导类加载器,它负责加载Java的核心类(如rt.jar) Extension ClassLoader:扩展类加载器,它负责加载JRE的扩展目录(JAVA_HOME/jre/lib/ext)中的JAR包 System ClassLoader:系统(也称为应用)类加载器,它负责在JVM被启动时加载来自在命令java中的-classpath中的JAR包 User-Defined ClassLoader:用户自定义的类加载器 linux中的命令: ps -ef | grep :查看进程信息 vi:文件编辑命令 more:分页查看命令 top:常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况 ifconfig:显示或配置网络设备的命令 ping:它通常用来测试与目标主机的连通性 rsync、scp:文件同步命令 2.云计算+大数据的具体技术实现方案: Hadoop是一个能够对大量数据进行分布式处理的软件框架。 它以并行的方式工作,通过并行处理加快处理速度,维护多个工作数据副本,具有可伸缩性,能够处理 PB 级数据. hadoop 由许多元素构成。其最底部是HDFS,它存储 Hadoop 集群中所有存储节点上的文件。 HDFS的上一层是MapReduce 引擎. hadoop下的子项目: HDFS:Hadoop分布式文件系统 MapReduce:并行计算框架(建立在HDFS上的) HBase: 类似Google BigTable的分布式NoSQL 列数据库 Hive:数据仓库工具 Zookeeper:分布式锁设施 Pig: 大数据分析平台,为用户提供多种接口 行业知识(了解): 存储容量:是该存储设备上可以存储数据的最大数量,通常使用千字节(kb kilobyte)、兆字节(MB megabyte)、吉字节(GB, gigabyte)、太字节(TB ,terabyte)和PB(Petabyte)、EB(Exabyte)等来衡量。 1KB=2(10)B=1024B; 括号中的数字为2的指数(即多少次方) 1MB=2(10)KB=1024KB=2(20)B; 1GB=2(10)MB=1024MB=2(30)B。 1TB=2(10) GB=1024GB=2(40)B 1PB=2(10) TB=1024TB=2(50)B 1EB=2(10) PB=1024PB=2(60)B 1Byte(相當於一個英文字母,您的名字相當6Bytes(6B)。 Kilobyte(KB)=1024B相當於一則短篇故事的內容。 Megabyte(MB)=l024KB相當於一則短篇小說的文字內容。 Gigabyte(GB)=1024MB相當於貝多芬第五樂章交響曲的樂譜內容。 Terabyte(TB)=1024GB相當於一家大型醫院中所有的X光圖片資訊量。 Petabyte(PB)=l024TB相當於50%的全美學術研究圖書館藏書資訊內容。 Exabyte (EB)=1024PB;5EB相當於至今全世界人類所講過的話語。 Zettabyte(ZB)=1024EB如同全世界海灘上的沙子數量總和。 Yottabyte(YB)=1024ZB相當於7000位人類體內的微細胞總和。 本篇文章的内容就到这了,希望大家可以喜欢,也希望大家可以多多关注脚本之家的其他精彩内容!三十二、memcached的介绍
优化篇
代码优化
业务优化
sql优化
防sql注入
sql注入
Sql注入的防护
五、数据库中常用术语:
深入java虚拟机以及大数据
总结