-------------------------------------servlet---------------------------------------------------------
Servlet是web服务器的补充,需要用相应的运行环境,如tomcat(容器)
servlet的生命周期
实例化 初始化init 调用service 销毁destroy
servlet线程不安全,如果两个用户同时访问同一个Servlet,可能发生线程安全问题
解决方法,加锁,避免使用共享变量
web容器模型
private ServerSocket server;
private ExecutorService threadpool;
public WebServer() throws Exception{
try {
server=new ServerSocket(8088);
threadpool=Executors.newFixedThreadPool(100);
} catch (Exception e) {throw e;}
}
public void start(){
try {
while(true){
Socket socket=server.accept();//等待连接
ClientHandle handler=new ClientHandle(socket);
threadpool.execute(handler);
}
} catch (Exception e) {
e.printStackTrace();
}
}
线程类
private Socket socket;
public ClientHandle(Socket socket) {
this.socket=socket;
}
public void run() {
try {
InputStream in=socket.getInputStream();
OutputStream out=socket.getOutputStream();
}
servlet 是扩展web服务器开发的一套组件规范,用于展示动态的html页面,相对于早时期的CGI,
CGI开发复杂,性能较差,用进程处理每一个请求,而Servlet开发简单,用线程来处理请求,
打打提高了效率
开发一个Servlet
import javax.servlet.http.HttpServlet
public class someServlet extends HttpServlet{
protected void service(HttpServletRequest request,HttpServletResponse response)
throws ServletException,IOException(){
String uri=request.getRequestURI()获得请求地址;
uri=uri.substring(uri.lastIndexOf("/"),uri.lastIndexOf("."));
HttpSession session=request.getSession();
request.getParameter(username);标签中有name属性
PrintWriter out=request.getWriter();
request.getRequestDispatcher("/reg.jsp").forward(request, response);转发
response.sendRedirect(request.getContextPath()+"/login.jsp");重定向
转发和重定向的主要区别在于,转发没有发送新的请求,共享request和response对象
而重定向发送新的请求,并生成新的request和response对象
response.setContentType(“text/html;charset=UTF-8”);
设置容器out.println时使用的字符集
通知浏览器以content-type消息头,页面的字符编码
如何处理表单中文提交,服务器默认使用iso-8859-1解码
01.request.setCharacterEncoding("utf-8");只对post请求有作用
String username = request.getParameter(“username”);
username = new String(username.getBytes(“iso-8859-1”),“UTF-8”);针对get请求
ServletContent Servlet上下文HttpSession提供的 getServletContext()
servlet的全局变量,生命周期与应用程序xiangtong
}
}
Jsp内置对象
request response session application out pagecontext config page exception
pageContext、request、session、application的getAttribute()方法
JSp指令
page指令
import属性:指定要导入的包,比如<%@ page import="java.util.*,java.text.*"%>
contentType属性:设置response.setContentType方法的 参数值。
pageEncoding属性:告诉容器,在读取jsp文件的内容时使用指定的字符集来解码。
include指令
taglib指令 <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
JSTL
核心标签
if
<c:if test="${user.gender =='m'}" var="rs" scope="request">男</c:if>
choose
<c:choose>
<c:when test="${user.gender == 'm'}">男</c:when>
<c:when test="${user.gender =='f'}">女</c:when>
<c:otherwise>未知</c:otherwise>
</c:choose>
foreach
<c:forEach items="${users}" var="u" varStatus="s">
<tr>
<td>${s.count}</td>
<td>${u.name}</td>
<td>${u.age}</td>
</tr>
</c:forEach>
-------------------------------------springMVC执行过程------------------------------------------------------
Tomcat启动时,根据(web.xml文件)会立将DispatcherServlet实例化和初始化(启动Srping容器)
初始化时根据
<param-name>ContextConfigLocation</param-name>
<param-value>classpath:spring.xml</param-value>
找到spring容器的配置文件
1. 服务器接受到一个请求
2.DispatcherServlet根据 HandlerMapping 配置的信息找到对应的Controller(模型)
简化后,无需配置HandlerMapping,由Controller中的@RequestMapping注解代替
需要在spring的配置文件中开启 mvc注解扫描
<mvc:annotation-driven />
3.Controller(处理器)一系列处理之后,返回ModelAndView(处理结果)给DispatcherServlet
4.DispatcherServlet根据ViewResolver(视图解析器)找到对应的jsp文件,发送给浏览器
------------------------------cookie 和 Session的区别--------------------------------------------------------
cookie 服务器为了识别用户身份而临时存放在浏览器端的少量数据。
浏览器访问服务器时,服务器将一些数据以set-cookie消息头
的形式发送给浏览器,浏览器会将这些数据临时保存下来;
当浏览器再次访问服务器时,会将这些数据以cookie消息头的
形式发送给服务器。
session 服务器端为了保存状态而创建的一个特殊的对象。
浏览器访问服务器时,服务器创建一个特殊对象session(
该对象有一个唯一的id,称之为sessionId),服务器会将
sessionId以cookie的形式发送给浏览器;
当浏览器再次访问服务器时,会将sessionId发送过来,
服务器端可以利用这个session找到对应的session对象。
可以修改web.xml配置,设置超时时间限制。默认时间一般是30分钟
<session-config>
<session-timeout>30</session-timeout>
</session-config>
c.setMaxInactiveInterval(int seconds)
----------------------------------------集合框架------------------------------------------------------------
(Java中的容器)专门存放其他类的对象,就叫做容器,或者叫做集合
如何设计一个线程安全的数组
原则上不应该把数组暴露出去让线程随意修改,应该将数组封装成为一个bean,或者说封装成一个类
然后针对这个数组的操作都由这个类完成
-----------------------------------------aop------------------------------------------------------------------
直接硬编码(在原有业务方法中直接添加扩展业务)
缺点:1.缺少封装的概念
2.违背OCP原则(开闭原则,对扩展开放,对修改关闭)
3.代码量大
扩展新的业务类,在此业务类中整合核心业务,扩展业务
在软件编程中将这种模式称为代理模式
客户端通过代理对象取执行目标对象的业务实现,这种方式我们称为代理模式
代理模式中的核心角色
抽象对象(接口)
目标对象(封装了核心业务)
代理对象(可以访问目标对象,添加扩展业务)
备注:目标对象与代理对象实现共同的接口
代理模式解决了什么问题:
解决了OCP(保护目标对象)
在不改变原有代码的基础上添加扩展功能
代理模式类型:
静态代理(基于某个接口自己写代理类)
动态代理(由系统创建代理类对象,一般借助于JDK,或CGLIB)
程序在运行时创建了代理类,创建代理对象,这个过程是一个动态的过程,所以称为动态代理
通过动态代理为核心业务对象添加扩展业务
动态代理可以为任何实现了接口的对象创建代理对象
代理类由谁创建?JDK底层
代理对象由谁创建?JDK底层
1.基于JDK的动态代理只能为实现了接口的对象创建代理对象(实现InvocationHandler接口)
2.基于CGLIB的动态代理可以为所有类创建动态代理
Spring IOC(控制反转)
Spring bean工厂(负责创建对象)
Spring bean容器(负责存储对象,底层是一个Map)
Spring bean DI(依赖注入,建立对象之间的关联)
public class DyServiceProxy {
/**业务处理对象*/
static class ServiceHandler implements InvocationHandler{
private Object target;/**目标对象*/
private TransactionAspect tx;/**封装了扩展业务的一个对象*/
public ServiceHandler(Object target,TransactionAspect tx) {
this.target=target;
this.tx=tx;
}
/**
* @param proxy 指向代理对象
* @param method 指向接口中的方法对象
* @param args 方法对象中参数
*/
@Override
public Object invoke(Object proxy,
Method method,
Object[] args) throws Throwable {
if(!method.isAnnotationPresent(Transaction.class)){
return method.invoke(target, args);
}else{
tx.beginTransaction();//事务开启
Object result=method.invoke(target, args);//业务执行(核心业务)
tx.endTransaction();//事务提交
return result;
}
}
}
public static void main(String[] args) {
TeamServiceImpl target=new TeamServiceImpl();//1.创建目标对象
//2.创建代理对象(为目标对象创建代理对象)
TeamService proxy=(TeamService)
Proxy.newProxyInstance(
target.getClass().getClassLoader(),//loader
target.getClass().getInterfaces(),//interfaces
new ServiceHandler(target,
new TransactionAspect()));//handler(处理器)
//3.执行业务(由代理去执行目标对象的具体业务)
proxy.saveObject();
proxy.updateObject();
//说明:当执行代理对象的saveObject方法时,底层会自动
//调用ServiceHandler对象的invoke方法
}
}
OOP面向对象编程(静态过程)
AOP面向切面编程(动态过程)
Spring AOP的应用场景?在不改变原有核心代码基础上扩展新的功能
日志处理
缓存应用
权限处理
事务处理:事务是一个不可分割的逻辑单元(转账,存钱)
原子性:事务中的多个操作,要么都执行,要么都不执行
一致性:事务前后数据状态一致
隔离性:多个事务并发执行,应该是相互隔离的
持久 性:事务一旦提交或回滚,事务状态将会持久性的发生变化
多事务并发执行可能导致什么问题:
1.脏读(读取了别人未提交的数据)
2.不可重复读(一个事务中多次读取的数据结果不一致)
3.幻影读(幻读)(修改了本事务看不到数据)解决方案:事务的隔离级别Serializable
中的隔离级别有如下几种方式:
1)READ_UNCOMMITTED (此级别可能会出现脏读)
2)READ_COMMITTED(此级别可能会出现不可重复读)
3)REPEATABLE_READ(此级别可能会出现幻读)
4)SERIALIZABLE(多事务串行执行)
说明:事务的隔离级别越高,并发性就会越差.
丢失更新:(一个事务修改了数据,令一个shi)如何解决,加锁
排他锁:(悲观锁,行锁)
start transaction;
select * from book where id=1 for update;
Spring中事务控制有两种实现
1编程式事务(基本不用)
try{
Connection conn=DbUtil.getConnection;
conn.setAutoCommit(false);
dao.updateObject(...);
conn.commit();
}catch{
conn.rollback();
}
2.声明式事务
将编程事务的那部分代码交给Spring底层实现,然后通过AOP机制将事务控制代码植入到业务层
声明式事务处理有两种方式:
1.基于XML
2. 基于注解(重点掌握)比较灵活
@Transactional注解
@Transactional(roolbackFor=ServiceException.class)
如果Service中抛出的是RuntimeException或他的子类,事务会自动回滚
Spring中事务的传播特性
@Transactional(propagation=Propagation.REQUIRED) (重点)//Propagation传播
如果没有事务创建新事务, 如果当前有事务参与当前事务
@Transactional(propagation=Propagation.REQUIRES_NEW)
必须是新事务, 如果有当前事务, 挂起当前事务并且开启新事务.
@Transactional(propagation=Propagation.MANDATORY)
必须有事务, 如果当前没有事务就抛异常
@Transactional(propagation=Propagation.NEVER)
绝对不能有事务, 如果在事务中调用则抛出异常
@Transactional(propagation=Propagation.NESTED)
必须被嵌套到其他事务中
@Transactional(propagation=Propagation.NOT_SUPPORTED)
不支持事务
@Transactional(propagation=Propagation.SUPPORTS)
支持事务, 如果没有事务也不会创建新事务
Spring中事务的隔离级别4种
常用的有:
@Transactional(isolation=Isolation.READ_COMMITTED) //isolation隔离
SpringAOP如何实现?
Aspect(切面)
Pointcut(切入点)植入扩展业务的那个点(方法集合)
JoinPoint(连接点)要植入扩展业务的那个具体方法
Advice(通知)定义植入扩展业务的先后顺序
*@Before前置通知
*@AfterReturning返回通知
*@AfterThrowing异常通知
*@After最终通知
*@Around环绕通知
@order(1)定义切面的植入顺序
Spring中的bean使用AOP以后通过ClassPathXmlApplicationContext的getBean方法获得的对象
是代理对象
1.构建项目添加依赖pom.xml(要植入扩展业务的那个具体方法)
2.配置spring配置文件 spring-aop.xml
3.定义切面然后植入扩展功能
切面表达式
@Before("bean()")
@Before("execution(* beans.*.*(..))")
任意访问修饰返回值 beans包下 任意类 任意方法 任意参数
public void checkPermission() {
System.out.println("进行权限检测");
}
--------------------------------------------数据库引擎----------------------------------------------------------
ISAM 读取操作快,不占用大量的内存和存储资源
它不支持事务,也不能容错,硬盘崩溃,数据无法恢复
MYISAM 是ISAM的扩展格式,提供了ISAM中没有的索引和字段管理大量的功能,还具有表格锁定的机制,优化
多并发的读写操作,代价是得经常使用optimize table命令来恢复更新机制浪费的空间
InnoDB 性能稍差,但是支持事务和外部键
主键,唯一标示一条记录,不为空 id int primary key auto_increment,
外键,表的外键是另一张表的主键
--------------------------------------数据库中表的设计---------------------------------------------------------
一对多的关系:自关联,单表,id ,parentid,表的关系由多的一方维护
多对多的关系:借助中间表(关系表),中间表中设置联合主键,
------------------------------------Mybatis中$和#的区别--------------------------------------------------------
${}是Properties文件中变量的占位符,属于静态文本替换
#{}是sql的参数占位符号,在执行时会被替换为?,再通过反射从参数对象中获取值,调用get方法
groupby 用is ${}
--------------------------------------TCP和UDP的区别-------------------------------------------------------------
TCP传输控制协议,面向连接的协议,一个TCP连接需要经过3次对话,
1.A我想发数据,可以吗?
2.B可以发
3.发送数据
UDP用户数据报协议,非连接的协议
-------------------------------------http常用的状态码-----------------------------------------------------------
404 无法找到指定资源
500 服务器发生错误
302 重定向
400客户端向服务端提交的数据被据收
406服务器返回数据有问题
int a=5;int b=5;
a==b true;
Integer a=5;Integer b=5;Integer重写了equals方法
a==b true;
int a=new Integer(5);int b=new Integer(5);
a==b true;
-----------------------------------volatile-ThreadLocal----------------------------------------------------------------------
volatile关键字:保证线程的可见性,一个线程创建td后,其他线程立即可见td,其他线程不用判断sdf是否为空
(一个线程修改了某个变量的值,其他线程立即可见)不能保证原子性,可以禁止指令重排序
private static volatile ThreadLocal<SimpleDateFormat>td=new ThreadLocal<SimpleDateFormat>();
private static SimpleDateFormat getInstance() {
//获取当前线程中的SimpleDateFormat,如果当前线程中没有则创建一个
SimpleDateFormat sdf=td.get();
if(sdf==null) {
sdf=new SimpleDateFormat("yyyy/MM/dd");
td.set(sdf);//绑定
}
return sdf;
}
-------------------------------start和run方法的区别-------------------------------------------------------
start()启动线程,使线程处于就绪状态,放入等待队列,等待cpu调度
run()方法可以看成一个普通方法,还是在主线程中执行
sysnchronized
同步锁
修饰代码块,被修饰的代码块称为同步代码块,作用的对象是调用这个代码块的对象
修饰方法,被修饰的方法称为同步方法,作用的对象是调用这个方法的对象
修饰一个静态方法,作用的对象是这个类的所有对象
修饰类,作用的对象是这个类的所有对象
怎么设置守护线程
Thread dt=new Thread();
dt.setDaemon(true);
52、请说出你所知道的线程同步的方法。
wait():使一个线程处于等待状态,并且释放所持有的对象的 lock。
sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉
InterruptedException 异常。
notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的
唤醒某一个等待状态的线程,而是由 JVM 确定唤醒哪个线程,而且不是按优先级。
notityAll():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,
而是让它们竞争。
终止线程的方法:
stop()
suspend()
java.util.concurrent并发工具包,JDK1.5
阻塞队列:BlockingQueue阻塞队列接口
实现类:ArrayBlockingQueue
LinkedBlockingQueue
DelayQueue
PriorityBlockingQueue
SynchronousQueue
----------------------------------------单例模式--------------------------------------------------------------
饿汉式单例:
饿汉式在类创建的同时就已经建好了一个静态对象供系统使用,以后不再改变,所以是线程安全的
public class Singleton {
private Singleton(){}
private static Singleton instance = new Singleton();
public static Singleton getInstance() {
return instance;
}
}
懒汉式单例:
线程不安全,并发环境下可能创建多个实例
解决办法:1.在getInstance()上加同步锁
2.双重检查锁定
3.静态内部类(即解决了线程安全,又提高了性能)
2.public class Singleton {
private Singleton(){}
private static Singleton instance = null;
public static Singleton getInstance() {
if(instance==null){
synchronized(Singleton.class){
if (instance==null){
instance=new Singleton();
}
}
}
return instance;
}
}
3.public class Singleton {
private Singleton(){}
//静态内部类,
private static class LazyHolder{
private static final Singleton INSTANCE=new Singleton();
}
public static final Singleton getInstance(){
return LazyHolder.INSTANCE;
}
}
静态内部类:1。不依赖外部类的实例被实例化(这是静态内部类和成员内部类的区别)
2。不能访问外围类的非静态对象
3.外部类访问静态内部类通过内部类实例访问
4.静态内部类可以有静态成员,非静态内部类不能
工厂模式:
工厂模式是一种经常被使用到的模式,根据工厂模式实现的类可以根据提供
的数据生成一组类中某一个类的实例,通常这一组类有一个公共的抽象父类并且实现了相同
的方法,但是这些方法针对不同的数据进行了不同的操作。首先需要定义一个基类,该类的
子类通过不同的方法实现了基类中的方法。然后需要定义一个工厂类,工厂类可以根据条件
生成不同的子类实例。当得到子类的实例后,开发人员可以调用基类中的方法而不必考虑到
底返回的是哪一个子类的实例。
-----------------------------------------序列化-------------------------------------------------------------
RMI(远程方法调用)是RPC(跨进程调用)的一种实现
实体对象(持久化对象):用于实现与表中数据的映射,应该是先序列化接口Serializable
1.实体对象类名不用复数
2.实体类中属性都要使用对象类型
3.实体类中属性名要与表中字段名一致,类型要匹配
1.什么是序列化,反序列化?反序列化调用构造方法吗?
将对象转换为字节的过程称为序列化,反序列化默认调用无参构造函数
2.序列化的应用场景?
缓存中的对象落地(持久化)
3.序列化的版本ID有什么用?
对象发生变化时,便于反序列化
4.序列化是安全的吗?
本身是不安全的,在序列化时可以对数据进行加密,在反序列化时进行解密
transient关键字修饰,序列化时忽略
5.transient 关键字修饰的属性默认不被序列化,怎么让被transient修饰的属性序列化
6.类中使用static修饰的属性可否被序列化,假如需要这个属性序列化怎么办?
7.Externalizable与Serializable有什么关系?什么场景下会使用Externalizable对象
Externalizable是Serializable的子类
void writeExternal(ObjectOutput out)
void readExternal(ObjectInput in)
8.如何对序列化内容进行细粒度控制, 按需求对内容进行序列化
static 修饰的变量默认不被序列化
transient修饰的变量默认不被序列化
通过Externalizable对象自定义序列化
------------------------------------IO模型--------------------------------------------------------------
BIO:阻塞式IO,JDK1.4之前
1.服务端建立ServerSocket,以一个端口启动
2.等待客户端socket连接,如果没有连接则一直阻塞
3.一个socket连接后,从线程池去取一个线程处理socket
适用范围:连接数量小,连接时间短,程序直观简单
NIO:非阻塞IO,JDK1.4之后
NIO的API由四个主要的部分组成:缓冲区,通道,选择器
工作流程:1.通道注册一个监听到事件处理器
2.有事件发生时,事件处理器会通知相应的通道处理
适用范围:连接数量大,连接时间短,比如HTTP服务器,并发限于应用之中,编程复杂
AIO:异步非阻塞IO,JDK1.7之后
工作流程:1.客户端发起一个IO调用
2.服务器接受IO之后,异步回调接受成公后的IO,不会阻挡当前主流程,
主流程继续接受下一个请求
适用范围:连接数量大,连接时间长,IO密集型,比如聊天服务器,
java中流的类型
字节流:InputStream,OutputStream抽象类
缓冲流:BufferedReader,PrintWriter(自动行刷新)
字符流:InputStreamReader,OutputStreamWriter(Reader和Writer接口)
对象流:ObjectOutputStream,ObjectInputStream(InputStream,OutputStream)
------------------------------------------什么是类?---------------------------------------------
类定义了一种抽象的数据类型(将不同类型的数据集合组成整体用来描述新的事物)
同时还定义了可以对该类型实施的操作(方法)
类中有成员变量和成员方法
--------------------------------------什么是面向对象?---------------------------------------------
----------------------------------------java中内存管理-----------------------------------------------
在JAVA中,有java程序、虚拟机、操作系统三个层次,其中java程序与虚拟机交互,
而虚拟机与操作系统交互。编译好的java字节码文件运行在JVM中。
程序中无论代码还是数据,都需要存储在内存中,而java程序所需内存均由JVM进行管理分配,
开发者只需关心JVM是如何管理内存的,而无需关注某种操作系统是如何管理内存的,
这就保证了java程序的平台无关性。
JVM会将申请的内存从逻辑上划分为三个区域:堆、栈、方法区。这三个区域分别用于存储不同的数据。
java类加载
类的加载是指将类的.class二进制文件读入内存中,将其放在方法区中,然后在堆中创建一个
java.lang.Class对象用来封装类在方法区内的数据结构,类的加载的最终产品是位于堆中的
Class对象,并且向程序依托于AspectJ框架实现面向切面编程.员提供了访问方法区内数据结构的接口。
类加载器大致分为3种:
启动类加载器:Bootstrap ClassLoader
扩展类加载器:Extension ClassLoader
应用程序加载器:Application ClassLoader,用来加载用户类路径
自定义类加载器:继承自ClassLoader类,重写findClass方法
类加载机制:
1.全盘负责,一个类加载器加载某个类时,该类依赖和引用的其他类也由该类加载器来载入
2.父类委托:总是先让父类加载其试图加载该类,父类无法加载时从自己的类路径加载该类
双亲委派模型:防止出现多份同样的字节码文件
保证java程序的安全稳定运行
3.缓存机制:所有加载过的类都会被缓存,类加载时,类加载器先从缓存区寻找该Class
类的加载有3种方式:
1.命令行启动应用时候由jvm初始化加载
2.通过Class.forName()动态加载,加载时还会对类进行解释,执行static块中的内容,通过
带参的构造函数可以控制是否加载static块
3.通过ClassLoader.loadClass()动态加载,只加载类,不执行static中的内容,只有调用了
newInstance方法之后才会执行static
JVM内存分区:
JVM初始运行的时候就会分配好Method Area和Heap,而JVM每遇到一个线程就会为其分配一个
Program Counter Register程序计数器,VM Stack(虚拟机栈)和本地方法栈,堆和方法区
线程共享,其余的不线程共享,是因为线程终止的时候程序计数器虚拟机栈和本地方法栈的内存
会被释放,他们的生命周期与线程相同,而堆和方法区的生命周期与java程序相同
堆:用来保存对象的实例,需要在栈中保存一个4字节的Heap的内存地址
方法区:加载类的类定义数据,常量和静态变量都存储方法区中
程序计数器:较小的内存区域,作用是可以看做是当前线程执行的字节码的位置指示器
虚拟机栈:存储局部变量(操作数),方法本身(指令的操作码)
本地方法栈:为JVM提供使用本地方法的服务
--------------------------------------------垃圾回收机制----------------------------------------------------
1.如何确定某个对象是垃圾?
引用计数法:如果一个对象没有任何引用与之相关联,那么这个对象就可能成为被回收对象
但是这种方法无法解决循环引用
可达性分析法:java中采用这种方法,通过一系列的GC Roots对象作为起点进行搜索,如果
GC Roots和一个对象没有可达路径,则这个对象在经过至少两次的标记后
就可能被回收。
2.垃圾回收算法?
标记-清除:这种方式容易产生内存碎片,碎片太多导致在为大对象分配内存空间时内存不够
而提前触发下一次GC操作
复制算法:将内存按容量分为等量的两块,每次使用其中的一块,当一块的内存用完之后,就
将存活的对象放到另一块内存之上,一次性清掉以用内存,这中方式不容易产生
内存碎片但是,浪费内存空间,如果存活对象过多,那么复制算法的效率大大降低
标记-整理:为了解决复制算法的缺陷,标记整理和标记清除一样,但是在标记完成之后是将
存活的对象移动到内存的一端,然后清掉端边界以外的内存
分代收集算法:根据对象的存活周期,将堆区划分为新生代和老年代
新生代(1/3堆空间):Minor GC是发生在新生代的垃圾收集动作,采用复制算法
新生代分为3块(Eden(8/10)、From Survivor(1/10)、To Survivor(1/10))
老年代(2/3堆空间):Full GC是发生在老年代的垃圾收集动作,采用的标记-整理算法
对象出生在Eden或者是其中一个Survivor区(假设是From)经过一次Minor GC之后,若对象
还存活并且能被另一块Survivor(To)所容纳,那么使用复制算法将Eden 喝 From Survivor中
存活的对象复制到另一块Survivor中(To),并将他们的年龄设置位1,以后对象在Survivor
中每熬过一次Minor GC他的年龄就会加1,当年龄到达15(默认),这些对象就会成为老年代。
------------------------------------------------------------------------------------------------------------------
ajax异步请求:
$.ajax({
"url":"",
"type":"post",
"dataType":"json",
"data":"{"name":"sdd","":""}",
"sussess":function(){
}
});
排序方法:
插入排序(直接插入排序,希尔排序)
交换排序(冒泡排序,快速排序)
选择排序()
归并排序
分配排序(箱排序,技术排序)
Linux进程间的通讯几种机制
管道:pipe 管道是一种半双工的通信方式,数据只能单向流动,且只能在有亲缘关系的进程间使用,
进程的亲缘关系通常是指父子进程
有名管道:named pipe 也是版双工的通信方式,但是允许无亲缘关系进程间的通信
信号量:semophore 信号量是一个计数器,可以用来多个进程堆共享资源的访问,他常作为一种锁机制,
防止某进程正在访问共享资源时,其他进程也访问该资源。主要作为进程间以及同一进程内不同线程之间
的同步手段
消息队列:message queue
信号:sinal
共享内存:shared momory
套接字:socket
DOM对象转换为jquery对象
dom对象无法是使用jquery的方法,同理jquery对象无法使用dom对象的方法
dom对象转换为jquery对象的方法
var v=document.getElementById("id");
得到的是一个dom对象
转换为jquery对象只需要用$()把dom对象包装就行
var $v=$(v);
jquery对象转换为dom对象
var $v=$('#v');
得到一个jquery对象,转换为dom对象有两种方法
1.var v=$v.get(0);
2.var v=$v[0];
ModelAndView 如何向前台页面传值
model:是ModelMap类型,ModelMap是一个LinkedHashMap的子类
view :包含了一些视图的信息
ModelAndView mav=new ModelAndView("hello");
mav.addObject("time",new Date());
return mav;
boolean类型在MySQL数据库中用tinyint(1)类型表示
MySQL中where子句判断为不为null 用is null ,is not null
事件冒泡:事件从事件目标开始,往上冒直到页面的最上一级标签
使用事件冒泡时,子级元素先触发,父级元素后触发
如何获得事件对象
事件对象常用属性:e.target获取事件源,返回DOM对象
e.pageX
e.pageY获取鼠标的坐标
阻止事件冒泡e.stopPropagation();
>>jquery的选择器返回的是一个对象,所以无论是否存在元素,这个对象都不为空
>>jquery.data()动态绑定数据,和读取数据jquery.removeData()移除数据
>>jquery.extend(target,src1,src2)作用,合并src1,src2 到target中
var result=$.exten依托于AspectJ框架实现面向切面编程.d({},{name:"tom",age:21},{name:"jerry",sex:"boy"})
result={name:"jerry",age:21,sex:"boy"}
后面的参数如果和前面的参数名称相同,那么后面的会覆盖前面的参数值
如果省略target,且只有一个参数,那么会将src1合并到调用extend方法的对象中去
--------------------------------------------面试1----------------------------------------------------
1.js基础对象有哪些?window和document的区别?常用的方法和属性有哪些?
String,Number,Array,Date,Math,RegExp,Function
window对象表示浏览器窗口,所有的javaScript全局对象,函数及变量,均自动成为window对象的成员
常用属性:document/history/location/screen/navigator/
常用的方法:alert()/confirm()
setInterval(exp,time)//参数1执行语句或者执行函数,参数2时间周期,
返回值tid为定时器对象
clerInterval(tid)//停止启动的定时器
setTimeout()
clearTimeout(tid)
history属性:length 代表浏览器历史列表中的URL数量
方法:back()/forword()/go(num)
location属性:href 当前窗口正在浏览的网页地址
方法:reload() 重新载入当前网页,刷新
document:文档对象模型(DOM)当网页被加载时,浏览器会创建文档对象模型,
document对象是DOM的根结点
3.什么是MVC模式,spring在MVC中是怎么运用的?
MVC模式,全称Model View Controller 是一种软件架构模式,MVC模式把用户界面交互拆分
到3个不同的角色中,使用MVC的目的是将M和V的实现代码分离,C的存在是则是确保M和V的同步
4.对Hibernate的理解?怎么使用Hibernate?
对JDBC进行了很好的封装,它通过配置使JavaBean对象和数据库表之间进行映射,
并提供对增、删、改、查便利的操作方法,同时支持事务处理,它对数据库记录
还提供了缓存机制,提高效率,它可以使程序员不用书写SQL,也不用关心数据库SQL之间的差异
第一步:
导包:required下的所有包,jpa下的所有包,所连接的sql驱动包
第二步:
创建于数据库表对应的实体类。并在该实体类所在包下创建后缀名为.hbm.xml的配置文件,该文件为映射配置文件
第三步:
在配置文件中配置映射关系
第四步:
创建hibernate的核心配置文件
核心配置文件xml,位置必须在src下面,名称必须是hibernate.cgf.xml
5.Hibernate中OpenSession和getCurrentSession的区别,load()和get()的区别?
* 采用getCurrentSession()创建的session会绑定到当前线程中,而采用openSession()
创建的session则不会
* 采用getCurrentSession()创建的session在commit或rollback时会自动关闭,而采用openSession()
创建的session必须手动关闭
1.get()方法直接返回实体类,load()方法可以返回实体的代理类实例。
2.hibernate load是采用延迟机制(当lazy属性为true时) 而get不采用延迟机制(get语句马上读库)
3.找不到符合条件的数据 get方法将返回null
load将会报出ObjectNotFoundExcepion
6.用自己的话简述一下strus2的执行流程?
1、客户端初始化一个指向Servlet容器的请求
2、请求经过系列的过滤器,FilterDispatcher被调用
3、ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy
4、ActionProxy通过ConfigurationManager询问框架的配置文件找到需要调用的Action类
5、ActionProxy创建一个ActionInvocation实例
6、ActionInvocation调用、回调Action的execute方法
7、Action执行完毕ActionInvocation根据struts.xml配置找到对应的返回结果
7.什么是spring IOC,有哪几种方式?
IOC控制反转,即对象之间的依赖关系由容器来建立,通过依赖注入DI来实现
注入方式:set方法注入:
<bean id="b" class="ioc.B"/>
<bean id="a" class="ioc.A">
<property name="b" ref="b"/> //name为"b",则会调用属性的setB方法
</bean>
构造器注入:
<bean id="cpu" class="ioc.Cpu"/>
<bean id="phone" class="ioc.Phone">
<constructor-arg index="0" ref="cpu"/> //index:构造器中的参数下标
</bean>
自动装配:只需要配置autowire属性
<bean id="stu" class="ioc.Student" autowire="byType[byName]"/>
9.什么是AOP,介绍一下spring事务管理,spring提供了哪些关于事务管理的类?
AOP:面向切面编程,通过动态代理模式,在不改变核心代码的情况下,为项目添加新的业务功能
springAOP 依托于AspectJ框架实现面向切面编程.
spring 控制事务有两种实现:
1编程式事务(基本不用)
try{
Connection conn=DbUtil.getConnection;
conn.setAutoCommit(false);
dao.updateObject(...);
conn.commit();
}catch{
conn.rollback();
}
2.声明式事务
将编程事务的那部分代码交给Spring底层实现,然后通过AOP机制将事务控制代码植入到业务层
声明式事务处理有两种方式:
1.基于XML
2. 基于注解(重点掌握)比较灵活
@Transactional注解
@Transactional(roolbackFor=ServiceException.class)
-------------------------------------------------------面试2-------------------------------------------------------------
1.什么是索引?有什么作用?
索引是一种允许直接访问数据表中某一数据行的树型结构,为了提高查询效率而引入,是独立于表的对象,
可以存放在与表不同的表空间(TABLESPACE)中。索引记录中存有索引关键字和指向表中数据的指针(地址)。
对索引进行的I/O操作比对表进行操作要少很多。
优点:加快数据查询的速度,加快表与表的连接,加快分组和排序时间
缺点:创建索引和维护索引需要耗费时间,索引占用物理空间,所以当堆表中的数据进行增删改的时候,
索引就需要频繁的维护,降低了数据的维护速度
索引的使用原则:
作为通用规则,只有当经常查询索引列中的数据时,才需要在表上创建索引。
1. 在经常用作过滤器的字段上建立索引;
2. 在SQL语句中经常进行GROUP BY、ORDER BY的字段上建立索引;
3. 在不同值较少的字段上不必要建立索引,如性别字段;
4. 对于经常存取的列避免建立索引;
5. 用于联接的列(主健/外健)上建立索引;
6. 在经常存取的多个列上建立复合索引,但要注意复合索引的建立顺序要按照使用的频度来确定;
7. 缺省情况下建立的是非簇集索引,但在以下情况下最好考虑簇集索引,
如:含有有限数目(不是很少)唯一的列;进行大范围的查询;
充分的利用索引可以减少表扫描I/0的次数,有效的避免对整表的搜索。
当然合理的索引要建立在对各种查询的分析和预测中,也取决于DBA的所设计的数据库结构。
2.什么是视图?有什么作用?
视图也被称作虚表,是一组数据的逻辑表示,本质是对应一个select语句,结果集被赋予一个名字,即视图名
视图本身并不包含任何数据,它只包含映射到基表的一个查询语句,当基表数据发生变化,视图数据也随之变化。
视图的分类:
SELECT语句是基于单表建立的,且不包含任何函数运算、表达式或分组函数,叫做简单视图,此时视图是基表的子集;
SELECT语句同样是基于单表,但包含了单行函数、表达式、分组函数或GROUP BY子句,叫做复杂视图;
SELECT语句是基于多个表的,叫做连接视图。
视图的作用:
1.如果需要经常执行某项复杂查询,可以基于这个复杂查询建立视图,此后查询此视图即可,简化复杂查询;
2.访问视图时,只能访问到所对应的SELECT语句中涉及到的列,对基表中的其它列起到安全和保密的作用,
可以限制数据访问。
3.什么是序列?有什么作用?
序列(SEQUENCE)是一种用来生成唯一数字值的数据库对象。序列的值由Oracle程序按递增或递减顺序自动生成,
通常用来自动产生表的主键值。
start with 起始数据 increment by 步进
4.js怎么提交表单?
5.怎么将一个List添加到jsp页面上?
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<c:forEach items="${employees}" var="e" varStatus="s">
<tr class="row${s.index%2+1}">
6.动态sql?
通过标签组合成的动态sql语句?
<sql id="queryWhereId">
<where>
<if test="name!=null and name!='' ">
name like concat ("%",#{name},"%")
</if>
<if test="valid!=null">
and valid=#{valid}
</if>
</where>
</sql>
<foreach collection="ids" open="(" close=")" separator="," item="i">
#{i}
</foreach>
7.Mybatis连接数据库需要配置什么?Spring集成Mybatis需要配置什么?
Mybatis需要配置连接池,指定映射文件
SqlSessionFactoryBuilder ssfb=new SqlSessionFactoryBuilder();
SqlSessionFactory ssf=ssfb.build
(TestCase.class.getClassLoader().getResourceAsStream("SqlMapConfig.xml"));
//获得SqlSession对象
session=ssf.openSession();
session.insert();session.delete();session.selectOne();
session.commit();
session.colse();
spring集成Mybatis
在sqlSessionFactory中注入连接池,注入Mapper文件,扫描dao接口
<!-- Mapper接口所在包,Spring会自动查找其下的Mapper -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="cn.tedu.**.dao " />
</bean>
8.什么是连接池?
连接池是用于创建和管理数据库连接的缓冲池,缓冲池中的连接可以被任何需要他们的线程使用,
当一个线程需要用JDBC对数据库进行操作的时候,从池中请求一个连接,当这个连接使用完毕之后,
返回到连接池中,
优点:减少创建连接的时间,连接重用,简化编程
如果不使用连接池,每一次访问数据库,都需要创建一个连接,对系统影响很大
9. 什么是EL表达式,什么是jstl
EL表达式,用于给JSTL标签的属性赋值,也可以直接用来输出而脱离标签单独使用。
$(对象名.属性名)/$(对象名["属性名"])
从pageContext、request、session、application中依次查找绑定名为“user”的对象,找到后调用“getName”方法
如何使用jstl
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
核心标签-if,-choose,-forEach标签
10.get请求和post请求的区别?
11.二叉树的遍历采用什么算法?
多个任务,希望交给一个线程,顺序执行如何实现?
使用阻塞队列
java中定时任务调度如何实现(Timer,ScheduledExecutorService)
spring如何实现定时任务调度(Quartz框架)
自己如何实现一个LruCache缓存结构对象(不利用LinkedHashMap)
-----------------------面试3------------------------------
值传递与引用传递的区别
---------------------面试4----------------------------------
spring boot
多线程应用的实例
servlet和jsp的区别
数据库自连接和外连接的区别
队列和链表的区别
数据库事务是什么
答:事务就是一系列的操作,这些操作完成一项任务。只要这些操作里有一个操作没有成功,
事务就操作失败,发生回滚事件。即撤消前面的操作,这样可以保证数据的一致性。
而且可以把操作暂时放在缓存里,等所有操作都成功有提交数据库,这样保证费时的操作都是有效操作。