301和302状态码都表示重定向,当浏览器拿到服务器返回的这个状态码后悔自动跳转到一个新的URL地址。 301代表永久性重定向,旧地址被永久移除,客户端向新地址发送请求。 302代表暂时性重定向,旧地址还在,客户端继续向旧地址发送请求。 303代表暂时性重定向,重定向到新地址时,必须使用GET方法请求新地址。 307代表暂时性重定向,与302的区别在于307不允许从POST改为GET。 307代表
当客户端登录完成后,会在服务端产生一个session,此时服务端会将sessionid返回给客户端浏览器。客户端将sessionid储存在浏览器的cookie中,当用户再次登录时,会获得对应的sessionid,然后将sessionid发送到服务端请求登录,服务端在内存中找到对应的sessionid,完成登录,如果找不到,返回登录页面。
多线程编程中一般线程的个数都大于 CPU 核心的个数,而一个 CPU 核心在任意时刻只能被一个线程使用,为了让这些线程都能得到有效执行,CPU 采取的策略是为每个线程分配时间片并轮转的形式。当一个线程的时间片用完的时候就会重新处于就绪状态让给其他线程使用,这个过程就属于一次上下文切换。 概括来说就是:当前任务在执行完 CPU 时间片切换到另一个任务之前会先保存自己的状态,以便下次再切换回这个任务时
一般默认情况下,在会话中,服务器存储 session 的 sessionid 是通过 cookie 存到浏览器里。 如果浏览器禁用了 cookie,浏览器请求服务器无法携带 sessionid,服务器无法识别请求中的用户身份,session失效。 但是可以通过其他方法在禁用 cookie 的情况下,可以继续使用session。 通过url重写,把 sessionid 作为参数追加的原 url 中,
(1)存储位置不同 cookie在客户端浏览器; session在服务器; (2)存储容量不同 cookie<=4K,一个站点最多保留20个cookie; session没有上线,出于对服务器的保护,session内不可存过多东西,并且要设置session删除机制; (3)存储方式不同 cookie只能保存ASCII字符串,并需要通过编码方式存储为Unicode字符或者二进制数据; session
application、session、request、page
forward是直接请求转发;redirect是间接请求转发,又叫重定向。 forward,客户端和浏览器执行一次请求;redirect,客户端和浏览器执行两次请求。 forward,经典的MVC模式就是forward;redirect,用于避免用户的非正常访问。(例如用户非正常访问,servlet就可以将HTTP请求重定向到登录页面)。 forward,地址不变;redirect,地址改变。 f
JSP九大内置对象: pageContext,页面上下文对象,相当于页面中所有功能的集合,通过它可以获取JSP页面的out、request、response、session、application对象。 request response session application,应用程序对象,application实现了用户间数据的共享,可存放全局变量,它开始于服务器启动,知道服务器关闭。 page
(1)servlet是服务器端的Java程序,它担当客户端和服务端的中间层。 (2)jsp全名为Java server pages,中文名叫Java服务器页面,其本质是一个简化的servlet设计。JSP是一种动态页面设计,它的主要目的是将表示逻辑从servlet中分离出来。 (3)JVM只能识别Java代码,不能识别JSP,JSP编译后变成了servlet,web容器将JSP的代码编译成JVM能
Lock 接口比同步方法和同步块提供了更具扩展性的锁操作。他们允许更灵活的结构,可以具有完全不同的性质,并且可以支持多个相关类的条件对象。 它的优势有: (1)可以使锁更公平 (2)可以使线程在等待锁的时候响应中断 (3)可以让线程尝试获取锁,并在无法获取锁的时候立即返回或者等待一段时间 (4)可以在不同的范围,以不同的顺序获取和释放锁 整体上来说 Lock 是 synchronized 的扩展版
synchronized 是和 if、else、for、while 一样的关键字,ReentrantLock 是类,这是二者的本质区别。既然 ReentrantLock 是类,那么它就提供了比synchronized 更多更灵活的特性,可以被继承、可以有方法、可以有各种各样的类变量 synchronized 早期的实现比较低效,对比 ReentrantLock,大多数场景性能都相差较大,但是在 J
synchronized 锁升级原理:在锁对象的对象头里面有一个 threadid 字段,在第一次访问的时候 threadid 为空,jvm 让其持有偏向锁,并将 threadid 设置为其线程 id,再次进入的时候会先判断 threadid 是否与其线程 id 一致,如果一致则可以直接使用此对象,如果不一致,则升级偏向锁为轻量级锁,通过自旋循环一定次数来获取锁,执行一定次数之后,如果还没有正常获
很多 synchronized 里面的代码只是一些很简单的代码,执行时间非常快,此时等待的线程都加锁可能是一种不太值得的操作,因为线程阻塞涉及到用户态和内核态切换的问题。既然 synchronized 里面的代码执行得非常快,不妨让等待锁的线程不要被阻塞,而是在 synchronized 的边界做忙循环,这就是自旋。如果做了多次循环发现还没有获得锁,再阻塞,这样可能是一种更好的策略。
在执行程序时,为了提供性能,处理器和编译器常常会对指令进行重排序,但是不能随意重排序,不是你想怎么排序就怎么排序,它需要满足以下两个条件: 在单线程环境下不能改变程序运行的结果; 存在数据依赖关系的不允许重排序 需要注意的是:重排序不会影响单线程环境的执行结果,但是会破坏多线程的执行语义。
ThreadLocal 变量解决了多线程环境下单个线程中变量的共享问题,使用名为ThreadLocalMap的哈希表进行维护(key为ThreadLocal变量名,value为ThreadLocal变量的值); 使用时需要注意以下几点: 线程之间的threadLocal变量是互不影响的, 使用private final static进行修饰,防止多实例时内存的泄露问题 线程池环境下使用后将thre