Java面试
2016年9月11日
1 Java基础特性
Java基础 面试题目总结
首先参考 骆昊的 上中下三篇,这三篇虽然有很大一部分过时了,不过还是可以温故而知新的嘛
java 默认是双精度的.如果携程float a = 2.4 ,
2.4双精度转换成单精度的float类型,会损失精度
hashcode() 叫哈希码值 是检查2个对象是否相等的必要条件,
===和equal()方法的区别 在于equal其实也是调用了== 他们的区别在于 基本数据类型比较的值,equal用于比较对象的内存存放地址,部分类库重写了equal()方法比如String Integer
hashcode == equal 的区别
object equal()方法和==区别总结: 比较对象不同之外,有些java库会重写equal()方法,比如String方法则会比较字符串值是否相同
SOLID (单一功能、开闭原则、里氏替换、接口隔离以及依赖反转)设计原则
设计模式
http的请求过程
1 域名解析 2 发起TCP握手 3 建立http请求 3然后把资源交给浏览器去渲染呈现
参考:
http://www.linux178.com/web/httprequest.html
http://blog.csdn.net/liudong8510/article/details/7908093
什么是注解:是一种元数据,用来描述数据的数据,来实现和源码的耦合,而基于 xml 形式的,则是松耦合,,为了平衡 xml 有必要引入注解
注解是如何工作的: Annotations仅仅提供它定义的属性(类/方法/包/域)的信息。Annotations的用户(同样是一些代码,比如 jdk用户的@ override,spring 的 aop 来使注解生效)来读取这些信息并实现必要的逻辑。开发注解
首先一个排序算法的实现
栈 队
队列 hashmap
2 MySQL数据库
mysql 面试问题
ACID原则
数据库事务的4个特性:
原子性(Atomic):组成一个事务的多个数据库操作是一个不可分割的原子单元;只有所有操作执行成功,整个事务才提交,
其中一个操作失败,都必须回滚到初始状态。
一致性(Consistency):事务操作成功后数据库所处的状态和它的业务规则是一致的;(即数据总额不会被破坏。
如A账户转账100到B账户,无论操作成功与否,A和B的存款总额是不变的)
隔离性(Isolation):在并发数据操作时,不同的事务拥有各自的数据空间,它们的操作不会对彼此产生干扰。(并非是完全无干扰,
根据数据库的隔离级别,会产生不同程度的干扰)
持久性(Durability):一旦事务提交成功,事务中的数据操作都必须持久化到数据库中;就算数据库崩溃,也必须保证有某种机制恢复。
在这些特性中,数据“一致性”是最终目标,其他的特性都是为了达到这个目标的措施和手段。
SQL注入攻击:把查询字符串换成了恶意的SQL命令
如果事务中所有sql语句执行正确则需要自己手动提交commit;否则有任何一条执行错误,需要自己提交一条rollback,这时会回滚所有操作,而不是commit会给你自动判断和回滚。
脏读 不可重复读 和幻读 含义的解释
1 脏读很好理解,值得是A事物修改了数据但是还没有提交的数据库中,B事务成功读取了包含A事务修改的数据,
2 不可重复读,指的是A事务读取数据是1,然后B事务修改为2,当A事务再次去读取数据的时候,会法身不可重复读取原先的数据,从1变到了2
3 幻读 和不可重复读的区别在于.A事务照旧读取,但是B事务对数据进行了修改或者删除操作,那么就会出现幻读现象
在MySQL中,isolation_read_read_uncommitted(RU): 读取未提交的数据,在并发的事务中允许一个事务读取另一个事务未交的更新数据, 出现脏读,不可重复读和幻读
isolation_read_committed(RC) :读取已提交的数据,保证在并发的事务中,一个事务修改的数据提交后才能被另外一个事
务读取到。(会出现不可重复读和幻读)
isolation_repeatable_read:可重复读,这是MySQL默认的事务隔离级别,确保同一个事务的多个实例在并发读取数据,会看到同样的数据行.不过,理论上会导致幻读(phantom read)
serializable 事务被强制为依次执行。会降低效率
隔离级别和3个读取问题的对应关系MySQL 事务隔离级别
PROPAGATION(事务传播属性)
1 PROPAGATION_REQUIRED:支持当前事务,如果当前没有事务,就新建一个事务。也就是说业务方法需要在一个事务中运行,如果
业务方法被调用时,调用业务方法的行为(方法)已经处在一个事务中,那么就加入到该事务,否则为自己创建一个新的事务。
(默认传播属性)
-PROPAGATION_SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。也就是说如果业务方法在某个事务范围内被调用,
则该方法成为该事务的一部分。如果业务方法在事务范围外被调用,则该方法在没有事务的环境下执行。
总结:有就支持,没有就不需要
-PROPAGATION_MANDATORY:支持当前事务,如果当前没有事务,就抛出异常。也就是说业务方法只能在一个已经存在的事务中执行,
业务方法不能发起自己的事务。如果业务方法在没有事务的环境下被调用,容器就会抛出例外。
总结:业务不能自己发起事务,只能在事务环境下被调用,不然的话,会抛出异常
-PROPAGATION_REQUIRESNEW:新建事务,如果当前存在事务,把当前事务挂起。也就是说业务方法被调用时,不管是否已经存在事务,
业务方法总会为自己发起一个新的事务。如果调用业务方法的行为(方法)已经运行在一个事务中,则原有事务会被挂起,新的事务
会被创建,直到业务方法执行结束,新事务才算结束,原先的事务才会恢复执行。
-PROPAGATION_NOT_SUPPORTED:以非事务方式执行,如果当前存在事务,就把当前事务挂起。也就是说业务方法不需要事务。如果
方法没有被关联到一个事务中,容器不会为它开启事务。如果方法在一个事务中被调用,该事务会被挂起,在方法调用结束后,
原先的事务便会恢复执行。
总结:原先业务被挂起,新建事务,执行完毕再继续执行原先的老业务
-PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。也就是说业务方法绝对不能在事务范围内执行。如果业务
方法在某个事务中执行,容器会抛出例外,只有业务方法没有关联到任何事务,才能正常执行。
总结:不能再事务范围内执行,否则抛出异常.
-PROPAGATION_NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中。 如果没有活动事务, 则按REQUIRED属性执行。
它使用了一个单独的事务, 这个事务拥有多个可以回滚的保存点。内部事务的回滚不会对外部事务造成影响。它只对DataSourceTransactionManager事务管理器起效。
理解Nested的关键是savepoint。他与PROPAGATION_REQUIRES_NEW的区别是,PROPAGATION_REQUIRES_NEW另起一个事务,将会与他的父事务相互独立,
而Nested的事务和他的父事务是相依的,他的提交是要等和他的父事务一块提交的。也就是说,如果父事务最后回滚,他也要回滚的。
而Nested事务的好处是他有一个savepoint。
设置innodb的事务级别方法是:set 作用域 transaction isolation level 事务隔离级别,
例如~SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}
mysql> set global transaction isolation level read committed; //全局的
mysql> set session transaction isolation level read committed; //当前会话
explain 详解
索引的原理 和 优化
B+树
b+树性质
1.通过上面的分析,我们知道IO次数取决于b+数的高度h,假设当前数据表的数据为N,每个磁盘块的数据项的数量是m,则有h=㏒(m+1)N,当数据量N一定的情况下,m越大,h越小;而m = 磁盘块的大小 / 数据项的大小,磁盘块的大小也就是一个数据页的大小,是固定的,如果数据项占的空间越小,数据项的数量越多,树的高度越低。这就是为什么每个数据项,即索引字段要尽量的小,比如int占4字节,要比bigint8字节少一半。这也是为什么b+树要求把真实的数据放到叶子节点而不是内层节点,一旦放到内层节点,磁盘块的数据项会大幅度下降,导致树增高。当数据项等于1时将会退化成线性表。
索引的优缺点:
建立索引的几大原则
1.最左前缀匹配原则,非常重要的原则,mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。
2.=和in可以乱序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识别的形式
3.尽量选择区分度高的列作为索引,区分度的公式是count(distinct col)/count(*),表示字段不重复的比例,比例越大我们扫描的记录数越少,唯一键的区分度是1,而一些状态、性别字段可能在大数据面前区分度就是0,那可能有人会问,这个比例有什么经验值吗?使用场景不同,这个值也很难确定,一般需要join的字段我们都要求是0.1以上,即平均1条扫描10条记录
4.索引列不能参与计算,保持列“干净”,比如from_unixtime(create_time) = ’2014-05-29’就不能使用到索引,原因很简单,b+树中存的都是数据表中的字段值,但进行检索时,需要把所有元素都应用函数才能比较,显然成本太大。所以语句应该写成create_time = unix_timestamp(’2014-05-29’);
5.尽量的扩展索引,不要新建索引。比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可
优化SQL语句的步骤
慢查询优化基本步骤
0.先运行看看是否真的很慢,注意设置SQL_NO_CACHE
1.where条件单表查,锁定最小返回记录表。这句话的意思是把查询语句的where都应用到表中返回的记录数最小的表开始查起,单表每个字段分别查询,看哪个字段的区分度最高
2.explain查看执行计划,是否与1预期一致(从锁定记录较少的表开始查询)
3.order by limit 形式的sql语句让排序的表优先查
4.了解业务方使用场景
5.加索引时参照建索引的几大原则
6.观察结果,不符合预期继续从0分析
参考 explain命令详解:Mysql explain详解
锁的分类
前面我们提到MySQL的加锁, 锁是作用于索引的,行级锁都是基于索引的,
这点很重要!!!。那么本篇文章说下索引。
**只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁! **
1 行锁以及死锁的产生
innodb中.索引分主键索引和非主键索引2种.
如果一条sql语句操作了主键索引,MySQL就会锁定这条主键索引;
如果一条语句操作了非主键索引,MySQL会先锁定该非主键索引,再锁定相关的主键索引;
当两个事务同时执行,一个锁住了主键索引,在等待其他相关索引。另一个锁定了非主键索引,在等待主键索引。这样就会发生死锁。
参考:MySQL死锁分析
2 表锁 分为共享读锁(又称读锁)和拍他锁
读锁(share lock)特点:用户可以并发读取数据,但任何事物都不能对数据进行修改,除非释放了所有共享锁
使用:SELECT ... LOCK IN SHARE MODE;
排他锁(exclusive Lock)又称写锁,如果事务T对数据A加上排他锁后,则其他事务不能再对A加任任何类型的锁。获准排他锁的事务既能读数据,又能修改数据。
特点:如果事务T对数据A加上排他锁后,则其他事务不能再对A加任任何类型的锁。
使用: select ... FOR UPDATE;
3、意向锁
意向共享锁(IS):表示事务准备给数据行加入共享锁,也就是说一个数据行加共享锁前必须先取得该表的IS锁
意向排他锁(IX):类似上面,表示事务准备给数据行加入排他锁,说明事务在一个数据行加排他锁前必须先取得该表的IX锁。
意向锁是InnoDB自动加的,不需要用户干预.
总结:
对于insert、update、delete,InnoDB会自动给涉及的数据加排他锁;
对于一般的Select语句,InnoDB不会加任何锁。
http://blog.csdn.net/xifeijian/article/details/20312557
mysql 事务隔离级别靠锁如何实现 这个博客对MySQL 锁 和 索引 事务隔离级别 进行了较好阐释 戳我
题外篇
悲观所 乐观锁
having子句和where条件的区别,参考来自这里
HAVING 子句使你能够指定过滤条件,从而控制查询结果中哪些组可以出现在最终结果里面。
WHERE 子句对被选择的列施加条件,而 HAVING 子句则对 GROUP BY 子句所产生的组施加条件。
如何避免sql注入攻击
null auto increment 主键 外键
union union all 区别
NOT NULL 约束:保证列中数据不能有 NULL 值
DEFAULT 约束:提供该列数据未指定时所采用的默认值
UNIQUE 约束:保证列中的所有数据各不相同
主键约束:唯一标识数据表中的行/记录
外键约束:唯一标识其他表中的一条行/记录
CHECK 约束:此约束保证列中的所有值满足某一条件
索引:用于在数据库中快速创建或检索数据
子查询中 in 除了一个特殊情况外,一般来说改成join更快 原因是因为参考这里.这里给出了MySQL 参考手册对于in和join查询快慢的说明
1.为查询缓存优化你的查询
2.EXPLAIN 你的 SELECT 查询
3.当只要一行数据时使用 LIMIT 1
4.为搜索字段建索引
5.在Join表的时候使用相当类型的例,并将其索引
6.千万不要 ORDER BY RAND()
7.使用 ENUM 而不是 VARCHAR
8.从 PROCEDURE ANALYSE() 取得建议
9.Prepared Statements
10.垂直分割 也就是拆分表
MySQL数据库博客 三石雨的几篇优秀博客
3 多线程 集合框架哦 锁
JAVA 多线程 和 集合框架 以及 线程状态 锁问题总结
多线程
Java集合框架问题总结
这篇博客有些总结的还是不错的戳我
hashcode 散列值 哈希值,java object的 hashcode()根据对象在内存中的唯一地址,计算出一个独有的哈希值
哈希值又叫散列值,计算方法是一个单向散列函数的性质,即散列值不同,那么输入值(原始值)必定不同,但是根据单向散列函数性质,也会存在哈希碰撞冲突,即输入值不同,会计算出相同的哈希值,这就是哈希碰撞.
还有一个 http://dwz.cn/45oJZ6
哈希冲突的解决方法:用线性探测法或者拉链法 解决哈希碰撞问题
hashcode 在Java集合框架中的运用
Java采用了哈希表的原理。哈希算法也称为散列算法,当集合要添加新的元素时,将对象通过哈希算法计算得到哈希值(正整数),然后将哈希值和集合(数组)长度进行&运算,得到该对象在该数组存放的位置索引。
hashmap底层就是一个数组,然后数组里每个元素装了个链表。这个数组元素称为bucket桶.先通过hashcode找到对象在数组中的位置,然后通过 key的equal方法找到在链表当中对应的value位置
hashmap 会被问到的几个问题总结
:grinning:
-hashing的概念
-HashMap中解决碰撞的方法
-equals()和hashCode()的应用,以及它们在HashMap中的重要性
-不可变对象的好处
-HashMap多线程的条件竞争
-重新调整HashMap的大小
interation和enumeration区别iterator多了一个remove方法定义之外,实现interator接口的java集合框架支持fail-fast机制
(01) 函数接口不同
Enumeration只有2个函数接口。通过Enumeration,我们只能读取集合的数据,而不能对数据进行修改。
Iterator只有3个函数接口。Iterator除了能读取集合的数据之外,也能数据进行删除操作。
(02) Iterator支持fail-fast机制,而Enumeration不支持。
Enumeration 是JDK 1.0添加的接口。使用到它的函数包括Vector、Hashtable等类,这些类都是JDK 1.0中加入的,Enumeration存在的目的就是为它们提供遍历接口。Enumeration本身并没有支持同步,而在Vector、Hashtable实现Enumeration时,添加了同步。
而Iterator 是JDK 1.2才添加的接口,它也是为了HashMap、ArrayList等集合提供遍历接口。
Iterator是支持fail-fast机制的:当多个线程对同一个集合的内容进行操作时,就可能会产生fail-fast事件。
什么叫做fail-fast机制 戳我
fail-fast 机制是java集合(Collection)中的一种错误机制。当多个线程对同一个集合的内容进行操作时,就可能会产生fail-fast事件。
例如:当某一个线程A通过iterator去遍历某集合的过程中,若该集合的内容被其他线程所改变了;那么线程A访问集合时,就会抛出ConcurrentModificationException异常,产生fail-fast事件。
ConcurrentModificationException异常 发生的原因
Java ArrayList 一个是动态数组 linkedlist 一个是链表 所以 插入和删除链表效率最高,访问的话数组咯
arraylist 不是线程安全的,多线程环境下建议是使用vector或者copyonwritearraylist
Java多线程问题
1 volatile 与 synchronized
在Java中,为了保证多线程读写数据时保证数据的一致性,可以采用两种方式:
-1.1 同步
如用synchronized关键字,或者使用锁对象.
-1.2 volatile
使用volatile关键字
用一句话概括volatile,它能够使变量在值发生改变时能尽快地让其他线程知道.
volatile本质是在告诉jvm当前变量在寄存器中的值是不确定的,需要从主存中读取,synchronized则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住.
volatile仅能使用在变量级别,synchronized则可以使用在变量,方法.
volatile仅能实现变量的修改可见性,但不具备原子特性,而synchronized则可以保证变量的修改可见性和原子性.
volatile不会造成线程的阻塞,而synchronized可能会造成线程的阻塞.
volatile标记的变量不会被编译器优化,而synchronized标记的变量可以被编译器优化.
时间片调度
值得注意的一点是 线程只能从就绪状态(runnable)这一条唯一路径到运行状态(running)
Java多线程状态说明:
线程共包括以下5种状态。
1.新建状态(New) : 线程对象被创建后,就进入了新建状态。例如,Thread thread = new Thread()。
2.就绪状态(Runnable): 也被称为“可执行状态”。线程对象被创建后,其它线程调用了该对象的start()方法,从而来启动该线程。例如,thread.start()。处于就绪状态的线程,随时可能被CPU调度执行。
3.运行状态(Running) : 线程获取CPU权限进行执行。需要注意的是,线程只能从就绪状态进入到运行状态。
4.阻塞状态(Blocked) : 阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:
(01) 等待阻塞 -- 通过调用线程的wait()方法,让线程等待某工作的完成。
(02) 同步阻塞 -- 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态。
(03) 其他阻塞 -- 通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
5.死亡状态(Dead) : 线程执行完了或者因异常退出了run()方法,该线程结束生命周期。
这5种状态涉及到的内容包括Object类, Thread和synchronized关键字。这些内容我们会在后面的章节中逐个进行学习。
Object类,定义了wait(), notify(), notifyAll()等休眠/唤醒函数。
Thread类,定义了一些列的线程操作函数。例如,sleep()休眠函数, interrupt()中断函数, getName()获取线程名称等。
synchronized,是关键字;它区分为synchronized代码块和synchronized方法。synchronized的作用是让线程获取对象的同步锁。
在后面详细介绍wait(),notify()等方法时,我们会分析为什么“wait(), notify()等方法要定义在Object类,而不是Thread类中”。
Thread 和 Runnable 的异同点
接口 和 类的区别
此外还有 runnable用于资源的共享,多个线程基于一个Runnable对象建立,他们会共享Runnable对象的上的资源
start()方法和run()方法的区别
~~start() : 它的作用是启动一个新线程,新线程会执行相应的run()方法。start()不能被重复调用。
run() : run()就和普通的成员方法一样,可以被重复调用。单独调用run()的话,会在当前线程中执行run(),而并不会启动新线程!~~
synchronized 关键字
这个需要好好看看这篇文章,戳我
讲的很透彻 ,到底什么时候能被同时访问,什么时候不能被访问,关键要清楚 线程 访问 锁 ,主语和宾语的限定条件,才能知道到底可不可以被访问哦
作者解释的已经很到位了,但是,我理解的时候还需要理解这里面源代码的执行顺序中的一点也就是,当t1.start()方法之后,他尝试去notify()唤醒当前等待的线程还没有,那么他会去继续尝试,等调用wait()方法之后,发现线程进入等待阻塞状态之后,那么就可以去唤醒了...
yield() 与 wait()的比较
我们知道,wait()的作用是让当前线程由“运行状态”进入“等待(阻塞)状态”的同时,也会释放同步锁。而yield()的作用是让步,它也会让当前线程离开“运行状态”。它们的区别是:
(01) wait()是让线程由“运行状态”进入到“等待(阻塞)状态”,而不yield()是让线程由“运行状态”进入到“就绪状态”。
(02) wait()是会线程释放它所持有对象的同步锁,而yield()方法不会释放锁。
我们知道,wait()的作用是让当前线程由“运行状态”进入“等待(阻塞)状态”的同时,也会释放同步锁。而sleep()的作用是也是让当前线程由“运行状态”进入到“休眠(阻塞)状态”。
但是,wait()会释放对象的同步锁,而sleep()则不会释放锁。
下面通过示例演示sleep()是不会释放锁的。
interrupt() 方法
interrupt()的作用是中断本线程。
本线程中断自己是被允许的;其它线程调用本线程的interrupt()方法时,会通过checkAccess()检查权限。这有可能抛出SecurityException异常。
如果本线程是处于阻塞状态:调用线程的wait(), wait(long)或wait(long, int)会让它进入等待(阻塞)状态,或者调用线程的join(), join(long), join(long, int), sleep(long), sleep(long, int)也会让它进入阻塞状态。若线程在阻塞状态时,调用了它的interrupt()方法,那么它的“中断状态”会被清除并且会收到一个InterruptedException异常。例如,线程通过wait()进入阻塞状态,此时通过interrupt()中断该线程;调用interrupt()会立即将线程的中断标记设为“true”,但是由于线程处于阻塞状态,所以该“中断标记”会立即被清除为“false”,同时,会产生一个InterruptedException的异常。
如果线程被阻塞在一个Selector选择器中,那么通过interrupt()中断它时;线程的中断标记会被设置为true,并且它会立即从选择操作中返回。
如果不属于前面所说的情况,那么通过interrupt()中断线程时,它的中断标记会被设置为“true”。
中断一个“已终止的线程”不会产生任何操作。
2016年9月7日17:59:24 多线程问题先到此结束
Redis 提供了多种不同级别的持久化方式:
RDB 持久化可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot)。
AOF 持久化记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集。 AOF 文件中的命令全部以 Redis 协议的格式来保存,新命令会被追加到文件的末尾。 Redis 还可以在后台对 AOF 文件进行重写(rewrite),使得 AOF 文件的体积不会超出保存数据集状态所需的实际大小。
Redis 还可以同时使用 AOF 持久化和 RDB 持久化。 在这种情况下, 当 Redis 重启时, 它会优先使用 AOF 文件来还原数据集, 因为 AOF 文件保存的数据集通常比 RDB 文件所保存的数据集更完整。
你甚至可以关闭持久化功能,让数据只在服务器运行时存在。
REDIS数据淘汰策略
JVM内存模型
4 框架面试
框架 架构问题 面试总结
消息队列
重点参考这篇文章 ,美团技术点评→消息队列涉及精要
消息队列设计思想:消息队列已经逐渐成为企业IT系统内部通信的核心手段。它具有低耦合、可靠投递、广播、流量控制、最终一致性等一系列功能,成为异步RPC的主要手段之一。本文首先会阐述什么时候你需要一个消息队列,然后以Push模型为主,从零开始分析设计一个消息队列时需要考虑到的问题,如RPC、高可用、顺序和重复消息、可靠投递、消费关系解析等。
何时需要消息队列
当你需要使用消息队列时,首先需要考虑它的必要性。可以使用mq的场景有很多,最常用的几种,是做业务解耦/最终一致性/广播/错峰流控等。反之,如果需要强一致性,关注业务逻辑的处理结果,则RPC显得更为合适。
名词幂等性
解耦
最终一致性
广播
错峰与流控
1.为什么使用消息队列
使用场景:用户发帖之后,推送一个消息到队列服务器,用户只要将消息存到队列服务器成功了,就将结果返回给用户,此时接收队列消息的消费者,将分批逐步完成大量的 insert 操作,实现用户发帖和推送发帖通知消息的异步,减轻数据库的压力
现代的互联网应用大量的使用了消息队列.
消息队列不仅被用于系统内部组件之间的通信,同时也被用于系统跟其他服务之间的交互.
消息队列的使用,可以增加系统的扩展性,灵活性和用户体验.
飞机与消息队列的系统,其运行速度取决于系统中最慢的组件速度,也就是所谓的短板效应.
而基于消息队列的系统,各组件可以实现松耦合,系统不再受限制与组件的束缚,可以异步运行,得以更快的速度完成各自的工作.
除了上述好处,业务逻辑解耦之外,调用方下达命令,而不用等待整个逻辑执行完毕,此外还有一个好处就是抑制性能波峰的产生,在瞬时业务增长的时候,保持性能曲线的平滑
2.什么是消息队列
在计算机科学中,消息队列是一种进程间的通信或者同一进程不同线程间的异步通信方式,消息队列一般保存在链表结构中,拥有权限的线程可以向消息队列写入和读取消息,
3.消息队列的缺点: 接收者必须轮询消息队列才能收到最新消息https://zh.wikipedia.org/wiki/%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97
4.消息队列的持久化问题 http://www.cnblogs.com/xiazh/archive/2011/04/29/2004859.html 消息队列和消息持久化之后,确保信息的可靠传输,防止消费者或者消息队列服务宕机,造成的信息传输丢失问题,数据纯到数据库上
5.相关技术点→ linux IPC 共享内存和消息队列的比较http://blog.csdn.net/ruizeng88/article/details/6702346 百度搜索下各个消息队列对比
REDIS面试
http://www.100mian.com/mianshi/dba/37381.html
http://blog.csdn.net/zdp072/article/details/50991116
spring是如何做到为普通类创建单例的呢
http://blog.csdn.net/arvinrong/article/details/7756167
RPC
5.相关技术点→ linux IPC 共享内存和消息队列的比较http://blog.csdn.net/ruizeng88/article/details/6702346 百度搜索下各个消息队列对比
6.什么是 RPC 框架
进程间通信 IPC,是指在多任务操作系统或者联网的计算机之间运行的程序,进程之间所要用到的通信技术,
IPC 分为 LPC 和 RPC,RPC 不用与 LPC, 因为 IPC共享内存空间所以不存在内存寻址问题,而 RPC 的实现要解决的是1发现服务的问题,就是 A 服务器要调用 B 服务器上的一个服务,如何连接的 B服务器,端口,方法名
dubbo采用的是发布对象的方式,RPC 的通讯协议基于底层的网络协议,而底层的网络协议是基于二进制的,因此服务器间的调用,就涉及到序列化和反序列化问题,
另外 zookeeper 实现了,服务的自动注册,发现告知,不需要写死服务器提供方的地址了
zookeeper提供了“心跳检测”功能,它会定时向各个服务提供者发送一个请求(实际上建立的是一个 Socket 长连接),如果长期没有响应,服务中心就认为该服务提供者已经“挂了”,并将其剔除,比如100.19.20.02这台机器如果宕机了,那么zookeeper上的路径就会只剩/HelloWorldService/1.0.0/100.19.20.01:16888。
服务消费者会去监听相应路径(/HelloWorldService/1.0.0),一旦路径上的数据有任务变化(增加或减少),zookeeper都会通知服务消费方服务提供者地址列表已经发生改变,从而进行更新。
更为重要的是zookeeper与生俱来的容错容灾能力(比如leader选举),可以确保服务注册表的高可用性。
RPC 原理 http://www.cnblogs.com/LBSer/p/4853234.html
7.为什么要用 RPC 框架
就是无法在一个进程内,甚至一个计算机内通过本地调用的方式完成的需求,比如比如不同的系统间的通讯,甚至不同的组织间的通讯。由于计算能力需要横向扩展,需要在多台机器组成的集群上部署应用,
一个请求应答网络交互通常包含两条链,一条链(Upstream)是从传输层,经过一系列步骤,如身份认证,解密,日志,流控,最后到达业务层,一条链(DownStream)是业务层返回后,又经过一系列步骤,如加密等,又回到传输层。
要知道实现RPC很麻烦呀,什么多线程、什么Socket、什么I/O,都是让咱们普通程序员很头疼的事情。于是就有牛人开发出RPC框架(比如,CORBA、RMI、Web Service、RESTful Web Services等等)。
OK,现在可以定义RPC框架的概念了。简单点讲,RPC框架就是可以让程序员来调用远程进程上的代码一套工具。有了RPC框架,咱程序员就轻松很多了,终于可以逃离多线程、Socket、I/O的苦海了。
用这种方式分割程序,当用户要访问数据时就无需每次拷贝整个数据库或它的大部分程序到用户系统。其实,服务器只处理请求,甚至只执行一些数据计算,把得出的结果再发送给用户。因为当数据存放在一个地方时,数据库同步很容易实现,所以多个用户可同时访问相同的数据。
MYBATIS
SPRING
http://www.imooc.com/article/1309
Spring总结起来优点如下: 低侵入式设计,代码的污染极低; 独立于各种应用服务器,基于Spring框架的应用,可以真正实现Write Once,Run Anywhere的承诺; Spring的IoC容器降低了业务对象替换的复杂性,提高了组件之间的解耦; Spring的AOP支持允许将一些通用任务如安全、事务、日志等进行集中式管理,从而提供了更好的复用; Spring的ORM和DAO提供了与第三方持久层框架的良好整合,并简化了底层的数据库访问; Spring的高度开放性,并不强制应用完全依赖于Spring,开发者可自由选用Spring框架的部分或全部。
作者: IT程序狮
链接:http://www.imooc.com/article/1309
来源:慕课网
DAO
ORM
mybatis面试题
-1 http://www.bug315.com/article/438.htm
-2 http://blog.csdn.net/cheat1173010256/article/details/50849176 这个好一点
spring面试
-http://ifeve.com/spring-interview-questions-and-answers/
-http://www.importnew.com/11657.html
待处理
133个Java面试题列表
http://www.codeceo.com/article/20-java-advanced-interview-questions.html
http://mm.fancymore.com/reading/jvm-mem.html
http://blog.csdn.net/moneyshi/article/details/50786786
http://www.codeceo.com/article/133-java-interview-5-years.html
http://www.codeceo.com/article/20-java-advanced-interview-questions.html
网友评论
博主写得很棒,这里推荐大家一个专注于Java开发的个人博客Queen's Blog(黛玛Queen),每天更新文章,干货满满哦,不容错过,需要的点这里咯。
http://www.marsitman.com/mybatis/mybatis-mysql-getid.html