2020.8.21

一、关于JVM

  大多数JVM将内存区域划分为Method Area(Non-Heap)(方法区) ,Heap(堆) ,Program Counter Register(程序计数器) ,   VM Stack(虚拟机栈,也有翻译成JAVA方法栈的),Native Method Stack( 本地方法栈 ),其中Method Area和Heap是线程共享的  ,VM Stack,Native Method Stack和Program Counter Register是非线程共享的。

  JVM初始运行的时候都会分配好Method Area(方法区)和Heap(堆) ,而JVM每遇到一个线程,就为其分配一个 Program Counter Register(程序计数器), VM Stack(虚拟机栈)和Native Method Stack(本地方法栈), 当线程终止时,三者(虚拟机栈,本地方法栈和程序计数器)所占用的内存空间也会被释放掉。这也是为什么我把内存区域分为线程共享和非线程共享的原因,非线程共享的那三个区域的生命周期与所属线程相同,而线程共享的区域与JAVA程序运行的生命周期相同,所以这也是系统垃圾回收的场所只发生在线程共享的区域(实际上对大部分虚拟机来说知发生在Heap上)的原因。

 

二、关于Statement、PreparedStatement、ConllableStatement

  1.Statement、PreparedStatement和CallableStatement都是接口(interface)。 

  2.Statement继承自Wrapper、PreparedStatement继承自Statement、CallableStatement继承自PreparedStatement。 

  3. Statement接口提供了执行语句和获取结果的基本方法; PreparedStatement接口添加了处理 IN 参数的方法; CallableStatement接口添加了处理 OUT 参数的方法。 

  4.

    a.Statement: 普通的不带参的查询SQL;支持批量更新,批量删除;

    b.PreparedStatement: 可变参数的SQL,编译一次,执行多次,效率高;安全性好,有效防止Sql注入等问题;支持批量更新,批量删除;

    c.CallableStatement: 继承自PreparedStatement,支持带参数的SQL操作;支持调用存储过程,提供了对输出和输入/输出参数(INOUT)的支持;


  Statement每次执行sql语句,数据库都要执行sql语句的编译 , 
  最好用于仅执行一次查询并返回结果的情形,效率高于PreparedStatement。 

  PreparedStatement是预编译的,使用PreparedStatement有几个好处 
  1. 在执行可变参数的一条SQL时,PreparedStatement比Statement的效率高,因为DBMS预编译一条SQL当然会比多次编译一条SQL的效率要高。 
  2. 安全性好,有效防止SQL注入等问题。 
  3.  对于多次重复执行的语句,使用PreparedStament效率会更高一点,并且在这种情况下也比较适合使用batch; 
  4.  代码的可读性和可维护性。

  注意:JDBC statement中的PreparedStatement的占位符对应着即将与之对应的值,并且一个占位符只能对应一个值,如果能对应多个就会引起混淆。sql语句是确定的,那么一个占位符必定只能对应一个值

 

三、 事务属性的种类:   传播行为、隔离级别、只读和事务超时

 

  

  c)    只读

  如果在一个事务中所有关于数据库的操作都是只读的,也就是说,这些操作只读取数据库中的数据,而并不更新数据,那么应将事务设为只读模式( READ_ONLY_MARKER ) , 这样更有利于数据库进行优化 

  因为只读的优化措施是事务启动后由数据库实施的,因此,只有将那些具有可能启动新事务的传播行为 (PROPAGATION_NESTED 、PROPAGATION_REQUIRED 、PROPAGATION_REQUIRED_NEW) 的方法的事务标记成只读才有意义。

  如果使用 Hibernate 作为持久化机制,那么将事务标记为只读后,会将 Hibernate 的 flush 模式设置为 FULSH_NEVER, 以告诉 Hibernate 避免和数据库之间进行不必要的同步,并将所有更新延迟到事务结束。

  d)   事务超时

  如果一个事务长时间运行,这时为了尽量避免浪费系统资源,应为这个事务设置一个有效时间,使其等待数秒后自动回滚。与设置“只读”属性一样,事务有效属性也需要给那些具有可能启动新事物的传播行为的方法的事务标记成只读才有意义。

 

四、doGet/doPost 则是在 javax.servlet.http.HttpServlet 中实现的

 

五、

  Servlet的生命周期分为5个阶段:加载、创建、初始化、处理客户请求、卸载。

    (1)加载:容器通过类加载器使用servlet类对应的文件加载servlet
    (2)创建:通过调用servlet构造函数创建一个servlet对象
    (3)初始化:调用init方法初始化
    (4)处理客户请求:每当有一个客户请求,容器会创建一个线程来处理客户请求
    (5)卸载:调用destroy方法让servlet自己释放其占用的资源

 

六、servlet在多线程下其本身并不是线程安全的。

  如果在类中定义成员变量,而在service中根据不同的线程对该成员变量进行更改,那么在并发的时候就会引起错误。最好是在方法中,定义局部变量,而不是类变量或者对象的成员变量。由于方法中的局部变量是在栈中,彼此各自都拥有独立的运行空间而不会互相干扰,因此才做到线程安全。
 
 
七、redirecit和forward 
  forward,服务器获取跳转页面内容传给用户,用户地址栏不变
  redirect,是服务器向用户发送转向的地址,redirect后地址栏变成新的地址
 
八、加载驱动的三种方式:
  1.Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
  2. DriverManager.registerDriver(new com.mysql.jdbc.Driver());
  3.System.setProperty("jdbc.drivers", "com.mysql.jdbc.Driver");
 
九、sleep()和wait()的区别

 

 

posted @ 2020-08-21 19:32  Rhettttt  阅读(125)  评论(0)    收藏  举报