【面试】数据库基础

#关系型数据库MySQL

#1、数据库底层

MySQL数据库的底层是B+树。说到B+树,先说下B树,B树也叫多路平衡查找树,所有的叶子节点位于同一层,具有以下特点:1)一个节点可以容纳多个值;2)除非数据已满,不会增加新的层,B树追求最少的层数;3)子节点中的值与父节点的值有严格的大小对应关系。一般来说,如果父节点有a个值,那么就有a+1个子节点;4)关键字集合分布在整棵树中;5)任何一个关键字出现且只出现在一个节点中;6)搜索可能在叶子结点结束,其搜索性能等价于在关键字全集做一次二分查找。

B+树是基于B树和叶子节点顺序访问指针进行实现,它具有B树的平衡性,并且通过顺序访问指针来提高区间查询的性能,一个叶子节点中的key从左至右非递减排列。特点在于:1)非叶子节点中含有n个关键字,关键字不保存数据,只作为索引,所有数据都保存在叶子结点;2)有的叶子节点中包含了全部关键字的信息及只想这些关键字记录的指针,即叶子节点包含链表结构,能够方便进行区间查询;3)所有的非叶子结点可以看成是索引部分,节点中仅包含其子树中的最大(或最小)关键字;4)同一个数字会在不同节点中重复出现,根节点的最大元素就是B+树的最大元素。

MySQL中的InnoDB引擎是以主键ID为索引的数据存储引擎。InnoDB通过B+树结构对ID建立索引,在叶子节点存储数据。若建索引的字段不是主键ID,则对该字段建索引,然后再叶子节点中存储的是该记录的主键,然后通过主键索引找到对应的记录。因为不再需要全表扫描,只需要对树进行搜索即可,所以查找速度很快,还可以用于排序和分组。

InnoDB和MyISAM引擎都是基于B+树,InnoDB是聚簇索引,数据域存放的是完整的数据记录;MyISAM是非聚簇索引,数据域存放的是数据记录的地址。InnoDB支持表锁、行锁、间隙锁、外键以及事务,MyISAM仅支持表锁,同时不支持外键和事务。InnoDB注重事务,MyISAM注重性能。

#2、SQL语言之DQL、DML、DDL和DCL

DQL指的是Data Query Language,数据库查询语言,主要是select命令;

DML指的是Data Manipulation Language,数据库操作语言,主要有insert、delete、update等命令;

DDL指的是Data Defined Language,数据库定义语言,主要是对数据库的某些对象,如database和table进行管理,主要有create、alter、drop等命令,比如创建数据库和表格、更改表结构和设置约束、删除表和数据库;

DCL指的是Data Control Language,数据库控制语言,主要是用于授予或回收访问数据库的某种特权,并控制数据库操纵事务发生的时间及效果,主要有grant、rollback等命令。

DML和DDL的区别:DML操作可以手动控制事务的开启、提交和回滚,而DDL是隐形提交不能回滚。

#3、数据库连接协议

JDBC驱动协议:默认TCP协议

客户端和Oracle服务器之间通信协议是TCP的,但是一个数据库连接也会其一个UDP端口。

MySQL的连接方式有两种:Socket和TCP/IP

-- Socket连接方式
mysql -uroot -padmin -S/application/mysql/tmp/mysql.sock
-- TCP/IP连接方式
mysql -uoot -padmin -h192.1.1.20
#4、索引和主键的区别

主键用于标识数据库记录的唯一性,不允许记录重复且键值不能为空。主键是特殊索引,但索引不一定是主键。

索引可以提高查询速度,可以不需要进行全表扫描而快速查询到结果。

使用主键,数据库会自动创建主键索引,同时也可以再非主键上创建索引。

数据表中只能由一个主键,但可以有多个索引。

#5、数据库四范式

范式:创建数据库的过程中必须遵循的准则。其作用在于减少数据库中的数据冗余,以增加数据的一致性。

候选键:唯一识别该表的属性或属性表。

第一范式(1NF):属性不可拆分或无重复的列;

第二范式(2NF):数据库中的每一行必须被唯一地区分,即表中字段必须完全依赖于全部主键而非部分主键;

第三范式(3NF):消除传递依赖,数据库非主键外的所有字段仅能以来于候选键,不存在与其他非主键关联;

第四范式(4NF):一个表的主键只对应一个多值,即消除多值依赖。

#6、SQL基础

数据库的创建与使用:

create database test;
use test;

创建表:

create table mytable (
id int not null auto_increment,
name varchar(20)
);

修改表:

alter table mytable add sex varchar(20);

增删改:

insert into mytable(id,name,sex) values(1,'zhangsan','male');
delete from mytable where id = 1;
update mytable set name = 'lisi' where id = 1;

清空表:

truncate table mytable;

distinct:用于返回唯一不同的值

select distinct name from mytable;

limit:检索记录行

-- 检索前5个记录行
select * from mytable limit 5;
-- 检索记录行1-5行
select * from mytable limit 0, 5;
-- 检索6-last行
select * from mytable limit 5, -1;

排序:

-- 默认升序
select * from mytable order by col1 DESC col2 ASC;

like匹配:

-- %匹配大于等于1个任意字符
select * from mytable where name = 'z%';
-- _匹配1个任意字符
select * from mytable where name = 'l_s_';
-- []匹配集合内的字符
select * from mytable where name = '[zl]%';
-- [!]匹配除开集合内的字符
select * from mytable where name = '[!z]%';

concat():用于将多个字符串连接成一个字符串

select concat(trim(col1), '(', trim(col2), ')') as new from mytable;

函数:

-- 均值
select avg(col) as col_avg from mytable;
-- 计数
select count(col) as col_count from mytable;
-- 类似的sum()、max()、min()等
-- 时间
select now();

分组:

select col, count(*) as num from mytable where col > 2 group by col having by num > 2;

子查询中只能返回一个字段的数据:

select * from mytable1 where col1 in (select col2 from mytable2);

组合查询:

select * from mytable where col = 1 union select col from mytable where col = 2;

视图:

create view as myview as select * from mytable where id > 2;

存储过程:

create procedure myprocedure(out ret int)
begin
...
end
#7、 删除操作delete、truncate和drop

delete:直接删除表中的某一行数据,并且同时将该行的删除操作作为事务记录在日志中保存便于进行回滚,因此delete操作更加占用资源,数据空间不释放。delete可以对table和view对象进行操作。

delete from mytable where id = 1;

truncate:一次性从数据表中删除所有数据(释放存储表数据所用的数据页来删除数据),因此不能回滚,占用资源更加少,速度更快。数据空间释放后,表和索引所占用的空间会回复到初始大小。只能对没有关联视图的table进行操作,对于外键约束引用的表,不能使用truncate,需要使用delete。

truncate mytable

drop:删除整个表,包括表的结构、数据、定义等。属于永久抹去,空间会释放,无法恢复,对table和view都能操作。

drop mytable;

总结:

在速度上,drop > truncate > delete;

在操作对象上,delete和drop可以对table和view操作,truncate只能对table操作;

在表和索引所占空间上,delete操作不会减少表和索引占用的空间,truncate操作后表和索引所占用的空间会恢复至初始大小,drop将表所占用的空间全部释放;

在回滚上方面,delete操作为DML语句可以回滚,truncate和drop为DDL语句,隐式提交无法回滚;

在删除限制上,delete可以操作带有外键约束引用的表,而truncate不可以;

#8、char和varchar的区别

char的长度是不可变的,而varchar的长度是可变的。例如,创建表时定义一个char[10]和varchar[10],当存入一个字符串sql时,char所占的长度依然为10,除了字符sql外后面跟7个空格,而varchar所占的长度变为字符串的实际长度3。在取数据时,char类型的要用trim()函数去掉多余的空格,而varchar类型不需要。

char类型的存取速度比varchar快得多,因为其长度固定方便存储与查找;但char类型会付出空间的代价,是以空间换时间来争取高的时间效率,而varchar是以空间效率为首。

char对英文字符(ASCII)占用1个字节,对汉字占用2个字节;varchar对英文字符和汉字都是占用2个字节。

#9、 数据库的冷备份与热备份

冷备份(off,慢,时间点上恢复):需要数据库正常关闭,会提供一个完整的数据库;将关键性文件拷贝到另外位置;对于备份数据库信息而言,冷备份是最快最安全的方法。

优点:易归档、能够回复到某个时间点;

缺点:数据库必须处于关闭状态;

热备份(on,块):数据库运行的情况下,备份数据库操作的sql语句,当数据库发生问题时可以重新执行一遍备份的sql语句。

优点:备份时数据库仍可以使用、快速恢复、属于表或数据库级别的备份,并且时间短

缺点:不能出错

#10、数据库的事务及ACID属性

事务:逻辑上的一组操作,要么都执行,要么都不执行。

四大特性:

A原子性:事务是最小的执行单位,不可分割,要么全部执行,要么都不执行;

C一致性:事务执行前后,数据库的数据保持一致,多个事务对同一数据读取的结果是相同的;

I隔离性:并发访问数据库时,事务之间互不打扰,各并发事务之间的数据库是独立的;

D持久性:一个事务被提交之后,该事务对数据库所做的改变是持久的,不会被回滚。

#11、并发事务的问题

脏读:一个事务读取到了另一个事务还未提交的修改数据,如果另一个事务进行了回滚,这个数据就是脏数据。

修改丢失:一个事务读取数据并进行了修改,另一个事务页读取了该数据进行了修改,这样第一个事务的修改结果就丢失了,也就是修改丢失问题。

不可重复读:一个事务对同一数据进行多次修改,期间另一事务也读取了该数据并进行了修改,这样第一个事务读取到的数据可能不一致,称为不可重复读。

幻读:一个事务在读取多行数据时,另一个并发事务插入了一些新数据,后续查询中第一个事务会查找到一些原本不存在的数据记录,称为幻读。在Mysql中利用MVCC解决了快照读幻读,利用间隙锁解决了当前读幻读

#12、隔离级别

读未提交:最低隔离级别,允许读取尚未提交的数据变更,会导致脏读、不可重复读和幻读;

读已提交:允许读取并发事务已经提交的数据,可以阻止脏读,会导致不可重复读和幻读;

可重复读:对同一字段多次读取的结果都是一样的,可以阻止脏读和不可重复读,会导致幻读;

串行化:最高隔离界别,可以阻止脏读、不可重复读和幻读。

MySQL中InnoDB引擎默认支持的隔离级别是可重复读,使用的是next-key Lock算法,可以避免幻读的产生,可以完全保证事务的隔离性要求

#13、多表查询

一对多关系:从表使用主表的主键作为外键;主表中有的数据,从表中可以没有;主表必须有数据,才能向从表中添加数据;要先删除从表的相应数据才能删除主表的数据;

多对多关系:老师与学生,一个老师可以教多个学生,一个学生也可以从多个老师那里学习知识。创建表格时,将多对多的关系拆分为多个一对多关系。

#14、数据库表的连接方式

内连接:inner join……on…… :取交集

外连接:

  • 1)left join……on…… :以左表为准,查询出左表的所有数据,右表中有对应的则显示出来,没有对应的则显示为null;
  • 2)right join……on…… :以右表为准,查询出右表的所有数据,左表中有对应的则显示出来,没有对应的则显示为null;
  • 3)full join……on…… :left和right的集合,某表中某一行在另一表中无匹配行,则相应列的内容为null;

交叉连接:cross join…… :笛卡尔积,相当于两个表中的所有行进行排列组合。

#15、存储过程与存储函数

存储过程:为以后的使用而保存的一条或多条SQL语句的集合,相当于批处理。存储过程被编译后会被直接保存在数据库中,成为数据库的一部分,以后就可以反复调用、运行速度快。

-- in表示输入变量,out表示输出变量,inout输入输出均可
create procedure myprocedure([IN|OUT|INOUT] 参数名 数据类型, [IN|OUT|INOUT] 参数名 数据类型, ...)
begin
...
end

存储函数:

create function myfunction(参数名 数据类型, ...) returns 返回类型
begin
...
end

二者区别:

  • 存储函数限制较多,例如不能使用临时表,只能用表变量,而存储过程限制较少;
  • 存储过程可以实现复杂的功能,存储函数针对性比较强;
  • 返回值不同,存储过程可以没有返回值,也可以返回单个或多个结果集,而存储函数有且仅有一个返回值;
  • 调用不同。存储过程通过call语句调用,存储函数通过select调用;
  • 参数不同。存储过程的参数类型可以是in、out、inout,而存储函数的参数类型只有in类型。
#16、触发器

SQL触发器是一种特殊类型的存储过程,不由用户调用。它在指定的表中的数据发生变化时自动生效。唤醒调用触发器以响应Insert、Update和Delete语句。他可以查询其它表,并可以包含复杂的Transact-SQL语句。将触发器和触发它的语句作为可在触发器内回滚的单个事务对待。如果检测到严重错误,整个事务自动回滚。

优点:

  • 触发器可通过数据库中的相关表实现级联更改;
  • 触发器可以强制比用check约束定义的约束更为复杂的约束;
  • 在约束所支持的功能无法满足应用程序的功能要求时,触发器就极为有用。
create trigger trigger_order after insert on orders for each row
begin
update product set pnum = pnum - new.onum where pid = new.pid;
end
#17、数据库的锁机制

MyISAM和InnoDB存储引擎使用的锁:

MyISAM采用表级锁(table-level locking),InnoDB支持行级锁(row-level locking)和表级锁,默认为行级锁。

二者对比:

  • 表级锁:MySQL中粒度最大的锁,对当前操作的整张表加锁,实现简单,资源消耗少,加锁快,不会出现死锁。锁冲突的概率高,并发度低。
  • 行级锁:MySQL中粒度最小的锁,只针对当前操作的行进行加锁。行级锁能大大减少数据库操作的冲突。加锁慢,开销大,并发度高,会出现死锁。

InnoDB引擎的锁算法:

  • Record lock:记录锁。条件为精准匹配时,锁住具体的索引项;

  • Gap lock:间隙锁。锁定一个范围,不包括记录本身。

  • Next-key lock:临键锁。锁定一个范围,包含记录本身。

按思想分为乐观锁和悲观锁

  • 乐观锁:事务并发操作时认为不会发生冲突,对数据进行更新并提交,如果检测到冲突就返回。
  • 悲观锁:事务并发操作使认为会发生冲突,先进行加锁操作。
#18、日志

bin log:二进制日志(服务层):涉及到主从复制;

redo log:重做日志(引擎层):数据的灾后重新提交,物理日志。包括两部分,内存中的日志缓存(redo log buffer)(易失性)和磁盘上的重做日志(redo log file)(持久性),需要将redo log buffer通过操作系统内核空间的OS buffer刷到磁盘上的log file中。

undo log:回滚日志(引擎层):主要用于数据修改的回滚,逻辑日志。会给予与操作相反的语句,当事务回滚时从undo log中反向读取内容。

MVCC:Multiversion concurrency control,多版本并发控制,实现并发和回滚的重要功能。它指的是数据库中的每一条数据,会存在多个版本。对同一条数据而言,MySQL 会通过一定的手段(ReadView 机制)控制每一个事务看到不同版本的数据,这样也就解决了不可重复读的问题。

#19、解决幻读

Innodb引擎中,每条聚集索引都会有两个隐藏字段:trx_idroll_pointer,每次事务对一条记录进行改动时,就会将事务id赋值给trx_id,并且会将旧数据写入一条undo日志,每条undo日志都有roll_pointer属性,可以将这些undo日志都连起来,串成一个链表,undo日志的写入采用头插法,新数据在前。

  • 快照读: MVCC中有一个ReadView的概念,其中记录了生成ReadView时的活跃事务id列表:m_ids最小事务id:min_trx_id将要分配给下一个事务的id:max_trx_id生成ReadView的事务id:creator_trx_id。如果被访问版本的trx_idcreator_trx_id相同或者小于min_trx_id,则可以访问;如果被访问版本的trx_id大于等于max_trx_id,则不能访问;如果被访问版本的trx_idmin_trx_idmax_trx_id之间,则当trx_id不在m_ids中时才能访问。
  • 当前读: InnoDB存储引擎有三种锁:Record lock:单个行记录上的锁;Gap lock:间隙锁,锁定一个范围,不包括记录本身;Next-key lockrecord+gap 锁定一个范围,包含记录本身。innodb对于行的查询使用next-key lock,当查询的索引含有唯一属性时,将next-key lock降级为record key
#20、数据库的索引机制

需要创建索引的情况:

  • 主键自动建立唯一索引;
  • 频繁作为查询条件的字段;
  • 查询与其它表关联的字段,外键关系建立索引;
  • 查询中排序的字段(通过索引访问将大大提高排序速度);
  • 查询中统计或分组的字段。

不需要创建索引的情况:

  • 表记录太少;
  • 经常增删改的表;
  • 频繁更新的字段;
  • where条件里用不到的字段;
  • 数据重复且分布平均的字段
#21、explain关键字

id:选择标识符;select_type:查询的类型;table:输出结果集的表;type:表的连接类型;possible_keys:可能使用的索引;key:实际使用的索引;key_len:索引字段的长度;ref:列与索引的比较;rows:扫描出的行数;extra:执行情况的描述和说明。

#22、索引优化思路

开启慢查询日志设置阈值;explain做慢SQL分析。

查询截取分析:using filesort效率低,using index效率高;最左前缀原则

#23、索引创建规则

最左前缀匹配原则:mysql会一直向右匹配指导遇到范围查询(betwee、like)就停止查询;选择区分度高的列作为索引;选择唯一性索引;尽量使用数据量少的索引;尽量使用前缀来索引;索引列不能参与计算;尽量的扩展索引不要新建索引;限制索引的数目。

#24、索引过多的问题

一般一个表对应5个索引左右,索引过多会导致:查找数据变慢;对insert语句影响很大,尤其是无序插入;删除数据多的情况下索引也需要更新;索引文件过大,占用存储空间,寻址的查询时间长;mysql优化器需要评估更多的组合。

#25、数据库数据导入与索引建立的顺序

数据库插入大量数据时需要先删除索引,插入完成后在重建索引,索引会影响插入数据的速度,因此先导入数据再插入索引。

#26、MySQL调优

合理添加索引;做索引的列不包含null值;用复合索引代替单索引;使用短索引;减少模糊扫描like和not in;读写分离;redis缓存;limit分页机制。

#27、MySQL主从复制

什么是主从复制

主从复制,是用来建立一个和主数据库完全一样的数据库环境,称为从数据库;

主从复制的作用

实时灾备,用于故障切换;架构扩展,提升机器性能;读写分离,避免影响业务

主从复制的原理

  • 数据库有个bin-log二进制文件,记录了所有sql语句。

  • 目标就是把主数据库的bin-log文件的sql语句复制过来。

  • 使其在从数据库的relay-log重做日志文件中再执行一次这些sql语句即可。

  • 主从复制配置具体需要三个线程: > - binlog输出线程:每当有从库连接到主库的时候,主库都会创建一个线程然后发送binlog内容到从库。在从库里,当复制开始的时候,从库就会创建以下两个线程进行处理。

    • 从库I/O线程:当START SLAVE语句在从库开始执行之后,从库创建一个I/O线程,该线程连接到主库并请求主库发送binlog里面的更新记录到从库上。从库I/O线程读取主库的binlog输出线程发送的更新并拷贝这些更新到本地文件,其中包括relay log文件。
    • 从库SQL线程:从库创建一个SQL线程,这个线程读取从库I/O线程写到relay log的更新事件并执行。
  • 对于每一个主从复制的连接,都有三个线程。拥有多个从库的主库为每一个连接到主库的从库创建一个binlog输出线程,每一个从库都有它自己的I/O线程和SQL线程。

interview-database-copy.png

#非关系型数据库Redis

#28、缓存

缓存就是数据交换的缓冲区,当硬件要读取数据时首先在缓存中查找,不存在时从内存中查找。缓存查找比内存查找更快。

缓存在不同场景下的应用:磁盘缓存——减少磁盘的机械操作;数据库缓存——减少对数据库的访问(redis)。客户端浏览器缓存——减少浏览器对服务器的访问。

数据库缓存的用处在于应对慢查询,环境数据库压力,适用于高性能高并发并且对实时性要求不高的场景。

缓存失效的策略:FIFO(先进先出,根据存储的时间进行淘汰),LRU(最近最少使用,根据使用时间淘汰最远的数据)、LFU(最不经常使用,根据使用频率进行淘汰)。

#29、redis简介

简介:非关系型数据库,广泛应用于缓存方向,提供了String(key-value类型,计数器)、List(链表,粉丝列表/消息列表)、Hash(底层hashtable,key是key,value可以看作是一个map,用于存储个人信息)、Set(底层是hashtable,可以实现交并差集操作,用于记录共同关注/共同喜好)以及ZSet(常用于排行榜)数据类型支持不同的场景业务。redis支持事务、持久化、集群等。

为什么用:高性能及高并发场景、减少数据库访问压力等。

与Memcached的区别:redis支持更丰富的数据类型,后者仅支持string;redis支持持久化(RDB和AOF),后者不支持;redis具有半事务支持(MULTI开启事务,EXEC执行事务块,DISCARD清空事务队列,WATCH监视),后者不支持;redis支持集群,可以进行主从复制进行数据备份,后者不可以;redis是单线程的,后者是多线程的。

内存淘汰策略:1)volatile-lru:从已设置过期时间的数据集中挑选最近最少使用的数据淘汰;2)volatile-ttl:从已设置过期时间的数据集中挑选将要过期的数据淘汰;3)volatile-random:从已设置过期时间的数据集中任意挑选数据淘汰;4)allkeys-lru:从所有数据集中选择最近最少使用的数据淘汰;5)allkeys-random:从所有数据集中随机选择数据淘汰;6)no-eviction:禁止淘汰数据。7)4.0版本后新增volatile-lfu和allkeys-lfu。

持久化:RDB快照:将某个时间点的所有数据都存放到硬盘上;AOF快照:将写命令添加到AOF文件末尾。使用AOF持久化需要设置同步选项,从而确保写命令何时会同同步到磁盘文件上。AOF比RDB更新频率高,优先使用AOF;AOF比RDB更安全;RDB性能比AOF好;优先加载AOF。

#30、redis的问题及解决办法

缓存穿透:大量请求的key不存在于缓存中,导致请求直接到了数据库上,没有经过缓存这一层。采用布隆过滤器可以解决这个问题。将可能存在请求的key放在布隆过滤器,当有非法key访问时,先判断是否再布隆过滤器存在,不存在直接返回参数错误信息。

缓存雪崩:缓存同一时间大面积失效,后面的请求都落在数据库上,造成数据库短时间承受大量请求而崩掉。解决办法:1)事前:尽量保证整个redis集群的高可用性,发现有机器宕掉后尽快补上。同时选择合适的淘汰策略;2)事中:本地encache缓存+hystrix限流&降级,避免MySQL崩掉;3)事后:利用redis持久化机制恢复缓存。

缓存击穿:过于热点的数据在缓存过期的瞬间,数据库会被过量访问。解决方法:1)设置热点数据永不过期;2)加互斥锁。

一致性:读请求和写请求串行化,串到一个内存队列中,保证双写一致性,但会系统导致吞吐量下降。延时双删保证一致性,先删除缓存,然后更新数据,再延时n ms后删除缓存。

#部分情景题

#31、微服务设计模式

聚合器微服务设计模式、代理微服务设计模式、分支微服务设计模式、链式微服务设计模式、数据共享微服务设计模式、异步消息传递微服务设计模式

#32、Spring的优点

轻量:大小和开销都是轻量的,非侵入式,即对象不依赖于Spring特定类;控制反转(IOC):将所有对象的创建和依赖关系的维护工作都交给IOC容器来管理,大大的降低了组件之间的耦合性;面向切面(AOP):把将一些通用任务,如安全、事物、日志等进行集中式处理,从而提高了程序的复用性;方便集成各种优秀框架,如MyBatis、Hibernate等;方便程序测试,提供可对Junit4的支持;支持声明式事务处理,通过配置文件就可以完成对事务的管理,无须手动编程。

#33、Springboot的优点

创建独立的Spring应用程序;嵌入的Tomcat,无序部署war文件;简化配置;自动配置Spring;快速整合第三方框架;能够于Spring生态的Spring JDBC、Spring Security等快速整合;提高了开发效率。

#34、系统架构风格以及优缺点

1)单体架构

介绍:把系统中所用的功能、模块耦合在一个应用中的架构方式。特点:打包成一个独立的单元(一个jar包或者war包),以进程的方式来运行。

优点:项目易于管理,部署简单。

缺点:测试成本高、可伸缩性差、可靠性差、迭代困难、跨语言程度差、团队协作难。

2)MVC架构

介绍:MVC是模型(Model)、视图(View)和控制器(Controller)。Model,主要是数据、业务逻辑和业务规则;View的目的在于提供与用户交互的界面;Contorller指的是控制器,主要负责与model和view打交道。

优点:MVC三层各司其职、互不干涉;有利于开发中的分工;有利于组件的重用。

缺点:增加了系统结构和实现的复杂性;View和Controller键连接过于紧密;View对Model数据的访问效率低。

3)面向服务架构(SOA)

介绍:SOA是一个组件模型,将应用程序拆分为不同功能单元(称为服务),通过这些服务间定义良好的接口和契约联系起来,使得构建在各种系统中的服务可以以一种同一和通用的方式进行交互。特点在于系统由多个服务组成,每个服务可以单独部署,每个服务内部室高内聚的,外部是低耦合的。

优点:测试容易、可伸缩性强、可靠性强、迭代容易、跨语言程度更灵活、团队协作容易。

缺点:服务部署过多导致运维成本高;分布式系统的复杂性等。

4)微服务架构

介绍:微服务架构可以说是更加细腻化的SOA,如果说SOA是粗粒度的划分,那么微服务的划分粒度更小,更加精确,SOA可以说由多个微服务组成。

优点同SOA,另外服务划分更加细致;缺点同上。

#35、系统安全架构包括

基础设施安全、应用系统安全(sql注入、xss攻击等)、数据保密安全(存储安全、传输安全)

#36、系统性能下降的原因及解决方法

硬件升级无法满足大数据流量情况下,系统性能下降的原因:

服务器超载、带宽瓶颈、传输距离遥远

解决方法:

分布式消息队列、服务器集群、redis缓存、cdn节点、数据库读写分离

#37、从数据库设计和软件性能改善高并发访问

库表散列、优化索引、存储过程、读写分离、redis缓存、消息队列

#38、针对高并发访问设计新的架构

HTML静态化、cdn节点、图片服务器分离、服务器集群、数据库集群、ngnix反向代理做负载均衡

#39、SSL加密过程

interview-database-ssl.png