Java高频面试题(二)

Java高频面试题二


(根据自己的面试经验总结的知识点,内容比较浅显,有问题的地方欢迎指正呀)

二、 java web部分

2.1、讲一下http get和post请求的区别?

GET和POST请求都是http的请求方式,用户通过不同的http的请求方式完成对资源(url)的不同操作。GET,POST,PUT,DELETE就对应着对这个资源的查 ,改 ,增 ,删 4个操作。
具体点来讲GET一般用于获取/查询资源信息,而POST一般用于更新资源信息
1、地址方式:
Get请求提交的数据会在地址栏显示出来,而post请求不会再地址栏显示出来
GET提交,请求的数据会附在URL之后(就是把数据放置在HTTP协议头中),以?分割URL和传输数据,多个参数用&连接;POST提交:把提交的数据放置在是HTTP包的包体中。因此,GET提交的数据会在地址栏中显示出来,而POST提交,地址栏不会改变
2、传输数据的大小
http Get请求由于浏览器对地址长度的限制而导致传输的数据有限制。而POST请求不会因为地址长度限制而导致传输数据限制。
3、 安全性
POST的安全性要比GET的安全性高。由于数据是会在地址中呈现,所以可以通过历史记录找到密码等关键信息。

2.2 、说一下你对servlet的理解?或者servlet是什么?

Servlet(Server Applet),全称Java Servlet, 是用Java编写的服务器端程序。而这些Sevlet都要实现Servlet这个接口。其主要功能在于交互式地浏览和修改数据,生成动态Web内容。Servlet运行于支持Java的应用服务器中。
HttpServlet 重写doGetdoPost方法或者你也可以重写service方法完成对get和post请求的响应

2.3、简单说一下servlet的生命周期

servlet有良好的生存期的定义,包括加载和实例化、初始化、处理请求以及服务结束。这个生存期由javax.servlet.Servlet接口的init,service和destroy方法表达。
加载Servlet的class---->实例化Servlet----->调用Servlet的init完成初始化---->响应请求(Servlet的service方法)----->Servlet容器关闭时(Servlet的destory方法)
Servlet启动时,开始加载servlet生命周期开始。Servlet被服务器实例化后,容器运行其init方法,请求到达时运行其service方法,service方法自动派遣运行与请求对应的doXXX方法(doGet,doPost)等,当服务器决定将实例销毁的时候(服务器关闭)调用其destroy方法。

2.4 、Servlet API中forward() 与redirect()的区别?

  1. forward是服务器端的转向而redirect是客户端的跳转。使用forward浏览器的地址不会发生改变。而redirect会发生改变。
  2. Forward是一次请求中完成。而redirect是重新发起请求。两次request,重定向可以访问自己的web应用以外的资源。重定向的过程,传输的信息会被丢失。
  3. Forward是在服务器端完成,而不用客户端重新发起请求,效率较高。
    Redirect:服务器内部把对一个request/response的处理权交给另外一个客户端,传输的信息不会丢失。

2.5 、JSP和Servlet有哪些相同点和不同点?

  1. 共同点:
    JSP是Servlet技术的扩展,所有的jsp文件都会被翻译为一个继承HttpServlet的类。也就是jsp最终也是一个Servlet.这个Servlet对外提供服务。
  2. 不同点:
    Servlet和JSP最主要的不同点在于JSP侧重于视图,Servlet主要用于控制逻辑。
    Servlet如果要实现html的功能,必须使用Writer输出对应的html,比较麻烦。而JSP的情况是Java和HTML可以组合成一个扩展名为.jsp的文件,做界面展示比较方便而嵌入逻辑比较复杂。

2.6、 Servlet线程安全问题

当多个客户端并发访问同一个Servlet时,web服务器会为每一个客户端的访问请求创建一个线程,并在这个线程上调用Servlet的service方法,因此service方法内如果访问了同一个资源的话,就有可能引发线程安全问题。

  1. 存在的问题:
    实例变量:实例变量在类中定义。类的每一个实例都拥有自己的实例变量,如果多个线程同时访问该实例的方法,而该方法又使用到实例变量,那么这些线程同时访问的是同一个实例变量,会共享该实例变量。
    局部变量:局部变量在方法中定义。每当一个线程访问局部变量所在的方法时,在线程的堆栈中就会创建这个局部变量,线程执行完这个方法时,该局部变量就被销毁。所有多个线程同时访问该方法时,每个线程都有自己的局部变量,不会共享。
  2. 怎么解决:
    如果不涉及到全局共享变量,全部放到局部变量,最好的做法
    如果使用到全局共享的场景,可以使用加锁的方式,最好使用乐观锁的形式去加锁
    或者使用线程安全的StringBuffer去代替String,
    或者使用线程安全的容器比如: java.util.concurrent.ConcurrentHashMap 等

2.7、 jsp有哪些内置对象?

9个内置的对象:
(1)request 用户端请求,此请求会包含来自GET/POST请求的参数request表示一次客户端的请求。一次请求的生命周期从客户端发起到服务器接收并响应该请求,或者将该请求forward到另一个页面或者Servlet进行处理而结束。在此期间,本次请求的参数,属性都是有效的;一旦客户端刷新浏览器,重新发起请求,则之前的请求参数和属性都将失效。
(2)response 网页传回用户端的回应
(3)pageContext 网页的属性是在这里管理
(4)session 与请求有关的会话期,当我们向服务器发送第一个请求开始,只要页面不关闭,或者会话未过期(默认30分钟),或者未调用HttpSession的invalidate()方法,接下来的操作都属于同一次会话的范畴。
(5)application servlet正在执行的内容,application的作用域是最广的,它代表着整个Web应用的全局变量,对每一个页面,每一个Servlet都是有效的。当我们在application中设置属性时,这个属性在任意的一个页面都是可以访问的。
(6)out 用来传送回应的输出
(7)config servlet的构架部件
(8)page JSP网页本身
(9)exception 针对错误网页,未捕捉的例外

2.8、jsp作用域分别是什么?

四大作用域:
page—只能在当前页面使用
request—只能在同一次请求当中使用
session—只能在同一个会话(session对象)中使用
context—只能在同一个web应用中使用

2.9、session和cookie的区别?你在项目中都有哪些地方使用了?

Session和cookie都是会话(Seesion)跟踪技术。Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。但是Session的实现依赖于Cookie,sessionId(session的唯一标识需要存放在客户端)
cookie 和session 的区别:
1、cookie数据存放在客户的浏览器上,session数据放在服务器上。
2、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗,考虑到安全应当使用session。
3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用COOKIE。
4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
5、所以个人建议:将登陆信息等重要信息存放为SESSION;其他信息如果需要保留,可以放在COOKIE中,比如购物车,购物车最好使用cookie,但是cookie是可以在客户端禁用的,这时候我们要使用cookie+数据库的方式实现,当从cookie中不能取出数据时,就从数据库获取。

2.10、 maven解决jar包冲突?

方式一:通过mvn tree查看
方式二:通过在启动过程中查看类文件位置,查看到具体类路径,辅助分析实际运行路径
方式三:查找类文件,最终:找到引入依赖源头,通过exclusions 进行排除
​​

2.11、 maven解决传递依赖?

传递依赖发现:当一个库说A就依赖于其他库说B的情况下,另一个项目Ç想用A,则该项目需要使用库中B。
在Maven帮助下以避免这样的要求来发现所有需要的库。 Maven通过读取依赖项项目文件(pom.xml中),找出它们的依赖等。
我们只需要在每个项目POM定义直接依赖关系。 Maven自动处理其余部分.

三、数据库部分

3.1、数据库的分类及常用的数据库

数据库分为:关系型数据库和非关系型数据库
关系型:mysql oracle sqlserver等
非关系型:redis,memcache,mogodb,hadoop等

3.2、简单介绍一下关系数据库三范式?

范式就是规范,就是关系型数据库在设计表时,要遵循的三个规范。
要想满足第二范式必须先满足第一范式,要满足第三范式必须先满足第二范式。
第一范式(1NF)是指数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值,即实体中的某个属性不能有多个值或者不能有重复的属性。列数据的不可分割
二范式(2NF)要求数据库表中的每个行必须可以被唯一地区分。为实现区分通常需要为表加上一个列,以存储各个实例的唯一标识。(主键)
满足第三范式(3NF)必须先满足第二范式(2NF)。简而言之,第三范式(3NF)要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。(外键)
反三范式,有的时候为了效率,可以设置重复或者可以推导出的字段.
订单(总价)和订单项(单价)

3.3、事务ACID 特性。

事务是并发控制的单位,是用户定义的一个操作序列。这些操作要么都做,要么都不做,是一个不可分割的工作单位。
一个转账必须 A账号扣钱成功,B账号加钱成功,才算正真的转账成功。
事务必须满足四大特征:原子性,一致性,隔离性持久性/持续性

  1. 原子性:表示事务内操作不可分割。要么都成功、要么都是失败.
  2. 一致性:要么都成功、要么都是失败.后面的失败了要对前面的操作进行回滚。
  3. 隔离性:一个事务开始后,不能后其他事务干扰。
  4. 持久性/持续性:表示事务开始了,就不能终止。

3.4、 mysql数据库的默认的最大连接数?

100
为什么需要最大连接数?特定服务器上面的数据库只能支持一定数目同时连接,这时候我们一般都会设置最大连接数(最多同时服务多少连接)。在数据库安装时都会有一个默认的最大连接数为100

3.5、说一下msyql、Oracle的分页?

  1. 为什么需要分页?
    在很多数据是,不可能完全显示数据。进行分段显示.
  2. 分页的方式
    (1)Mysql是使用关键字limit来进行分页的 limit (offset,size )表示从多少索引去多少位.
    (2)Oracle的分页,大部分情况下,我们是记不住了。说思路,要使用三层嵌套查询。在Oracle中实现分页的方法大致分为两种,用ROWNUM关键字和用ROWID关键字
    mysql:String sql ="select * from students order by id limit "+ pageSize*(pageNumber-1) + “,” + pageSize;
    oracle:String sql ="select * from " + (select ,rownum rid from (select * from students order by postime desc) where rid<=" + pagesizepagenumber + “) as t” +“where t>” + pageSize*(pageNumber-1);

3.6、简单讲一下数据库的触发器的使用场景?

触发器,需要有触发条件,当条件满足以后做什么操作。
触发器用处还是很多的,比如校内网、开心网、Facebook,你发一个日志,自动通知好友,其实就是在增加日志时做一个后触发,再向通知表中写入条目。因为触发器效率高。而UCH没有用触发器,效率和数据处理能力都很低。每插入一个帖子,都希望将版面表中的最后发帖时间,帖子总数字段进行同步更新,用触发器做效率就很高。

3.7 、数据库存储过程的使用场景?

数据库存储过程具有如下优点:
1、存储过程只在创建时进行编译,以后每次执行存储过程都不需再重新编译,而一般 SQL 语句每执行一次就编译一次,因此使用存储过程可以大大提高数据库执行速度。
2、通常,复杂的业务逻辑需要多条 SQL 语句。这些语句要分别地从客户机发送到服务器,当客户机和服务器之间的操作很多时,将产生大量的网络传输。如果将这些操作放在一个存储过程中,那么客户机和服务器之间的网络传输就会大大减少,降低了网络负载。
3、存储过程创建一次便可以重复使用,从而可以减少数据库开发人员的工作量。
4、安全性高,存储过程可以屏蔽对底层数据库对象的直接访问,使用 EXECUTE 权限调用存储过程,无需拥有访问底层数据库对象的显式权限。

正是由于存储过程的上述优点,目前常用的数据库都支持存储过程,例如 IBM DB2,Microsoft SQL Server,Oracle,Access 等,开源数据库系统 MySQL 也在 5.0 的时候实现了对存储过程的支持。

定义存储过程:
create procedure insert_Student (_name varchar(50),_age int ,out _id int)begininsert into student value(null,_name,_age);select max(stuId) into _id from student;end;call insert_Student(‘wfz’,23,@id);select @id;

3.8、 用jdbc怎么调用存储过程?

调用过程如下所示:

  1. 创建数据存储
  2. 加载驱动
  3. 获取连接
  4. 设置参数
  5. 执行
  6. 释放连接
    具体代码如下:
    package com.huawei.interview.lym;
    import java.sql.CallableStatement;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    import java.sql.Types;
    public class JdbcTest {
    public static void main(String[] args) {
    // TODO Auto-generated method stub
    Connection cn = null;
    CallableStatement cstmt = null;
    try {
    //这里最好不要这么干,因为驱动名写死在程序中了
    Class.forName(“com.mysql.jdbc.Driver”);
    //实际项目中,这里应用DataSource数据,如果用框架,
    //这个数据源不需要我们编码创建,我们只需Datasource ds = context.lookup()
    //cn = ds.getConnection();
    cn = DriverManager.getConnection(“jdbc:mysql:///test”,“root”,“root”);
    cstmt = cn.prepareCall("{call insert_Student(?,?,?)}");
    cstmt.registerOutParameter(3,Types.INTEGER);
    cstmt.setString(1, “wangwu”);
    cstmt.setInt(2, 25);
    cstmt.execute();
    //get第几个,不同的数据库不一样,建议不写
    System.out.println(cstmt.getString(3));
    } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    finally
    {/try{cstmt.close();}catch(Exception e){}
    try{cn.close();}catch(Exception e){}
    /
    try {
    if(cstmt != null)
    cstmt.close();
    if(cn != null)
    cn.close();
    } catch (SQLException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();

3.9、简单说一下你对jdbc的理解?

  1. JDBC是什么?
    JDBC英文名为:Java Data Base Connectivity(Java数据库连接),官方解释它是Java编程语言和广泛的数据库之间独立于数据库的连接标准的Java API,根本上说JDBC是一种规范,它提供的接口,一套完整的,允许便捷式访问底层数据库。可以用JAVA来写不同类型的可执行文件:JAVA应用程序、JAVA Applets、Java Servlet、JSP等,不同的可执行文件都能通过JDBC访问数据库,又兼备存储的优势。简单说它就是JAVA与数据库的连接的桥梁或者插件,用JAVA代码就能操作数据库的增删改查、存储过程、事务等。
  2. JDBC有什么用?
    我们用JAVA就能连接到数据库;创建SQL或者MYSQL语句;执行SQL或MYSQL的查询数据库;查看和修改结果记录。
    Java database connection java数据库连接.数据库管理系统(mysql oracle等)是很多,每个数据库管理系统支持的命令是不一样的。
    Java只定义接口,让数据库厂商自己实现接口,对于我们者而言。只需要导入对应厂商开发的实现即可。然后以接口方式进行调用.(mysql + mysql驱动(实现)+jdbc)

3.10、 写一个简单的jdbc的程序。写一个访问oracle数据的jdbc程序?

创建存储
加载驱动
(com.mysql.jdbc.Driver,oracle.jdbc.driver.OracleDriver)
获取连接
(DriverManager.getConnection(url,usernam,passord))设置参数 Statement PreparedStatement
cstmt.setXXX(index, value);
执行 executeQuery executeUpdate
释放连接(是否连接要从小到大,必须放到finnaly)

3.11、 JDBC中的PreparedStatement相比Statement的好处

大多数我们都使用PreparedStatement代替Statement设置参数

  1. PreparedStatement是预编译的,比Statement速度快
  2. 代码的可读性和可维护性
    虽然用PreparedStatement来代替Statement会使代码多出几行,但这样的代码无论从可读性还是可维护性上来说.都比直接用Statement的代码高很多档次:
  3. 安全性
    PreparedStatement可以防止SQL注入攻击,而Statement却不能。比如说:
    String sql = “select * from tb_name where name= '”+varname+"’ and passwd=’"+varpasswd+"’";
    如果我们把[’ or ‘1’ = ‘1]作为varpasswd传入进来.用户名随意,看看会成为什么?
    select * from tb_name = ‘随意’ and passwd = ‘’ or ‘1’ = ‘1’;
    因为’1’=‘1’肯定成立,所以可以任何通过验证,更有甚者:
    把[’;drop table tb_name;]作为varpasswd传入进来,则:
    select * from tb_name = ‘随意’ and passwd = ‘’;drop table tb_name;有些数据库是不会让你成功的,但也有很多数据库就可以使这些语句得到执行。
    而如果你使用预编译语句你传入的任何内容就不会和原来的语句发生任何匹配的关系,只要全使用预编译语句你就用不着对传入的数据做任何过虑。而如果使用普通的statement,有可能要对drop等做费尽心机的判断和过虑。

3.12、 数据库连接池作用

  1. 限定数据库的个数,不会导致由于数据库连接过多导致系统运行缓慢或崩溃
  2. 数据库连接不需要每次都去创建或销毁,节约了资源
  3. 数据库连接不需要每次都去创建,响应时间更快。

3.13、 数据库索引

  1. InnoDB支持hash索引吗?
    InnoDB是支持hash索引的,不过其支持的hash索引是自适应的,InnoDB存储引擎会根据表的使用情况自动为表生成hash索引,不能人为干预是否在一张表中生成hash索引。
  2. InnoDB主键索引的叶节点含完整的数据记录,那主键索引文件要比数据文件大吗?–徐财厚
    1).在Innodb 引擎中,主键索引中的叶子结点包含记录数据,主键索引文件即为数据文件。
    2).在 tables 表中统计的data_length数据为主键索引大小,index_length 为统计的这个表中所有辅助索引(二级索引)索引的大小。

3.14、 数据库优化?

做过mysql数据库的优化、其他数据库类似
定位:查找、定位慢查询
优化手段:
1.创建索引:创建合适的索引,我们就可以现在索引中查询,查询到以后直接找对应的记录。
2. 分表:当一张表的数据比较多或者一张表的某些字段的值比较多并且很少使用时,采用水平分表和垂直分表来优化
3. 读写分离:当一台服务器不能满足需求时,采用读写分离的方式进行集群。
4. 缓存:使用redis来进行缓存

3.15、 查找慢查询并定位慢查询?

在项目自验项目转测试之前,在启动mysql数据库时开启慢查询,并且把执行慢的语句写到日志中,在运行一定时间后。通过查看日志找到慢查询语句。
要找出项目中的慢Sql时
1、关闭数据库服务器(关闭服务)
2、把慢查询记录到日志中
3、设置慢查询时间
4、找出日志中的慢查询SQL
5、使用explain 慢查询语句,来详细分析语句的问题.

3.16、 数据库优化之遵循范式?

数据库表设计时需要遵循方式
表的范式,是首先符合1NF, 才能满足2NF , 进一步满足3NF

  1. 1NF: 即表的列的具有原子性,不可再分解,即列的信息,不能分解.只要数据库是关系型数据库(mysql/oracle/db2/sysbase/sql server),就自动的满足1NF.关系型数据库中是不允许分割列的。
  2. 2NF:表中的记录是唯一的.通常我们设计一个主键来实现
  3. 3NF:即表中不要有冗余数据, 就是说,表的信息,如果能够被推导出来,就不应该单独的设计一个字段来存放.(外键)
  4. 反3NF :没有冗余的数据库未必是最好的数据库,有时为了提高运行效率,就必须降低范式标准,适当保留冗余数据。具体做法是:在概念数据模型设计时遵守第三范式,降低范式标准的工作放到物理数据模型设计时考虑。降低范式就是增加字段,允许冗余。 订单和订单项、相册浏览次数和照片的浏览次数

3.17、 选择合适的存储引擎

在开发中,我们经常使用的存储引擎 myisam / innodb/ memory

  1. MyISAM存储引擎
    如果表对事务要求不高,同时是以查询和添加为主的,我们考虑使用myisam存储引擎. 比如 bbs 中的 发帖表,回复表.
  2. INNODB存储引擎:
    对事务要求高,保存的数据都是重要数据,我们建议使用INNODB,比如订单表,账号表.
  3. Memory 存储
    我们数据变化频繁,不需要入库,同时又频繁的查询和修改,我们考虑使用memory, 速度极快.

MyISAM 和 INNODB的区别

  1. 事务安全 myisam不支持事务而innodb支持
  2. 查询和添加速度 myisam不用支持事务就不用考虑同步锁,查找和添加和添加的速度快
  3. 支持全文索引 myisam支持innodb不支持
  4. 锁机制 myisam支持表锁而innodb支持行锁(事务)
  5. 外键 MyISAM 不支持外键, INNODB支持外键. (通常不设置外键,通常是在程序中保证数据的一致)

3.18、 数据库优化

3.18.1、数据库优化之索引

索引(Index)是帮助DBMS高效获取数据的数据结构。
分类:普通索引/唯一索引/主键索引/全文索引
普通索引:允许重复的值出现
唯一索引:除了不能有重复的记录外,其它和普通索引一样(用户名、用户身份证、email,tel)
主键索引:是随着设定主键而创建的,也就是把某个列设为主键的时候,数据库就会給改列创建索引。这就是主键索引.唯一且没有null值
全文索引:用来对表中的文本域(char,varchar,text)进行索引, 全文索引针对MyIsam
explain select * from articles where match(title,body) against(‘database’);【会使用全文索引】

3.18.2、 索引使用小技巧?

索引弊端
1.占用磁盘空间。
2.对dml(插入、修改、删除)操作有影响,变慢。
使用场景:
a: 肯定在where条件经常使用,如果不做查询就没有意义
b: 该字段的内容不是唯一的几个值(sex)
c: 字段内容不是频繁变化.

具体技巧:
1:对于创建的多列索引(复合索引),不是使用的第一部分就不会使用索引。
2:alter table dept add index my_ind (dname,loc); // dname 左边的列,loc就是右边的列
explain select * from dept where dname=‘aaa’\G 会使用到索引
explain select * from dept where loc=‘aaa’\G 就不会使用到索引
3. 对于使用like的查询,查询如果是’%aaa’不会使用到索引而‘aaa%’会使用到索引。
explain select * from dept where dname like ‘%aaa’\G不能使用索引
explain select * from dept where dname like ‘aaa%’\G使用索引.
所以在like查询时,‘关键字’的最前面不能使用 % 或者 _这样的字符.,如果一定要前面有变化的值,则考虑使用 全文索引->sphinx.
4:如果条件中有or,有条件没有使用索引,即使其中有条件带索引也不会使用。换言之,就是要求使用的所有字段,都必须单独使用时能使用索引.
5:如果列类型是字符串,那一定要在条件中将数据使用引号引用起来。否则不使用索引。
expain select * from dept where dname=’111’;
expain select * from dept where dname=111;(数值自动转字符串)
expain select * from dept where dname=qqq;报错
也就是,如果列是字符串类型,无论是不是字符串数字就一定要用 ‘’ 把它包括起来.
6:如果mysql估计使用全表扫描要比使用索引快,则不使用索引。
7:表里面只有一条记录

3.18.3、 数据库优化之分表?

分表分为水平(按行)分表和垂直(按列)分表
根据经验,Mysql表数据一般达到百万级别,查询效率会很低,容易造成表锁,甚至堆积很多连接,直接挂掉;水平分表能够很大程度较少这些压力。
按行数据进行分表。
如果一张表中某个字段值非常多(长文本、二进制等),而且只有在很少的情况下会查询。这时候就可以把字段多个单独放到一个表,通过外键关联起来。
水平分表策略:
1.按时间分表
这种分表方式有一定的局限性,当数据有较强的实效性,如微博发送记录、微信消息记录等,这种数据很少有用户会查询几个月前的数据,如就可以按月分表。
2.按区间范围分表
一般在有严格的自增id需求上,如按照user_id水平分表:
table_1 user_id从1~100w
table_2 user_id从101~200w
table_3 user_id从201~300w
3.hash分表*****
通过一个原始目标的ID或者名称通过一定的hash算法计算出数据存储表的表名,然后访问相应的表。

3.18.4、 数据库优化之读写分离

一台数据库支持的最大并发连接数是有限的,如果用户并发访问太多。一台服务器满足不要要求是就可以集群处理。Mysql的集群处理技术最常用的就是读写分离。
主从同步
数据库最终会把数据持久化到磁盘,如果集群必须确保每个数据库服务器的数据是一直的。能改变数据库数据的操作都往主数据库去写,而其他的数据库从主数据库上同步数据。
读写分离
使用负载均衡来实现写的操作都往主数据去,而读的操作往从服务器去。

3.18.5、 数据库优化之缓存

在持久层(dao)和数据库(db)之间添加一个缓存层,如果用户访问的数据已经缓存起来时,在用户访问时直接从缓存中获取,不用访问数据库。而缓存是在操作内存级,访问速度快。
作用:减少数据库服务器压力,减少访问时间。
Java中常用的缓存有,
1、hibernate的二级缓存。该缓存不能完成分布式缓存。
2、可以使用redis(memcahe等)来作为中央缓存。 对缓存的数据进行集中处理

3.18.6、 语句优化小技巧

对sql语句优化的常用方法:
(1)子查询变成left join
(2)limit 分布优化,先利用ID定位,再分页
(3)or条件优化,多个or条件可以用union all对结果进行合并(union all结果可能重复)
(4)减少不必要的排序
(5)where代替having,having 检索完所有记录,才进行过滤
(6)避免嵌套查询
(7)对多个字段进行等值查询时,联合索引
(8)DDL优化:通过禁用索引来提供导入数据性能 。这个操作主要针对有数据库的表,追加数据
例如://去除键alter table test3 DISABLE keys;
//批量插入数据insert into test3 select * from test;
//恢复键alter table test3 ENABLE keys;
(9)修改事务提交方式(导入)(变多次提交为一次或者批量插入)
set autocommit=0 关闭//批量插入set autocommit=1 开启
insert into test values(1,2);
insert into test values(1,3);
insert into test values(1,4);//合并多条为一条
insert into test values(1,2),(1,3),(1,4)

3.19、 jdbc批量插入几百万数据怎么实现?

  1. 变多次提交为一次
  2. 使用Sql语句进行分页limit(stat,long)
  3. 使用批量操作
    省出的时间可观。
    像这样的批量插入操作能不使用代码操作就不使用,可以使用存储过程来实现。

3.20、inner join, outer join, cross join

  1. 以A,B两张表为例
    A left join B:选出A的所有记录,B表中没有的以null 代替
    right join 同理
  2. inner join
    A,B的所有匹配的记录都选出
  3. cross join (笛卡尔积)
    A中的每一条记录和B中的每一条记录生成一条记录
    例如A中有4条,B中有4条,cross join 就有16条记录

3.21、外连接和内连接各自什么什么时候使用?有何作用?

  1. 内连接:返回连接表中符合连接条件和查询条件的数据行(所谓的连接表就是早数据库中在做查询的时候形成的中间表)
    (1)隐式内连接: 形成的中间表为两个表的笛卡尔积
    select o.id,o.order_number,c.id,c.name from customers c, orders o where c.id=o.customer_id;
    (2)显示内连接:形成的中间表为两个表经过on条件过滤后的笛卡尔积
    select o.id,o.order_number,c.id,c.name from customers c inner join orders o on c.id=o.customer_id;
  2. 外连接:外连接不但返回符合连接和查询条件的数据行,还返回不符合条件的一些行。外连接分为三类:左外连接(left outer join)、右外连接(right outer join)、全外连接(full outer join)
    (1)左外连接:还会返回左标中不符合连接条件但是符合查询查询条件的数据行
    select o.id,o.order_number,o.customer_id,c.id,c.name from orders o left outer join customers c on c.id=o.customer_id;
    (2)右外链接:还会返回右标中不符合连接条件但是符合查询查询条件的数据行
    select o.id,o.order_number,o.customer_id,c.id,c.name from orders o right outer join customers c on c.id=o.customer_id;
  3. 全外连接:全外=左外 union 右外,相当于数学合集(去掉重复)
    select o.id,o.order_number,o.customer_id,c.id,c.name from orders o full outer join customers c on c.id=o.customer_id;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值