java开发面试问题

Java面试题:java的垮平台原理
为何要跨平台使用?????
其实说白了就是个操做系统支持的指令集是不同的。咱们的程序须要再不一样的操做系统上运行这些代码。
可是不要说jvm是跨平台的,而真正跨平台的是 Java 程序,而不是 JVM。JVM 是用 C/C++ 开发的,是编译后的机器码,不能跨平台,不一样平台下须要安装不一样版本的 JVMhtml

答:
咱们编写的 Java 源码,编译后会生成一种 .class 文件,称为字节码文件。Java 虚拟机(JVM)就是负责将字节码文件翻译成特定平台下的机器码而后运行,也就是说,只要在不一样平台上安装对应的 JVM,就能够运行字节码文件,运行咱们编写的 Java 程序。
而这个过程,咱们编写的 Java 程序没有作任何改变,仅仅是经过 JVM 这一 “中间层” ,就能在不一样平台上运行,真正实现了 “一次编译,处处运行” 的目的。前端

Java面试题:JVM由哪些部分组成?
答:JVM 的结构基本上由 4 部分组成:
• 类加载器,在 JVM 启动时或者类运行时将须要的 class 加载到 JVM 中
• 执行引擎,执行引擎的任务是负责执行 class 文件中包含的字节码指令,至关于实际机器上的 CPU
• 内存区,将内存划分红若干个区以模拟实际机器上的存储、记录和调度功能模块,如实际机器上的各类功能的寄存器或者 PC 指针的记录器等
• 本地方法调用C 或 C++ 实现的本地,调用方法的代码返回结果java

Java面试题:类加载器是有了解吗?
答:顾名思义,类加载器(class loader)用来加载 Java 类到 Java 虚拟机中。通常来讲, Java 源程序(.java 文件)在通过 Java 编译器编译以后就被转换成 Java 字节代码(.class 文件)。
类加载器负责读取 Java 字节代码,并转换成 java.lang.Class类的一个实例。每一个这样的实例用来表示一个 Java 类。经过此实例的 newInstance()方法就能够建立出该类的一个对象?
Java面试题:Java 虚拟机是如何断定两个 Java 类是相同的?
答:Java 虚拟机不只要看类的全名是否相同,还要看加载此类的类加载器是否同样。只有二者都相同的状况,才认为两个类是相同的。即使是一样的字节代码,被不一样的类加载器加载以后所获得的类,也是不一样的。好比一个 Java 类 com.example.Sample,编译以后生成了字节代码文件 Sample.class。两个不一样的类加载器 ClassLoaderA和 ClassLoaderB分别读取了这个 Sample.class文件,并定义出两个 java.lang.Class类的实例来表示这个类。这两个实例是不相同的。对于 Java 虚拟机来讲,它们是不一样的类。试图对这两个类的对象进行相互赋值,会抛出运行时异常 ClassCastException。mysql

双亲委派模型(Parent Delegation Model)
该模型要求除了顶层的 Bootstrap class loader 启动类加载器外,其他的类加载器都应当有本身的父类加载器。子类加载器和父类加载器不是以继承(Inheritance)的关系来实现,而是经过组合(Composition)关系来复用父加载器的代码。每一个类加载器都有本身的命名空间(由该加载器及全部父类加载器所加载的类组成,在同一个命名空间中,不会出现类的完整名字(包括类的包名)相同的两个类;在不一样的命名空间中,有可能会出现类的完整名字(包括类的包名)相同的两个类)
面试官:双亲委派模型的工做过程?
答:
1.当前 ClassLoader 首先从本身已经加载的类中查询是否此类已经加载,若是已经加载则直接返回原来已经加载的类。
每一个类加载器都有本身的加载缓存,当一个类被加载了之后就会放入缓存,
等下次加载的时候就能够直接返回了。
2.当前 ClassLoader 的缓存中没有找到被加载的类的时候,委托父类加载器去加载,父类加载器采用一样的策略,首先查看本身的缓存,而后委托父类的父类去加载,一直到 bootstrap ClassLoader.
当全部的父类加载器都没有加载的时候,再由当前的类加载器加载,并将其放入它本身的缓存中,以便下次有加载请求的时候直接返回。
面试官:为何这样设计呢?
解析:这是对于使用这种模型来组织累加器的好处
答:主要是为了安全性,避免用户本身编写的类动态替换 Java 的一些核心类
同时也避免了重复加载,由于 JVM 中区分不一样类,不只仅是根据类名,相同的 class 文件被不一样的 ClassLoader 加载就是不一样的两个类,若是相互转型的话会抛java.lang.ClassCaseException.程序员

Jvm垃圾回收算法,原理
    引用计数:标记-清除:复制算法:标记-整理:分代收集算法:

Java面试题:java面向对象的特征
面向对象的特征:封装,抽象,继承,多态
你们必定要注意:回答比较抽象的问题的时候必定要举例子web

Java面试题:装箱和拆箱
?????有了基本的数据类型,咱们为何还要有包装类型。
说白了。。。就是体现面向对象的思想
基本类型,int ,flout,double, Bollean等
BooleanBoolean
IntInteger
自动装箱是jdk1.5之后增长的功能
装箱:就是把基本数据类型转化成对应的包装类型。
总结一下:
Java是一个面向对象的语言,而基本的数据类型,不具有面向对象的特性。
Java面试题:讲一下java中的集合
Java集合分为两种,一个是value类型的,另外一个就是key.value (Map)两种
List是有序的,能够重复的
Set是无序的,不能够重复的(根据equals和hashcode来判断。)也就是说若是一个对象要存储到set当中,就必需要重写咱们的equals和hashcode的方法。
Map就是key.value的类型数据。
Hashmap存储原理:
1, API中的经常使用的属性
2, Hashmap、默认四个构造方法
3, Hash碰撞 ,桶的概念
4, Entry【】--》next属性面试

Hashmap弹性伸缩的角度不足:
谈不足的时候必定要谈一下时间复杂度和空间复杂度。
在用hashmap的时候要给一个初始容量。ajax

Java面试题:ArrayList 和LinkedList的区别
是什么?区别???使用场景
ArrayList底层使用的是数组,LinkedList底层使用的是链表
数组查询的时候具备查询特定元素比较快。而插入和删除和修改比较慢(数组在内存当中是一块联系的内存,若是插入或者删除是须要移动内存的)
链表不要求内存是连续的,当查询的时候,须要从头部一个一个的找,因此查询效率低,而插入的时候不须要移动内存,只须要改变引用的指向。
应用场景:ArrayList使用在查询比较多,答案是插入和删除比较少的状况,而LinkedList使用在查询比较少而插入和删除比较多的状况redis

Java面试题:HashMap和HashTable的区别
相同点:均可以用来存储Key.value型数据
区别:
一、 hashMap是能够把null做为能够key或者value,而hashtable不能够
二、 HashMap是线程不安全的,效率较高,而hashtable是线程安全的,效率较低
我想线程安全我又想效率比较高?????what?????算法

原理—》就是把整个map分为N个segment(相似于hashtable),能够提供相同的线程安全,可是效率提高N。默认提高的16倍。

Java面试题:线程的的实现方式?怎么启动线程?怎么区分线程?
一、 实现方式

a) 经常使用的经过继承Thread类来实现一个线程

b) 经过实现Runnable接口来实现一个线程。

c) 经过实现Callable借口来实现一个线程
2.怎么启动????
咱们经过
Thread thread=new Thread(继承了thread类的对象\或者把实现了runnable接口的对象)
thread.start();
启动线程的时候用的是start()方法,而后执行线程的时候用的是run()方法;
二、 怎么样区分线程???

a) 在一个系统当中咱们有不少线程,每一个系统都会打印日志,我想区分一下究竟是哪一个系统打印的???
thread.setName(设置一个线程的名称),这是一个规范,大家未来在开发的时候写完多线程必定要及记得设置线程名称。
Java面试题:线程并发库和线程池的做用
简单了解过就行
Jdk1.5的时候增长了Doug Lea的并发库,大大的增长了便利性。Java.util.current
包提供了对线程的优化,包括管理的各项操做。--》线程池的建立,以及线程的生命周期的管理。
Java经过Executors提供四个静态方法来建立四种线程 池:
1, newCachedThreadPool,可缓存的线程池
2, newFixedThreadPool,建立一个定长线程池
3, newScheduledThreadPool,建立一个定长线程池,支 持定时以及周期性任务
4, newSingleThreadExcutor,建立一个单线程化的线程池
线程池的做用:
一、 限定了线程的个数,不会致使因为线程过多致使系统运行缓慢或崩溃
二、 节约资源,咱们不会去关心它的建立于销毁。
Java面试题:设计模式和经常使用的设计模式
设计模式就是通过前人总结和实践出来的,设计过程能够反复的使用,能够解决特定的问题的设计方法
经常使用的设计模式:
一、单例(饿汉式和饱汉式)
一、构造方法私有化,
二、要本身建立一个对象
三、提供对外获取对象的方法。
二、工厂设计模式:
Spring IOC就是用的就是工厂模式
三、 代理模式:

a) Spring AOP用的就是动态代理
Java面试题:http get post请求的区别
Get和post都是http的请求方式,用户能够经过不一样的http请求方式完成对资源(url)的操做,get , post,put,delete,对应的是我们对资源的,查,改,增,删,四个操做,具体的来讲通常状况下,get用于获取、查询资源信息。而post通常用于更新资源信息
区别:
一、 get请求提交的数据会在地址栏显示出来,而post请求不会在地址栏显示出来
二、 传输数据的大小
http get请求因为浏览器对地址长度有限制,因此就致使对传输的数据有限制,而post不会
3,安全性的问题,post的安全性要比get的安全性要高。
Java面试题:Servlet的生命周期

Servlet有良好的生命周期的定义,他包括加载和实例化、初始化、处理请求以及服务结束。这个生命周期是由javax.servlet.Servlet接口中的int 、service、destroy方法来描述。
        Servlet启动时,开始加载servlet生命周期的开始,servlet被服务器实例化后,容器运行其init方法,请求到达时运行去service方法,service方法会自动派遣运行对应的doXXX等。而后当服务器决定将实例销毁的时候,这个时候调用destroy方法

Java面试题:jsp和Servlet的相同点和不一样点
Jsp本质:
Jsp是servlet的扩展,全部的jsp文件都会被翻译成为一个继承HttpServlet的类,而后对外提供服务
不一样点:
一、Jsp偏重于视图,而servlet只要用于控制逻辑
二、servlet若是想要实现html的功能,比喻使用writer输出对应的html,这个比较麻烦,而jsp是servlet和html组合起来的,作界面展现比较方便,可是想要嵌入逻辑比较复杂。
Java面试题:Session和Cookie的区别和使用场景,你在项目当中哪些地方用到了?????
Session和cookie都是会话跟踪技术,cookie是经过在客户端记录信息来肯定用户身份,session他是经过服务端来记录用户的身份。。可是session的实现依赖于cookie,sessionId(session的惟一标识)
区别:
一、 Session放在服务器,而cookie放在浏览器
二、 Cookie不是很安全,别人能够经过分析你本地的cookie进行cookie的欺诈,考虑到安全,咱们用session
三、 Session会在服务器保存必定的时间,也就是说,当访问增多的时候,会比较占用服务器的性能,若是未来考虑到服务器压力的时候,咱们要用cookie。
四、 Cookie保存的数据不能超过4k,不少浏览器都限制一个站点最多保存50个cookie
五、 我的建议:
要将我的信息保存到session当中
其余的信息,若是须要保留咱们放到cookie:购物车信息。

Java面试题:关系型数据库的三范式
范式?????说白了就是规范
想要知足第二范式,你就必需要知足第一范式,而后,你想要知足第三范式,你就必需要知足第一第二范式
第一范式(1nf),列数据不可分割,是指数据库表的每一列都是不可分割的基本数据项,同一列当中不能有多个值,对应到我们的pojo对象当中,你一个对象的属性不能有多个值。

未来的设计不能这样设计,应为地址还能够再分

可是你们须要注意的是,拆不拆要看业务,好比咱们未来要按照国家和省份来分类汇总,那咱们就要把它拆掉,可是若是这个字段仅仅起到一个字符串的做用,那咱们就不必拆分,你们明白吧????
        第二范式(2nf),针对主键:

1.要求数据库当中的每一行必须能够被惟一的区分,你想要给惟一的区分????加一列设成主键。
2.另外非主键的列要依赖主键,最好第二范式要让每一个表只描述一件事情

实际,产品的编号和订单的编号没有明确的关系,购买日期和订单编号有关系。
价格和订单编号也没有关系,而与产品编号有关,那么咱们应该拆分为

第三范式(2nf),第三范式、要求一个数据库中非主键列不依赖于其余非主键列

学号和姓名存在传递,由于(学号,姓名)成绩 学号成绩 姓名成绩,冗余了,只需保留一个

反三范式:订单(总价)和订单项(单价)。咱们能够经过每个订单去算总价,这是能够的,可是每次算的时候都得合并计算,影响效率,因此有时候该反的时候就得反
因此什么是老大,需求是老大!!!!需求>>结构设计

Java面试题:事务的四大特征
事务是什么??what????
事务是并发控制的单位,是用户定义的一个操做序列,这些操做要么作,要么不作,是一个不可分割的单位。
转帐---》1000 a—》b 500 a500 b1500 a转帐成功并不表明这件事情已经成功了,也就是说,当a转帐成功,b收到钱之后这个事情才算结束 。
事务必须知足四大特性:原子性,一致性,隔离性,持久性(持续性)
原子性:表示事务内操做不可分割,要么都成功,要么都失败。
一致性:要么都成功,要么都失败,可是后面失败了的要对前面的操做进行回滚,
隔离性:一个事务开始后,后面不能有其余事务干扰。
持久性:表示事务开始了,就不能终止
Java面试题:触发器的使用场景?
触发器,what?????
触发器须要有触发条件,当条件知足以后作相应的操做
好比:学校的校园网,开心网,facebook,当你发一个日志,会自动通知好友,本质就是当你增长一个日志的时候作了一个后触发。再向数据库表当中写入相应的操做。
CREATE TRIGGER trigger_name
trigger_time
trigger_event ON tbl_name
FOR EACH ROW
trigger_stmt
其中:
trigger_name:标识触发器名称,用户自行指定;
trigger_time:标识触发时机,取值为 BEFORE 或 AFTER;
trigger_event:标识触发事件,取值为 INSERT、UPDATE 或 DELETE;
tbl_name:标识创建触发器的表名,即在哪张表上创建触发器;
trigger_stmt:触发器程序体,能够是一句SQL语句,或者用 BEGIN 和 END 包含的多条语句。
好处:????效率高。在贴吧发一条帖子,都但愿在页面当中展示咱们的最后发帖时间,帖子总数(保证他们的同步更新。)这个时候就能够用到触发器并且效率很是高。
Java面试题:存储过程的优势
create proceduce insert_student(xxx xxx xxx)
begin
insert 。。。。。
select 。。。。。
sql语句
end;

存储过程有什么优势???????******

一、 存储过程只在建立是编译,之后每次执行存储过程都不须要在从新编译,而普通的sql语句每执行一次就编译一次,所以使用存储过程能够大大提升数据库的执行速度。
二、 一般状况下,复杂的业务逻辑须要执行多条sql语句,这些语句分别都要从客户端去连接服务器端,这个时候就会产生大量的网络传输,
这个时候,结合业务,咱们应该吧这些sql语句放在咱们的存储过程中,提升咱们的效率,下降咱们的网络负载
三、 存储过程建立一次能够屡次调用,能够减小咱们开发人员的工做量。
四、 安全性高,存储过程能够屏蔽对底层数据库对象的直接访问。
如今的数据库支持咱们的存储过程,IBM DB2,oracle。Mysql(5.0) ACCESS。

Java面试题:jdbc调用存储过程
过程和jdbc调用数据库的过程差很少
加载驱动
获取连接
设置参数
执行sql
释放资源

Java面试题:数据库链接池的做用
一、 限定了数据库的个数。不会致使因为数据库连接过多致使系统运行缓慢
二、 数据库链接池,不须要每次都去建立和销毁,节约资源
三、 响应时间比较快

Java面试题:简单介绍了一下Ajax
首先必需要说一下??what????做用是什么????使用场景,怎么使用??
什么是ajax????异步的js和xml
做用是什么????咱们能够经过ajax来与服务器进行交互,进行数据的交换,能够实现局部刷新,这就意味着,咱们能够不从新加载整个网页的状况下,对网页进行更新。
怎么实现????咱们经过XmlHttpRequest这个对象,使用这个对象来异步的向服务器发送请求,获取响应,完成局部刷新。
使用场景?????登陆失败不跳转页面,注册时用户名是否存在。二级联动,三级联动

Java面试题:Spring MVC的执行流程
一、 用户向服务器发送请求,请求被spring前端控制器捕获,
二、 前端控制器对请求的url进行解析,获得url根据这个url调用HandlerMapping 得到该handler配置的相关信息(包括handler对象以及handler对象对应的拦截器)返回的是以handlerExcutionChain对象的形式进行返回
三、 前端控制器,根据得到的handler,选择一个合适的handlerAdapter,获取到request中的数据模型,填充到handler,并开始执行整个流程,而后向前端控制器返回model and view
四、 前端控制器根据返回的model and view,选择一个合适的ViewResolver对象。
五、 最后一个就是经过ViewResolver对象结合model and view进行视图渲染,将渲染结果返回给客户端

Java面试题:简单介绍一下Spring或者Spring的两大核心
Spring是将j2EE的应用程序框架,轻量级,能够单独使用也能够整合咱们 struts2 mybatis 。-------EJB
IOC和DI
AOP
Java面试题:AOP是什么?都用它作什么?
AOP:面向切面编程。
用它来干吗???
一、 事务的控制
二、 权限的判断
三、 日志
四、 。。。。。。。。。。

Java面试题:Spring事务的传播特性和隔离级别
1) PROPAGATION_REQUIRED ,默认的spring事务传播级别,使用该级别的特色是,若是上下文中已经存在事务,那么就加入到事务中执行,若是当前上下文中不存在事务,则新建事务执行。因此这个级别一般能知足处理大多数的业务场景。
2)PROPAGATION_SUPPORTS ,从字面意思就知道,supports,支持,该传播级别的特色是,若是上下文存在事务,则支持事务加入事务,若是没有事务,则使用非事务的方式执行。因此说,并不是全部的包在transactionTemplate.execute中的代码都会有事务支持。这个一般是用来处理那些并不是原子性的非核心业务逻辑操做。应用场景较少。
3)PROPAGATION_MANDATORY , 该级别的事务要求上下文中必需要存在事务,不然就会抛出异常!配置该方式的传播级别是有效的控制上下文调用代码遗漏添加事务控制的保证手段。好比一段代码不能单独被调用执行,可是一旦被调用,就必须有事务包含的状况,就可使用这个传播级别。
4)PROPAGATION_REQUIRES_NEW ,从字面便可知道,new,每次都要一个新事务,该传播级别的特色是,每次都会新建一个事务,而且同时将上下文中的事务挂起,执行当前新建事务完成之后,上下文事务恢复再执行。
问题 :若是其中一个子事务回滚了,父事务是否回滚?答案是不会,由于子事务是新建事务,父事务已经被挂起,二者不会受到影响。
再问:若是父事务回滚了,子事务是否回滚?答案是不会,一样的理由。可是能够手动控制一旦子事务回滚,父事务也回滚。

5)PROPAGATION_NOT_SUPPORTED ,这个也能够从字面得知,not supported ,不支持,当前级别的特色就是上下文中存在事务,则挂起事务,执行当前逻辑,结束后恢复上下文的事务。
这个级别有什么好处?能够帮助你将事务很可能的缩小。咱们知道一个事务越大,它存在的风险也就越多。因此在处理事务的过程当中,要保证尽量的缩小范围。好比一段代码,是每次逻辑操做都必须调用的,好比循环1000次的某个非核心业务逻辑操做。这样的代码若是包在事务中,势必形成事务太大,致使出现一些难以考虑周全的异常状况。因此这个事务这个级别的传播级别就派上用场了。用当前级别的事务模板抱起来就能够了。
6)PROPAGATION_NEVER ,该事务更严格,上面一个事务传播级别只是不支持而已,有事务就挂起,而PROPAGATION_NEVER传播级别要求上下文中不能存在事务,一旦有事务,就抛出runtime异常,强制中止执行!这个级别上辈子跟事务有仇。
7)PROPAGATION_NESTED ,字面也可知道,nested,嵌套级别事务。该传播级别特征是,若是上下文中存在事务,则嵌套事务执行,若是不存在事务,则新建事务。Propagation_required_new 老是开启一个新的事务,若是有一个事务存在,就将已存在的事务挂起
隔离级别:
脏读 :所谓的脏读,其实就是读到了别的事务回滚前的脏数据。好比事务B执行过程当中修改了数据X,在未提交前,事务A读取了X,而事务B却回滚了,这样事务A就造成了脏读。
不可重复读 :不可重复读字面含义已经很明了了,好比事务A首先读取了一条数据,而后执行逻辑的时候,事务B将这条数据改变了,而后事务A再次读取的时候,发现数据不匹配了,就是所谓的不可重复读了。
幻读 :小的时候数手指,第一次数十10个,第二次数是11个,怎么回事?产生幻觉了?
幻读也是这样子,事务A首先根据条件索引获得10条数据,而后事务B改变了数据库一条数据,致使也符合事务A当时的搜索条件,这样事务A再次搜索发现有11条数据了,就产生了幻读。
Java面试::数据库优化方面的事情
一、 查询,并定位慢查询
二、 优化手段

a) 建立索引:建立合适的索引,咱们就能够先在索引当中查询,经过索引找到对应的记录

b) 分表。也就是说当一张表的数据比较多的时候,或者一张表当中某些字段的值比较多而且不怎么经常使用的时候咱们要分表。水平拆分和垂直拆分

c) 读写分离:当一个服务器不能知足需求的时候,咱们能够创建数据库集群

d) 缓存:也就是咱们要用redis。
Java面试::若是查询和定位慢查询
slow_query_log= 1
long_query_time= 1
slow_query_log_file=c:/slow.log
在项目当中,给测试人员执以前,再启动mysql数据的时候,咱们开启慢查询,而且把慢查询语句打到咱们的日志当中,运行一段时间,看看哪些语句执行效率最慢

Java面试::选择合适的数据库引擎
show engines;
SHOW VARIABLES LIKE 'storage_engine';
在开发当中,咱们常常用的存储引擎
Myisam innodb memory
Myisam 存储引擎
MyISAM基于ISAM存储引擎,并对其进行扩展。它是在Web、数据仓储和其余应用环境下最常使用的存储引擎之一。MyISAM拥有较高的插入、查询速度,但不支持事物。
Innodb 存储引擎
InnoDB是事务型数据库的首选引擎,支持事务安全表(ACID),支持行锁定和外键
Memory
MEMORY存储引擎将表中的数据存储到内存中,当咱们的数据频繁变化的时候,并且不须要入库,这个时候用memory存储引擎。
Myisam和innodb的区别:
1, 事务安全 myisam不支持事务,而innodb支持
2, 查询和添加速度, myisam他由于不支持事务,因此就表明不须要考虑同步锁,也就是说查找和添加的速度快
3, 支持全文检索方面 myisam支持 innodb不支持
4, 锁机制 myisam支持的是表锁 innodb支持的是行锁
5, 外键方面 myisam不支持外键 innodb支持外键

Java面试::选择合适的索引
What???--》索引是帮助dbms(数据库管理)用来高效获取数据的数据结构
分类 普通索引\惟一索引\主键索引\全文索引
普通索引:容许重复的值出现
惟一索引:除了不能有重复的数据记录外,和普通索引同样
主键索引:是随着设定主键而建立的,也就是说把某个列设为主键的时候,这个时候数据库会给该列建立索引,注意!!主键索引是惟一的且不能是null值
全文索引:整个表中的文本域都是索引
Java面试::使用索引的一些技巧
索引有什么弊端!!!!
1,占用磁盘空间。
2, 对dml(插入、修改、删除)操做有影响,会变慢。
索引的使用场景:
,1:在where条件常用,若是不作查询基本上索引没有什么意义
2:该字段的内容不是惟一的几个值
3:字段的内容不能频繁的变化
具体的技巧:
1:对于建立多列索引的时候(复合索引),记住,若是不是使用的第一部分就不会使用索引

2:对于使用like语句的时候没若是查询是‘%aaa’ 不会使用索引,’aaa%’ 会使用索引
3:当你的sql语句有or的时候,只要是有条件没有使用索引,其余条件即便带索引也不会使用。
4:若是列类型是字符串,那必定要在条件中讲数据使用引号引发来,不然就不能使用索引

5:Mysql若是感受我遍历整个表都比使用索引快,那么它自动就不使用索引了
Java面试::数据库优化之分表
根据经验,mysql数据达到百万级别,查询效率就很是低了,就会形成锁表,甚至堆积多链接,致使mysql直接挂掉,水平分表就能够减小压力。
按行数据进行分表:
若是一张表当中某个字段很是多(长文本,二进制),不多状况下查询,这个时候咱们就要考虑把这些字段单独放到一个表中,经过外键关联起来。
场景:考试详情 咱们就关心这我的考了多少分,不关心学习过程
水平分表策略:
一、 按时间分表 *****

a) 微博,qq,咱们想要查询月份动态,或者月份的缴费状况,这些有规律性的数据内容,咱们能够按时间分表
二、 按区间分表:数据库当中的自增id
三、 Hash分表********

a) 经过一个原始目标的id或者名称经过必定的合适算法,算出来数据库的表名称。而后访问相应的表。
Java面试::数据库的读写分离
背景:一台数据库支持最大的并发连接数量是有限的,若是用户访问量加大,一台服务器是知足不了咱们的需求,因此咱们用集群的方式来实现。
主从同步
读写分离
Java面试::数据库优化之缓存
Java当中咱们持久层和数据库这个层面 常见的缓存有hb的二级缓存,mb二级缓存,这些缓存都不支持分布式缓存
咱们能够用redis来做为中央缓存

Java面试::sql语句优化小技巧

  1. 对查询进行优化,要尽可能避免全表扫描,首先应考虑在 where 及 order by 涉及的列上创建索引。
  2. 应尽可能避免在 where 子句中对字段进行 null 值判断,不然将致使引擎放弃使用索引而进行全表扫描
  3. 应尽可能避免在 where 子句中使用 != 或 <> 操做符,不然将引擎放弃使用索引而进行全表扫描。
  4. 应尽可能避免在 where 子句中使用 or 来链接条件,若是一个字段有索引,一个字段没有索引,将致使引擎放弃使用索引而进行全表扫描,如
    select id from t where num=10 or Name = 'admin'
    能够这样查询:
    select id from t where num = 10union allselect id from t where Name = 'admin'
  5. select count(*) from table;这样不带任何条件的count会引发全表扫描,而且没有任何业务意义,是必定要杜绝的。
    调优参数:
  6. back_log:back_log值指出在MySQL暂时中止回答新请求以前的短期内多少个请求能够被存在堆栈中。也就是说,若是MySql的链接数据达到max_connections时,新来的请求将会被存在堆栈中,以等待某一链接释放资源,该堆栈的数量即back_log,若是等待链接的数量超过back_log,将不被授予链接资源。能够从默认的50升至500
  7. wait_timeout:数据库链接闲置时间,闲置链接会占用内存资源。能够从默认的8小时减到半小时
  8. max_user_connection: 最大链接数,默认为0无上限,最好设一个合理上限
  9. thread_concurrency:并发线程数,设为CPU核数的两倍
  10. skip_name_resolve:禁止对外部链接进行DNS解析,消除DNS解析时间,但须要全部远程主机用IP访问
  11. key_buffer_size:索引块的缓存大小,增长会提高索引处理速度,对MyISAM表性能影响最大。对于内存4G左右,可设为256M或384M,经过查询show status like 'key_read%',保证key_reads / key_read_requests在0.1%如下最好
  12. innodb_buffer_pool_size:缓存数据块和索引块,对InnoDB表性能影响最大。经过查询show status like 'Innodb_buffer_pool_read%',保证(Innodb_buffer_pool_read_requests – Innodb_buffer_pool_reads) / Innodb_buffer_pool_read_requests越高越好
  13. innodb_additional_mem_pool_size:InnoDB存储引擎用来存放数据字典信息以及一些内部数据结构的内存空间大小,当数据库对象很是多的时候,适当调整该参数的大小以确保全部数据都能存放在内存中提升访问效率,当太小的时候,MySQL会记录Warning信息到数据库的错误日志中,这时就须要该调整这个参数大小
  14. innodb_log_buffer_size:InnoDB存储引擎的事务日志所使用的缓冲区,通常来讲不建议超过32MB
  15. query_cache_size:缓存MySQL中的ResultSet,也就是一条SQL语执行的结果集,因此仅仅只能针对select语句。当某个表的数据有任何任何变化,都会致使全部引用了该表的select语句在Query Cache中的缓存数据失效。因此,当咱们的数据变化很是频繁的状况下,使用Query Cache可能会得不偿失。根据命中率(Qcache_hits/(Qcache_hits+Qcache_inserts)*100))进行调整,通常不建议太大,256MB可能已经差很少了,大型的配置型静态数据可适当调大.
    能够经过命令show status like 'Qcache_%'查看目前系统Query catch使用大小
  16. read_buffer_size:MySql读入缓冲区大小。对表进行顺序扫描的请求将分配一个读入缓冲区,MySql会为它分配一段内存缓冲区。若是对表的顺序扫描请求很是频繁,能够经过增长该变量值以及内存缓冲区大小提升其性能
  17. sort_buffer_size:MySql执行排序使用的缓冲大小。若是想要增长ORDER BY的速度,首先看是否可让MySQL使用索引而不是额外的排序阶段。若是不能,能够尝试增长sort_buffer_size变量的大小
  18. read_rnd_buffer_size:MySql的随机读缓冲区大小。当按任意顺序读取行时(例如,按照排序顺序),将分配一个随机读缓存区。进行排序查询时,MySql会首先扫描一遍该缓冲,以免磁盘搜索,提升查询速度,若是须要排序大量数据,可适当调高该值。但MySql会为每一个客户链接发放该缓冲空间,因此应尽可能适当设置该值,以免内存开销过大。
  19. record_buffer:每一个进行一个顺序扫描的线程为其扫描的每张表分配这个大小的一个缓冲区。若是你作不少顺序扫描,可能想要增长该值
  20. thread_cache_size:保存当前没有与链接关联可是准备为后面新的链接服务的线程,能够快速响应链接的线程请求而无需建立新的
  21. table_cache:相似于thread_cache_size,但用来缓存表文件,对InnoDB效果不大,主要用于MyISAM

Java面试::批量插入几百万条数据
一、 修改事务的提交方式
二、 set autocommit=0 开启
//批量导入数据的时候
set autocommit=1 关闭

二、将多条sql语句合成一条去执行
            能省出的时候很是可观
            尽可能不要用java代码去写,要用存储过程(最好用)。

Java面试::有没有使用过redis
介绍一下redis
Redis是一个key_value的非关系型数据库,它会先把数据放到内存房中,,会根据必定的策略持久化到磁盘当中,及时断电也不会丢失,支持的数据类型比较多。(数据结构)
Redis主要是用来。缓存数据库当中的数据,在web集群当中用做中央缓存存放session
Java面试::redis的使用场景
缓存:
把常常须要查询的,不多修改的数据,放到读取速度很快的空间当中(redis),来减小访问时间,减轻数据压力
计数器:
Redis当中的计数器是原子性的内存操做
能够解决数据库溢出的问题。
Session缓存服务器
web集群当中用做中央缓存存放session
Java面试::redis存储对象的方式
一、咱们须要把对象转化成json字符串,当作字符串处理,直接咱们就可使用set get来设置
优势就是:获取和设置的时候比较简单
缺点是:redis没有专门的方法去把对象转化成json形式
三、 字节的形式,必要的时候,咱们能够把对象序列化,转化成字节保存

咱们会担忧json在转化成对象的时候会消耗咱们的资源的???
第一点:咱们使用lib库转化成json的形式的时候,是否会存在性能问题
第二点,数据量的级别,百万级别的大对象,咱们就不要用lib转json的形式,咱们就直接用序列化的形式
根据应用场景结合业务---redis其实对string支持的最好若是数据量少,咱们仍是要用json的形式
Java面试::redis数据淘汰机制
背景:
在redis当中,咱们用户是能够设置最大使用内存的大小,可是内存是固定的,因此须要咱们有必定的数据淘汰机制
一、 volatile_lru 从已设置过时时间的数据集中挑选最近不多使用的数据淘汰
二、 volatile_ttl 从已设置过时时间的数据集中选择将要过时的数据淘汰
三、 volatile_random: 从已设置过时时间的数据集中任意选择数据淘汰
四、 allkeys_lru:从数据集中挑选最近使用的数据淘汰
五、 allkeys_ random:从数据集当中任意选择数据淘汰
六、 no_enviction:禁止驱逐数据
java面试题:为何要使用消息队列?
直接回答6个字,解耦、异步、削峰
使用消息队列有什么缺点?
1,系统可用性下降:你想啊,原本其余系统只要运行好好的,那你的系统就是正常的。如今你非要加个消息队列进去,那消息队列挂了,你的系统不是呵呵了。所以,系统可用性下降
2,系统复杂性增长:要多考虑不少方面的问题,好比一致性问题、如何保证消息不被重复消费,如何保证保证消息可靠传输。所以,须要考虑的东西更多,系统复杂性增大
怎么选型???ActiveMQ,RabbitMQ,RocketMQ,Kafka
建议选RabbitMQ.一方面,erlang语言天生具有高并发的特性,并且他的管理界面用起来十分方便。正所谓,成也萧何,败也萧何!他的弊端也在这里,虽然RabbitMQ是开源的,然而国内有几个能定制化开发erlang的程序员呢?所幸,RabbitMQ的社区十分活跃,能够解决开发过程当中遇到的bug,这点对于中小型公司来讲十分重要。不考虑rocketmq和kafka的缘由是,一方面中小型软件公司不如互联网公司,数据量没那么大,选消息中间件,应首选功能比较完备的,因此kafka排除。不考虑rocketmq的缘由是,rocketmq是阿里出品,若是阿里放弃维护rocketmq,中小型公司通常抽不出人来进行rocketmq的定制化开发,所以不推荐。
(2)大型软件公司,根据具体使用在rocketMq和kafka之间二选一。一方面,大型软件公司,具有足够的资金搭建分布式环境,也具有足够大的数据量。针对rocketMQ,大型软件公司也能够抽出人手对rocketMQ进行定制化开发,毕竟国内有能力改JAVA源码的人,仍是至关多的。至于kafka,根据业务场景选择,若是有日志采集功能,确定是首选kafka了。具体该选哪一个,看使用场景。如何保证消息不被重复消费?
Java面试题:如何保证消息不被重复消费?
分析:这个问题其实换一种问法就是,如何保证消息队列的幂等性?
回答:先来讲一下为何会形成重复消费?
  其实不管是那种消息队列,形成重复消费缘由其实都是相似的。正常状况下,消费者在消费消息时候,消费完毕后,会发送一个确认信息给消息队列,消息队列就知道该消息被消费了,就会将该消息从消息队列中删除。只是不一样的消息队列发送的确认信息形式不一样,例如RabbitMQ是发送一个ACK确认消息,RocketMQ是返回一个CONSUME_SUCCESS成功标志,kafka实际上有个offset的概念,简单说一下(若是还不懂,出门找一个kafka入门到精通教程),就是每个消息都有一个offset,kafka消费过消息后,须要提交offset,让消息队列知道本身已经消费过了。那形成重复消费的缘由?,就是由于网络传输等等故障,确认信息没有传送到消息队列,致使消息队列不知道本身已经消费过该消息了,再次将该消息分发给其余的消费者。
如何解决?这个问题针对业务场景来答分如下几点
  (1)好比,你拿到这个消息作数据库的insert操做。那就容易了,给这个消息作一个惟一主键,那么就算出现重复消费的状况,就会致使主键冲突,避免数据库出现脏数据。
  (2)再好比,你拿到这个消息作redis的set的操做,那就容易了,不用解决,由于你不管set几回结果都是同样的,set操做原本就算幂等操做。
  (3)若是上面两种状况还不行,上大招。准备一个第三方介质,来作消费记录。以redis为例,给消息分配一个全局id,只要消费过该消息,将<id,message>以K-V形式写入redis。那消费者开始消费前,先去redis中查询有没消费记录便可。
六、如何保证消费的可靠性传输?

回答:其实这个可靠性传输,每种MQ都要从三个角度来分析:生产者弄丢数据、消息队列弄丢数据、消费者弄丢数据
RabbitMQ
(1)生产者丢数据
从生产者弄丢数据这个角度来看,RabbitMQ提供transaction和confirm模式来确保生产者不丢消息。
transaction机制就是说,发送消息前,开启事物(channel.txSelect()),而后发送消息,若是发送过程当中出现什么异常,事物就会回滚(channel.txRollback()),若是发送成功则提交事物(channel.txCommit())。
然而缺点就是吞吐量降低了。所以,生产上用confirm模式的居多。一旦channel进入confirm模式,全部在该信道上面发布的消息都将会被指派一个惟一的ID(从1开始),一旦消息被投递到全部匹配的队列以后,rabbitMQ就会发送一个Ack给生产者(包含消息的惟一ID),这就使得生产者知道消息已经正确到达目的队列了.若是rabiitMQ没能处理该消息,则会发送一个Nack消息给你,你能够进行重试操做。处理Ack和Nack的代码以下所示(说好不上代码的,偷偷上了):
(2)消息队列丢数据
处理消息队列丢数据的状况,通常是开启持久化磁盘的配置。这个持久化配置能够和confirm机制配合使用,你能够在消息持久化磁盘后,再给生产者发送一个Ack信号。这样,若是消息持久化磁盘以前,rabbitMQ阵亡了,那么生产者收不到Ack信号,生产者会自动重发。
那么如何持久化呢,这里顺便说一下吧,其实也很容易,就下面两步
一、将queue的持久化标识durable设置为true,则表明是一个持久的队列
二、发送消息的时候将deliveryMode=2
这样设置之后,rabbitMQ就算挂了,重启后也能恢复数据

消费者丢数据
消费者丢数据通常是由于采用了自动确认消息模式。这种模式下,消费者会自动确认收到信息。这时rahbitMQ会当即将消息删除,这种状况下若是消费者出现异常而没能处理该消息,就会丢失该消息。
至于解决方案,采用手动确认消息便可。
KAFKA
(1)生产者丢数据
在kafka生产中,基本都有一个leader和多个follwer。follwer会去同步leader的信息。所以,为了不生产者丢数据,作以下两点配置

  1. 第一个配置要在producer端设置acks=all。这个配置保证了,follwer同步完成后,才认为消息发送成功。
  2. 在producer端设置retries=MAX,一旦写入失败,这无限重试
    (2)消息队列丢数据
    针对消息队列丢数据的状况,无外乎就是,数据还没同步,leader就挂了,这时zookpeer会将其余的follwer切换为leader,那数据就丢失了。针对这种状况,应该作两个配置。
  3. replication.factor参数,这个值必须大于1,即要求每一个partition必须有至少2个副本
  4. min.insync.replicas参数,这个值必须大于1,这个是要求一个leader至少感知到有至少一个follower还跟本身保持联系 这两个配置加上上面生产者的配置联合起来用,基本可确保kafka不丢数据 (3)消费者丢数据 这种状况通常是自动提交了offset,而后你处理程序过程当中挂了。kafka觉得你处理好了。再强调一次offset是干吗的 解决方案也很简单,改为手动提交便可。