老师好!我是曾强,今年22岁,出生于四川省成都市,现就读于XX人工智能学院软件工程专业。很荣幸有机会参加此次面试。
大学期间,我努力学习,通过了大学英语四级考试,软考中级软件设计师考试,我热爱编程,主攻Java方向,有良好的编程习惯;熟悉JSP+Servlet+JavaBean模式的WEB开发;熟悉Struts,Spring ,Hibernate,Springboot等热门框架;熟悉前端基础知识和框架的使用,能进行基本的网页开发;能使用基本命令操作 Linux 系统;熟悉python,能进行简单的爬虫程序编写。
我待人坦诚有责任心,勤实践,喜欢团队合作,能够很好地融入团队,有良好的团队精神,性格开朗,喜欢结交朋友。
成为一名优秀的Java开发工程师是我长期以来渴望的梦想。我也希望贵公司能给我一个机会,我定能努力工作,努力创造自己的价值。
封装
继承
多态
charAt(i)、toCharArray()、equals()、contains()、replaceAll()、substring()、split()、isEmpty()、trim()、toUpperCase()、toLoweCase()、concat()
This:当前对象、本类属性、本类方法
Super:父类对象,调用父类属性和方法
定义属性:使用static定义公共属性(所有对象都可使用),修改的属性内容适用于全部的实例化对象,可直接通过类名称.static属性来进行调用修改
定义方法:static定义的方法,类名称直接调用
作用:没有实例化对象时执行类的某些操作;实现数据的共享
应用:实例化对象个数统计、类属性自动命名等
重载:同一个类中,方法名相同,参数不同
覆写:继承关系中,方法名称参数完全相同,子类不能有比父类更严格的控制权限
相当于一个终结器
定义类:不能被继承
定义方法:不能被子类覆写
定义变量:相当于常量,无法被修改,且常量单词字母全部大写
特点:构造方法被私有化,只能有一个实例化对象,在类中实例化,外部无法实例化对象
应用:如Windows系统的回收站
class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return instance;
}
public void print() {
System.out.println("单例设计模式");
}
}
public class 单例设计模式 {
public static void main(String[] args) {
// Singleton singleton = new Singleton(); //报错,外部无法实例化对象
Singleton inst = null;
inst = Singleton.getInstance();
inst.print();
}
}
使用抽象类定义一个模板
abstract class Action { // 定义模板
public static final int EAT = 1;
public static final int SLEEP = 3;
public static final int WORK = 5;
public static final int RUN = 7;
public void order(int flag) {
switch (flag) {
case EAT:
this.eat();
break;
case SLEEP:
this.sleep();
break;
case WORK:
this.work();
break;
case RUN:
this.run();
break;
case EAT + SLEEP + RUN:
this.eat();
this.sleep();
this.run();
break;
case EAT + WORK:
this.eat();
this.work();
break;
case EAT + SLEEP + WORK + RUN:
this.eat();
this.sleep();
this.work();
this.run();
break;
}
}
public abstract void eat();
public abstract void sleep();
public abstract void work();
public abstract void run();
}
class Dog extends Action {
@Override
public void eat() {
System.out.println("狗在吃");
}
@Override
public void sleep() {
System.out.println("狗在睡");
}
@Override
public void work() {
}
@Override
public void run() {
System.out.println("狗在跑");
}
}
public class 模板设计模式 {
public static void main(String[] args) {
Action ac1 = new Dog();
ac1.order(Action.EAT + Action.SLEEP + Action.RUN);
}
}
9、工厂设计模式
使用接口实现程序的可移植性
设置过渡端,,降低耦合
interface Fruit {
public void eat();
}
class Apple implements Fruit {
public void eat() {
System.out.println("吃苹果");
}
}
class Orange implements Fruit {
public void eat() {
System.out.println("吃橘子");
}
}
class Factory { // 过渡端
public static Fruit getInstance(String className) {
if (className.equals("apple")) {
return new Apple();
}
if (className.equals("orange")) {
return new Orange();
}
return null;
}
}
public class 工厂设计模式 {
public static void main(String[] args) {
Fruit f = Factory.getInstance("apple");
f.eat();
}
}
10、代理设计模式
是指一个代理主题来操作真实主题。真实主题执行具体的业务操作,而代理主题负责其他相关业务处理
interface Network {
public void browse();
}
class Real implements Network {
public void browse() {
System.out.println("上网浏览信息");
}
}
class Proxy implements Network {
private Network network;
public Proxy(Network network) {
this.network = network;
}
public void check() {
System.out.println("检查用户是否合法");
}
public void browse() {
this.check();
this.network.browse();
}
}
public class 代理设计模式 {
public static void main(String[] args) {
Network net = new Proxy(new Real());
net.browse();
}
}
产生异常,实例化异常对象,(try catch finnally处理)/JVM默认处理,输出异常信息。
都是异常处理中的关键字
throw:用户手工抛出异常类的实例化对象
throws:表示方法不处理异常,而将异常交给程序被调用处处理
进程:程序的一次动态执行过程,经历了程序加载、执行、执行完毕的完整过程,每一个进程至少有两个线程,main和gc
线程:线程是进程的进一步划分,一个进程中有很多线程,线程依附于进程才能够存在,主方法是一个线程
java支持多线程
继承Thread类:覆写run()方法,启动start()方法
实现Runnable接口:避免单继承局限,但仍然需要Thread来启动
同步:多个线程操作同一资源,解决安全性问题,是指多个操作在同一时间段内只能有一个线程进行,其他线程要等待此线程完成后才可以继续执行。
同步代码块和同步方法,synchronized
死锁:两个线程都在等待彼此先完成,造成了程序的停滞状态
解决数据错位
解决数据重复生产和重复取出
class Message {
private String title;
private String content;
private boolean flag = true;
// flag == true:没有数据,可生产,但是不能取出
// flag == false:有数据,可以取出,但是不能生产
public synchronized void set(String title, String content) { // 生产判断
if (this.flag == false) {
try {
super.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.title = title;
this.content = content;
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.content = content;
this.flag = false;
super.notify(); // 可以唤醒wait()
}
public synchronized void get() { // 取出判断
if (this.flag == true) {
try {
super.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(this.title + "-->" + this.content);// 取走数据
this.flag = true;
super.notify();
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public boolean isFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
}
// 生产者
class Producer implements Runnable {
private Message msg = null;
public Producer(Message msg) {
this.msg = msg;
}
@Override
public void run() {
for (int i = 0; i < 50; i++) {
if (i % 2 == 0) {
this.msg.set("标题1", "内容1");
} else {
this.msg.set("标题2", "内容2");
}
}
}
}
// 消费者
class Consumer implements Runnable {
private Message msg = null;
public Consumer(Message msg) {
this.msg = msg;
}
@Override
public void run() {
for (int i = 0; i < 50; i++) {
this.msg.get();
}
}
}
public class 生产者消费者问题 {
public static void main(String[] args) {
Message msg = new Message();
new Thread(new Producer(msg)).start();
new Thread(new Consumer(msg)).start();
}
}
适用于字符串要频繁修改
append():拼接
reverse():反转
replace(int start,int end,String str):替换
insert(int offset,数据):插入
delete(start,end):删除
equals(int[] a,int[] b):相等判断
fill(int[] a,int val):指定内容填充
sort(int[] a):排序
binarySearch(int[] a,int key):二分查找
toString(int[] a):输出数组信息
字节流:直接操作的是数据终端,如文件;
OutputStream output = new FileOutputStream(file, true);// true表示追加数据
InputStream input = new FileInputStream(file);
字符流:操作的是缓冲区,由缓冲区去输出内容,最后需要关闭或者刷新,不然不能真正输出内容到文件;处理中文用字符流会更好
Writer out = new FileWriter(file);
Reader in = new FileReader(file);
BufferReader buf = new BufferReader(new InputStreamReader(System.in));String str = buf.readLine();
Scanner scan = new Scanner(System.in);scan.next();
目的:为保证对象可以以二进制数据的方式进行传输
对象所在类实现java.io.Serializable接口
transient关键字定义的属性不被序列化
ServerSocket server = new ServerSocket(9999);// 开辟监听端口
Socket client = server.accept();// 接收客户端连接,程序进入阻塞状态
PrintStream out = new PrintStream(client.getOutputStream());// 取得指定客户端的输出对象
Socket client = new Socket("localhost", 9999);// 连接服务器和端口
Scanner scan = new Scanner(client.getInputStream());// 取得客户端输入流
1.List
允许重复
List list = new ArrayList();
add(),contains(),remove(),clear()
2.Set
不允许重复
Set set = new HashSet():无序存放
Set<String> set = new TreeSet():有序存放,自动排序
3.Iterator
迭代输出
hasNext():判断是否有下一个值
next():当前元素
remove():移除当前元素
4.Map
保存键值对,key-value,key不允许重复
put(key,value):保存数据
get(key):通过指定的key得到value
keySet():将map中的所有key以集合的方式返回
entrySet():将map变为set集合
实例化:Map<Integer,String> map = new HashMap<Integer,String>();
1.加载JDBC数据库驱动程序
2.建立与指定数据库的连接(Connect)
3.将创建数据库操作对象用于执行SQL语句
4.处理执行结果(ResultSet)
5.释放资源
MVC模式(Model-View-Controller),把软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller)。
模型Model:模型对象封装了应用程序的数据,并定义操控和处理该数据的逻辑和运算。
视图View:视图对象是应用程序中用户可以看见的对象。视图对象知道如何将自己绘制出来,接收用户操作与请求。
控制器Controller:对请求进行处理,负责请求转发;连接Model和view;
显示层(View):主要负责接受Servlet传递的内容,调用JavaBean,将内容显示给用户
控制层(Controller):主要负责所有用户的请求参数,判断请求参数是否合法,根据请求的类型调用JavaBean,将最终的处理结果交给显示层显示!
模型层(Mode):模型层包括了业务层,DAO层。
http是超文本传输协议,信息是明文传输,http的连接很简单,是无状态的;
https则是具有安全性的ssl/tls加密传输协议、身份认证的网络协议,比http协议安全。
用的端口也不一样,前者是80,后者是443。
状态码:
200 - 服务器成功返回网页(表示请求成功)
404 - 请求的网页不存在(可能是网络的问题,也可能是网页没办法访问不代表网页不存在)
503 - 服务器超时(服务器故障)
500 - (服务器内部错误)服务器遇到错误,无法完成请求
对称加密指的就是加密和解密使用同一个秘钥,所以叫做对称加密。对称加密只有一个秘钥,作为私钥。常见的对称加密算法:DES,AES,3DES等等。
非对称加密指的是:加密和解密使用不同的秘钥,一把作为公开的公钥,另一把作为私钥。公钥加密的信息,只有私钥才能解密。私钥加密的信息,只有公钥才能解密。
常见的非对称加密算法:RSA,ECC
对称加密算法相比非对称加密算法来说,加解密的效率要高得多。但是缺陷在于对于秘钥的管理上,以及在非安全信道中通讯时,密钥交换的安全性不能保障。所以在实际的网络环境中,会将两者混合使用.
HashMap 不是线程安全的。hashmap是一个接口,是map接口的子接口,是将键映射到值的对象,其中键和值都是对象,并且不能包含重复键,但可以包含重复值。HashMap允许null key和 null value,而hashtable不允许。
HashTable是线程安全的一个Collection。
HashMap是 Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key) ,由于非线程安全,效率上可能高于Hashtable。HashMap 允许将null作为一个entry的key或者value,而Hashtable不允许
最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多个线程访问Hashtable时,不需要自己为它的方法实现同步,而 HashMap就必须为之提供外同步。
多线程有两种实现方法,分别是继承Thread类与实现Runnable接口
同步的实现方面有两种,一种同步方法,一种同步代码!分别是synchronized;
notify
wait():使一个线程处于等待状态,并且释放所持有的对象的lock。
sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉InterruptedException异常。
notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不
千不育有角白JpE
某一个等待状态的线程,而是由JⅣM确定唤醒哪个线程,而且不是按优先级
Allnotity():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争
StringBuffer和 StringBuilder类都表示内容可以被修改的字符串,StringBuilder是线程不安全的,运行效率高,如果一个字符串变量是在方法里面定义,这种情况只可能有一个线程访问它,不存在不安全的因素了,则用stringBuilder。如果要在类里面定义成员变量,并且这个类的实例对象会在多线程环境下使用,那么最好用stringBuffer。
TCP(Transmission Control Protocol,传输控制协议)是面向连接的协议,也就是说,在收发数据前,必须和对方建立可靠的连接。 一个TCP连接必须要经过三次“对话”才能建立起来TCP建立连接要进行3次握手,而断开连接要进行4次
UDP(User Data Protocol,用户数据报协议)
1、UDP是一个非连接的协议,传输数据之前源端和终端不建立连接, 当它想传送时就简单地去抓取来自应用程序的数据,并尽可能快地把它扔到网络上。 在发送端,UDP传送数据的速度仅仅是受应用程序生成数据的速度、 计算机的能力和传输带宽的限制; 在接收端,UDP把每个消息段放在队列中,应用程序每次从队列中读一个消息段。
面向对象是向现实世界模型的自然延伸,这是一种“万物皆对象”的编程思想。在现实生活中的任何物体都可以归为一类事物,而每一个个体都是一类事物的实例。面向对象的编程是以对象为中心,以消息为驱动,所以程序=对象+消息。(对象+方法调用)
面向对象有三大特性,封装、继承和多态。
equals用来判断两个对象是否相等,hashCode用来在比较对象的是有减少equals的调用次数,因为hashCode不相等,那么肯定就不相等,不用去调用equals,如果equals相等,hashcode一定相等
1、equals方法用于比较对象的内容是否相等(覆盖以后)
2、hashcode方法只有在集合中用到
1、Integer是int的包装类,int则是java的一种基本数据类型
2、Integer变量必须实例化后才能使用,而int变量不需要
3、Integer实际是对象的引用,当new一个Integer时,实际上是生成一个指针指向此对象;而int则是直接存储数据值
4、Integer的默认值是null,int的默认值是0
所具有的特性有 ( 原子性 )( 一致性 )( 隔离性 )( 持久性 )
1)、原子性(Atomic),指事务包含的所有操作要么全部执行,要么全部失败回滚,要么全做,要么全都不做。
2)、一致性(Consistency),事务应确保数据库的状态从一个一致状态转变为另外一个一致的状态,一致的状态时指数据库中的数据应该满足完整性约束,例如转账,A用户和B用户两者的钱加起来是2k,A用户和B用户进行转账,不论怎么进行转账,最后A用户和B用户的钱加到一起还是2k。
3)、隔离性(Isolation),隔离性是多个事务并发执行的时候,一个事务的执行不应该其它事务的执行,重点掌握。
4)、持久性(Durability),一个事务一旦提交,数据库的修改应该永久保存到数据库中,持久性意味着当系统发生故障的时候,确保已提交事务的更新不能丢失,即对已提交事务的更新能恢复,一旦一个事务b被提交,DBMS必须保证提供适当的冗余,使其耐得住系统的故障,所以持久性主要在于DBMS的恢复性能。
E-R 模型的组成包括那些元素 ( 实体 )( 属性 )( 关系 )
1、 innoDB
优点: 支持事务管理,崩溃修复能力和并发控制,支持自动增长列,支持外键;
缺点: 读写效率较差,占用数据空间大;
应用场景:适合于对事务完整性要求高,要求并发控制,需要频繁更新,删除等操作的数据 库;
2、MyISAM
优点: 占用空间小,处理速度快;
缺点: 不支持事务的完整性和并发性;
应用场景:适用于表主要用于插入新纪录和读出记录,对应用完整性和并发性要求低;
3、MEMORY 存储引擎
优点: 处理速度快;
缺点: 数据易丢失,生命周期短;
应用场景: 适用于读写速度快,对数据安全性要求低,使用相对较小的数据库表;
CHAR :存储定长数据
VARCHAR :存储变长数据
NVARCHAR :存储变长数据 , Unicode 编码,支持多语言
设计关系数据库时, 遵从不同的规范要求, 设计出合理的关系型数据库, 这些不同的规 范要求被称为不同的范式,各种范式呈递次规范,越高的范式数据库冗余越小
第一范式( 1NF )实体中的某个属性有多个值时,必须拆分为不同的属性
第二范式( 2NF )要求数据库表中的每个实例或记录必须可以被唯一地区分
第三范式( 3NF )要求一个关系中不包含已在其它关系已包含的非主关键字信息
设教学数据库 Education 有三个关系:
学生关系 S(SNO ,SNAME ,AGE,SEX,SDEPT);
学习关系 SC(SNO,CNO , GRADE);
课程关系 C(CNO ,CNAME ,CDEPT,TNAME )
(1)、检索计算机系的全体学生的学号,姓名和性别
SELECT Sno ,Sname ,Sex FROM S WHERE Sdept = ’CS’;
(2)、检索学习课程号为 C2 的学生学号与姓名;
SELECT Sno ,Sname FROM S
WHERE Sno IN ( SELECT Sno FROM SC WHERE Cno= ‘C2’)
(3)、检索选修课程名为“ DS”的学生学号与姓名
Select sno,sname fron s where sno in (select sno from sc where cno in (select cname from c where cname=’ds’))
(4)、检索选修课程号为 C2 或 C4 的学生学号;
SELECT Sno FROM SC X,SC Y
WHERE X.Sno=Y.Sno AND X.Cno= ‘C2 ’ AND Y.Cno= ‘C4’ ;
(5)、检索不学 C2 课的学生姓名和年龄;
SELECT Sname,age FROM S WHERE Sno NOT IN ( SELECT Sno FROM SC WHERE Cno= ‘C2 ’);
SELECT Sname,age FROM S WHERE NOT EXISTS ( SELECT * FROM SC WHERE SC.Sno=S.Sno AND Cno= ‘C2’);
(6)、检索学习全部课程的学生姓名;
SELECT Sname FROM S WHERE NOT EXISTS (SELECT * FROM C where not exists /*该学生没有学*/
(select * from sc where sc.s#=s.s# and sc.c#=c.c#));
需求分析、概念设计、逻辑设计、物理设计
为什么要使用索引?
答:如果进行全表扫描,将整个数据表的数据全部或者分批次加载到内存当中,存储的最小单位是块或者页,它们是由多行数据来组成的,将这些块都加载进来,逐个块去轮询,找到我们要的目标并返回,这种方式非常的慢,但是如果数据量小的话,这种方式也非常快的。如果数据量过大,就要避免全表扫描的情况发生,此时就要引入索引了,索引可以快速查询数据,避免全表扫描查找数据,提升检索效率。
什么样的信息能称为索引?
答:可以将记录限制到一定范围内的字段,主键是一个很好的数据切入点,包含主键、唯一键以及普通键等等。主键、唯一键等,只要是能让数据具备一定区分性的字段都可以成为索引。
更新丢失lost update、脏读dirty read、不可重复读non repeatable read、幻读Phantom read
共享锁:(读取)操作创建的锁。其他用户可以并发读取数据,但任何事物都不能获取数据上的排它锁,直到已释放所有共享锁。
排他锁(X锁):对数据A加上排他锁后,则其他事务不能再对A加任任何类型的封锁。获准排他锁的事务既能读数据,又能修改数据。
Avg() Count() Max() Min() Sum()
Group By():
GROUP BY 语句用于结合聚合函数,根据一个或多个列对结果集进行分组。
HAVING 子句可以让我们筛选分组后的各组数据。
悲观锁的特点是先获取锁,再进行业务操作,即“悲观”的认为获取锁是非常有可能失败的,因此要先确保获取锁成功再进行业务操作。通常所说的“一锁二查三更新”即指的是使用悲观锁。通常来讲在数据库上的悲观锁需要数据库本身提供支持,即通过常用的select … for update操作来实现悲观锁。当数据库执行select for update时会获取被select中的数据行的行锁,因此其他并发执行的select for update如果试图选中同一行则会发生排斥(需要等待行锁被释放),因此达到锁的效果。select for update获取的行锁会在当前事务结束时自动释放,因此必须在事务中使用。
乐观锁,也叫乐观并发控制,它假设多用户并发的事务在处理时不会彼此互相影响,各事务能够在不产生锁的情况下处理各自影响的那部分数据。在提交数据更新之前,每个事务会先检查在该事务读取数据后,有没有其他事务又修改了该数据。如果其他事务有更新的话,那么当前正在提交的事务会进行回滚。
客户端通过传递start(页码),limit(每页显示的条数)两个参数去分页查询数据库表中的数据,那我们知道MySql数据库提供了分页的函数limit m,n,但是该函数的用法和我们的需求不一样,所以就需要我们根据实际情况去改写适合我们自己的分页语句
分页sql格式是:
select * from table limit (start-1)*limit,limit;
其中start是页码,limit是每页显示的条数。
include指令是静态包含。静态包含的意思就是:把文件的代码内容都包含进来再编译
动态包含可以向被包含的页面传递参数(用处不大),并且是分别处理被包含页面的(将被包含页面编译后得出的结果再写进包含页面)【如果有相同名称的参数,使用静态包含就会报错!】
pageContext是内置对象中最重要的一个对象,它代表着JSP页面编译后的内容(也就是JSP页面的运行环境),pageContext本质上代表的是当前JSP页面编译后的内容,作为域对象而言,它就代表着当前JSP页面(也就是page)也就是说: pageContext域对象只在page范围内有效,超出了page范围就无效了!
out对象用于向浏览器输出数据,与之对应的是Servlet的PrintWriter对象。然而这个out对象的类型并不是PrintWriter,是JspWriter
内置对象page是HttpJasPage对象,其实page对象代表的就是当前JSP页面,是当前JSP编译后的Servlet类的对象。也就是说:page对象相当于普通java类的this
内置对象exception是java.lang.Exception类的对象,exception封装了JSP页面抛出的异常信息。exception经常被用来处理错误页面
request 用户端请求,此请求会包含来自GET/POST请求的参数
response 网页传回用户端的回应
session 与请求有关的会话期
application servlet 正在执行的内容
config servlet的构架部件
JSP是Servlet技术的扩展,本质上就是Servlet的简易方式。JSP编译后是“类servlet”。
Servlet和JSP最主要的不同点在于:Servlet的应用逻辑是在Java文件中,并且完全从表示层中的HTML里分离开来。而JSP的情况是Java和HTML可以组合成一个扩展名为.jsp的文件。
JSP侧重于视图,Servlet主要用于控制逻辑。
<c:if>,<c:item>,<c:foreach>,<c:out>,<c:set>
当客户端向一个jsp页面发送请求时,Web Container将jsp转化成servlet的源代码(只在第一次请求时),然后编译转化后的servlet并加载到内存中执行,执行的结果response到客户端
jsp只在第一次执行的时候会转化成servlet,以后每次执行,web容器都是直接执行编译后的servlet,所以jsp和servlet只是在第一次执行的时候不一样,jsp慢一点,以后的执行都是相同的
Servlet处于服务器进程中,只会有**一个servlet实例,**每个请求都会产生一个新的线程,而且servlet实例一般不会销毁
CGI:来一个请求就创建一个进程,用完就销毁,效率低于servlet
DAO(Data Access Object):主要对数据的操作,增加、修改、删除等原子性操作。
Web层:界面+控制器,也就是说JSP【界面】+Servlet【控制器】
Service业务层:将多个原子性的DAO操作进行组合,组合成一个完整的业务逻辑
控制层:主要使用Servlet进行控制
数据访问层:使用DAO、Hibernate、JDBC技术实现对数据的增删改查
JavaBean用于封装数据,处理部分核心逻辑,每一层中都用到
1.数据长度:get长度比较小;post则没有长度限制
2.数据传递方式:get使用URL传递参数值;post直接将参数值放入request body中打包传递
3.数据传递安全性:get的传递方式并不安全;而post相对安全。原因是在传递参数的时候,get会将其参数显示在地址栏通过url地址请求,但是post通过将参数放入request body中传递所以相对安全。
4.发送的数据包数量:get在传递是发送1个TCP数据包;post则发送2个数据包(①首先发送一个请求头request head,为一个数据包,②随后服务器接收请求头后返回100成功状态码,③再将第二个数据包request body发送)
以上这是get请求与post请求的区别。
1.跳转执行的对象:首先重定向是客户端浏览器执行跳转 ;请求转发是服务器端直接进行跳转,与客户端无关。
2.地址栏的地址:重定向之后客户端浏览器地址栏显示的是新请求的地址;而请求转发后,客户端浏览器地址栏显示的是之前原来的地址不会改变。
3.传值过程:
①对于重定向来说,它是客户端的一次新的请求,那么其中请求request中的值也会刷新,在调用request对象拿值的时候就不能使用重定向,因为无法拿到原来的值;
②对于请求转发来说,它则是服务器的一次跳转,在servlet中调用request对象的getRequestDispatcher()方法定义好要跳转的地址,再调用其forward()方法跳转,全程都是同一个客户端发送的请求request,所以在参数传递的时候就可以正常的拿到原有的request中携带的值。
Servlet的生命周期从Web加载Servlet开始,通过调用Servlet的init()方法进行Servlet的初始化,通过调用service()方法处理请求,根据不同的请求调用不同的方法(doget(),dopost())。服务结束,Web容器调用Servlet的destroy()方法。
·jsp:include:在页面被请求的时候引入一个静态或动态的文件。
·jsp:useBean:寻求或者实例化一个JavaBean。
·jsp:setProperty:设置JavaBean的属性。
·jsp:getProperty:获取某个JavaBean的属性。
·jsp:forward:把请求转到一个新的页面(html文件、jsp文件或者一个程序段)。
·jsp:plugin:根据浏览器类型为Java插件生成object或embed标记。
存储位置:Cookie存在浏览器,Session存储在服务器
安全角度:cookie不安全,session安全
数据量:cookie不可以存大数据,session可以存大数据,重要数据等.
Cookie来跟踪会话,由于HTTP是一种无状态的协议,服务器单从网络连接上无从知道客户身份。怎么办呢?就给客户端们颁发一个通行证吧,每人一个,无论谁访问都必须携带自己通行证。这样服务器就能从通行证上确认客户身份了。这就是Cookie的工作原理。
Cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。
查看某个网站颁发的Cookie很简单。在浏览器地址栏输入**javascript:alert (document. cookie)**就可以了(需要有网才能查看)
Session是服务器端使用的一种记录客户端状态的机制,使用上比Cookie简单一些,相应的也增加了服务器的存储压力。Session保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是Session。客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了。Session机制就是通过检查服务器上的“客户明细表”来确认客户身份。Session相当于程序在服务器上建立的一份客户档案,客户来访的时候只需要查询客户档案表就可以了。Session对象是在客户端第一次请求服务器的时候创建的。Session也是一种key-value的属性对,通过getAttribute(Stringkey)和setAttribute(String key,Objectvalue)方法读写客户状态信息。Servlet里通过request.getSession()方法获取该客户的Session
关机会造成session生命周期的结束,但是对cookie没有影响
cookie可以被多个同类型的浏览器共享可以把cookie想象成一张表
struts是一个按MVC模式设计的Web层框架,其实它就是一个大大的servlet,这个Servlet名为ActionServlet,或是ActionServlet的子类。我们可以在web.xml文件中将符合某种特征的所有请求交给这个Servlet处理,这个Servlet再参照一个配置文件(通常为/WEB-INF/struts-config.xml)将各个请求分别分配给不同的action去处理。
1、客户端初始化一个指向Servlet容器(例如Tomcat)的请求;
2、这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,这个过滤器对于Struts2和其他框架的集成很有帮助,例如:SiteMesh Plugin);
3、接着FilterDispatcher被调用,FilterDispatcher询问ActionMapper来决定这个请求是否需要调用某个Action;
4、如果ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy;
5、ActionProxy通过ConfigurationManager询问框架的配置文件,找到需要调用的Action类;
6、ActionProxy创建一个ActionInvocation的实例。
7、ActionInvocation实例使用命名模式来调用,在调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用。
8、一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果通常是(但不总是,也可能是另外的一个Action链)一个需要被表示的JSP或者FreeMarker的模版。在表示的过程中可以使用Struts2框架中继承的标签。在这个过程中需要涉及到ActionMapper。
1、加载类(FilterDispatcher)
2、读取配置(struts配置文件中的Action)
3、派发请求(客户端发送请求)
4、调用Action(FilterDispatcher从struts配置文件中读取与之相对应的Action)
5、启用拦截器(WebWork拦截器链自动对请求应用通用功能,如验证)
6、处理业务(回调Action的execute()方法)
7、返回响应(通过execute方法将信息返回到FilterDispatcher)
8、查找响应(FilterDispatcher根据配置查找响应的是什么信息如:SUCCESS、ERROR,将跳转到哪个jsp页面)
9、响应用户(jsp--->客户浏览器端显示)
ActionServlet继承自javax.servlet.http.HttpServlet类,其在Strutsframework中扮演的角色是中心控制器。它提供一个中心位置来处理全部的终端请求。控制器ActionServlet主要负责将HTTP的客户请求信息组装后,根据配置文件的指定描述,转发到适当的处理器。
待完成
spring是一个集成了许多第三方框架,其核心技术是IOC(控制反转,也称依赖注入)和AOP(面向切面编程)
Spring实现了工厂模式的工厂类(在这里有必要解释清楚什么是工厂模式),这个类名为BeanFactory(实际上是一个接口),在程序中通常BeanFactory的子类ApplicationContext。Spring相当于一个大的工厂类,在其配置文件中通过<bean>元素配置用于创建实例对象的类名和实例对象的属性。
Spring提供了对IOC(控制反转)良好支持,IOC是一种编程思想,是一种架构艺术,利用这种思想可以很好地实现模块之间的解耦
Spring提供了对AOP技术的良好封装, AOP称为面向切面编程,就是系统中有很多各不相干的类的方法,在这些众多方法中要加入某种系统功能的代码,例如,加入日志,加入权限判断,加入异常处理,这种应用称为AOP。实现AOP功能采用的是代理技术,客户端程序不再调用目标,而调用代理类,代理类与目标类对外具有相同的方法声明,有两种方式可以实现相同的方法声明,一是实现相同的接口,二是作为目标的子类在,JDK中采用Proxy类产生动态代理的方式为某个接口生成实现类
beanfactory(容器),applicationContext(应用上下文)
1.通知(Advice):通知定义了切面是什么以及何时使用。描述了切面要完成的工作和何时需要执行这个工作。
2.连接点(Joinpoint):程序能够应用通知的一个“时机”,这些“时机”就是连接点,例如方法被调用时、异常被抛出时等等。
3.切入点(Pointcut)通知定义了切面要发生的“故事”和时间,那么切入点就定义了“故事”发生的地点,例如某个类或方法的名称,Spring中允许我们方便的用正则表达式来指定
4.切面(Aspect)通知和切入点共同组成了切面:时间、地点和要发生的“故事”
5.引入(Introduction)引入允许我们向现有的类添加新的方法和属性(Spring提供了一个方法注入的功能)
6.目标(Target)即被通知的对象,如果没有AOP,那么它的逻辑将要交叉别的事务逻辑,有了AOP之后它可以只关注自己要做的事(AOP让他做爱做的事)
7.代理(proxy)应用通知的对象,详细内容参见设计模式里面的代理模式
8.织入(Weaving)把切面应用到目标对象来创建新的代理对象的过程
有setter注入(即类中设置一个全局属性,并对属性有setter方法,以供容器注入),接口注入和 构造器注入
singleton(单例) ,prototype(原型) ,request,session,globalsession
1.读取并解析配置文件
2.读取并解析映射信息,创建SessionFactory
3.打开Session
4.创建事务Transation
5.持久化操作
6.提交事务
7.关闭Session
8.关闭SesstionFactory
Hibernate对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码
简化DAO层的编码工作hibernate的性能非常好,因为它是个轻量级框架。映射的灵活性很出色。它支持各种关系数据库,从一对一到多对多的各种复杂关系。
瞬时态(Transient)、持久态(Persistent)、脱管态(Detached)。
1.瞬时对象在内存孤立存在,它是携带信息的载体,不和数据库的数据有任何关联关系,在Hibernate中,可通过session的save()或saveOrUpdate()方法将瞬时对象与数据库相关联,并将数据对应的插入数据库中,此时该瞬时对象转变成持久化对象。
2.持久对象具有如下特点: 1. 和session实例关联; 2. 在数据库中有与之关联的记录。 3. 比瞬时对象多了一个数据库记录标识值。
3.托管态,也叫游离态等,持久化对象脱离了Session的对象。如Session缓存被清空的对象。特点:已经持久化,但不在Session缓存中。处于此状态的对象叫游离对象。
延迟加载机制是为了避免一些无谓的性能开销而提出来的,所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作。在Hibernate中提供了对实体对象的延迟加载以及对集合的延迟加载,另外在Hibernate3中还提供了对属性的延迟加载。
struts 在 SSH 框架中起控制的作用 , 其核心是 (控制器)Controller, 即ActionServlet, 而 ActionServlet 的核心就是 Struts-config.xml. 主要控制逻辑关系的处理 .
hibernate 是数据持久化层 , 是一种新的对象、关系的映射工具 , 提供了从 Java 类到数据表的映射,也提供了数据查询和恢复等机制 , 大大减少数据访问的复杂度。把对数据库的直接操作 , 转换为对持久对象的操作 .
spring 是一个轻量级的控制反转 (IoC) 和面向切面 (AOP) 的容器框架 , 面向接口的编程 , 由容器控制程序之间的(依赖)关系,而非传统实现中,由程序代码直接操控。这也就是所谓“ 控制反转 ” 的概念所在:(依赖)控制权由应用代码中转到了外部容器,控制权的转移,是所谓反转。依赖注入,即组件之间的依赖关系由容器在运行期决定,形象的来说,即由容器动态的将某种依赖关系注入到组件之中 起到的主要作用是解耦
Spring是一个以IoC和AOP为内核的框架。 IoC(Inversion of Control ,控制反转)是Spring的基础。
IoC简单说就是创建对象由以前的程序员调用new 构造方法,变成了交由Spring创建对象。 把各个对象类封装之后,通过IoC容器来关联这些对象类。这样对象与对象之间就通过IoC容器进行联系,而对象与对象之间没有什么直接联系。
DI(Dependency Inject,依赖注入)与IoC的含义相同,只不过这两个称呼是从两个角度描述的同一个概念。简单地说, DI就是对象的属性,已经被注入好相关值了,直接使用即可。由IoC容器在运行期间,动态地将某种依赖关系注入到对象之中。例如,将对象B注入(赋值)给对象A的成员变量。
AOP的全称是 Aspect-Oriented Programming,即面向切面编程(也称面向方面编程,它是面向对象编程(OOP)的一种补充,目前已成为一种比较成熟的编程方式。
AOP采取横向抽取机制,将分散在各个方法中的重复代码提取出来,然后在程序编译或运行时,再将这些提取出来的代码应用到需要执行的地方。虽然AOP是一种新的编程思想,但却不是OOP的替代品,它只是OOP的延伸和补充。
SpringBoot是用来简化Spring框架应用初始化搭建以及开发的全新框架,比如通过自动化配置省去了大量繁琐的配置文件。
快速创建独立运行的Spring项目与主流框架集成;
使用嵌入式的servlet容器,应用无需打包成war包;
starters自动依赖与版本控制
大量的自动配置,简化开发,也可修改默认值
准生产环境的运行应用监控
与云计算的天然集成、
内部嵌入了tomcat,可以自动配置spring,为程序员减少大量时间用于写业务逻辑,更不用担心使用某个依赖的版本问题
Spring Boot的核心配置文件是application和bootstrap配置文件。
application配置文件主要用于Spring Boot项目的自动化配置;
bootstrap配置文件有以下几个应用场景:
使用Spring Cloud
Config配置中心时,可在bootstrap配置文件中增加连接到配置中心的配置属性来加载外部配置中心的配置信息;
少量固定的不能被覆盖的属性;
少量加密/解密的场景;
Spring Boot的核心注解是@SpringBootApplication,它主要包含了以下3个注解:
@SpringBootConfiguration:组合了@Configuration注解,实现配置文件的功能。
@EnableAutoConfiguration:打开自动配置的功能,也可以关闭某个自动配置的选项,比如关闭数据源自动配置功能@SpringBootApplication(exclude
= {DataSourceAutoConfiguration.class})。
@ComponentScan:Spring组件扫描。
Spring Boot实现分页有两种方式,一种是通过Spring Data JPA将实现分页的org.springframework.data.domain.Pageable的实现类传给存储库的方法。另一种方法是pringboot+Mybatis+PageHelper 实现分页、排序。
@SpringBootApplication:该注解是springboot最核心注解,也是组合注解,声明它就可以让springboot自动给程序进行必要的配置(简单的说,开启组件扫描和自己配置的功能)。
@EnableAutoCfiguration:使用该注解作用就是告诉springboot根据添加jar依赖猜测你想如何配置spring。
@ComponentScan:组件扫描,自动扫面包。并把这些类注册为Bean。
@SpringBootConfiguration:是标志当前的类的配置类。
@Configuration:定义配置类,可以替换xml文件,如果被注解的类内部包含有一个或者多个被@Bean注解的方法。
@Autowired:使用该注解作用就是进行自动注入
@Controller:该注解用于定义控制器,在spring项目中是由控制器负责用户发来的请求,然后控制器将用户请求的URL转发到对应的接口service层,进行调用相应的业务,在使用该注解时,还用结合@RequestMapping一起使用,处理http请求。
@ResponseBody:使用该注解表示方法的返回结果直接写入HTTP response body中的,当我们异步请求的时候常使用,用于构建restful的API
@Repository:该注解用于标注数据访问组件,DAO组件的。
@service:该注解使用于标注业务层,当在业务层的类上使用时,bean就是自动找到该类就是service的。
@PequestParam注解:是指获取请求参数的值,
@GetMapping是组合注解。
Spring MVC是Spring提供的一个轻量级Web框架,它实现了 Web MVC设计模式。Spring MVC在使用和性能等方面比另外一个框架Struts2更加优异。
Spring MVC具有的特点:
可以方便地利用Spring所提供的其它功能;
灵活性强,易于与其他框架集成;
DispatcherServlet的全名是org. springframework. web. servlet.DispatcherServlet,它在程序中充当着前端控制器的角色。在使用时,只需将其配置在项目的 web.xml文件中。
org.springframework.stereotype.Controller注解类型用于指示Spring类的实例是一个控制器,其注解形式为@Controller。该注解在使用时不需要再实现 Controller接口,只需要将@ Controller注解加入到控制器类上,然后通过 Spring的扫描机制找到标注了该注解的控制器即可。
@RequestMapping注解的使用Spring通过@Controller注解找到相应的控制器类后,还需要知道控制器内部对每一个请求是如何处理的,这就需要使用org.springframework.web.bind.annotation.RequestMapping注解类型。
具体步骤:
首先用户发送请求到前端控制器,前端控制器根据请求信息(如 URL)来决定选择哪一个页面控制器进行处理并把请求委托给它,即以前的控制器的控制逻辑部分;
页面控制器接收到请求后,进行功能处理,首先需要收集和绑定请求参数到一个对象,这个对象在 Spring Web MVC 中叫命令对象,并进行验证,然后将命令对象委托给业务对象进行处理;处理完毕后返回一个 ModelAndView(模型数据和逻辑视图名);
前端控制器收回控制权,然后根据返回的逻辑视图名,选择相应的视图进行渲染,并把模型数据传入以便视图渲染;
前端控制器再次收回控制权,将响应返回给用户
评论