2.6.1有没有用过Linux?你都用它来做什么?
Linux是一个长时间运行比较稳定的操作系统,所以我们一般会拿他作为服务器(web,db,app等)。
Linux本身具有C的编译环境,我们的一些软件是没有软件包的(redis等),需要在Linux的C编译环境编译得到软件包
2.6.2说一下Linux下面的一些常用命令
常用:
pwd 获取当前路径
cd 跳转到目录
su -u 切换到管理员
ls 列举目录
文件操作命令:
文件
tail 查看
rm -rf 删除
vim 修改
文件夹
mkdir 创建
rm -r 删除
2.6.3你使用什么来连接远程的Linux服务器
连接远程需要依赖于Linux服务器安装ssh服务端,一般这个ssh服务的端口为22
连接远程需要依赖于Linux服务器安装sftp服务端,一般这个sftp服务的端口为25
使用ssh客户端连接Linux服务器,就有点儿像Windows下面的远程连接,但是Linux通过ssh连接上以后是没有图形界面,全是命令。
putty
Xshell
使用sftp客户端来连接sftp服务端,来上传和下载文件。(上传安装包,修改配置文件上传。)
winscp
xftp
企业中常用的两种组合:
putty+winscp
xshell+sftp+manager
面试:使用xshell、putty等ssh客户端来连接服务器,使用xftp、winscp等sftp客户端来上传和下载文件,连接和上传、下载必须依赖于服务器的ssh、sftp服务,也就是Linux服务器需要启动这两个服务。
2.6.4有没有使用过云主机?
使用过,在原来的公司,我们没有使用自己的服务器,而是租用阿里的云主机。
没有使用过,但有所了解。
云主机就是一些云服务运营商(阿里、华为、西部数码、新浪等),提供的远程的服务器功能,我们开发者或者企业只需要按需付费就可以租用对应的服务器。
使用ssh和sftp来进行操作
2.6.5有没有做过数据库优化方面的事情?
做过mysql数据库的优化,其他数据库类似
查找、定位慢查询,并优化
优化手段:
1、创建索引:创建合适的索引,我们就可以在索引中查询,查询到以后直接找对应的纪录。
2、分表:当一张表的数据比较多或者一张表的某些字段的值比较多并且很少使用时,采用水平分表和垂直分表来优化。
3、读写分离:当一台服务器不能满足需求时,采用读写分离的方式来进行集群。
4、缓存:使用redis来进行缓存
5、一些常用优化技巧
2.6.6查找慢查询并定位慢查询?
在项目自验项目转测试之前,在启动mysql数据库时开启慢查询,并且把执行慢的语句写到日志中,在运行一定时间后,通过查看日志找到慢查询语句。
使用explain慢查询语句,来详细分析语句的问题
2.6.6数据库优化之遵循范式
数据库设计时需要遵循方式
什么样的表才是符合3NF(范式)
表的范式,是首先符合1NF,才能满足2NF,进一步满足3NF
1NF:即表的列具有原子性,不可再分割,即列的信息,不能分解,还要数据库是关系型数据库(mysql/oracle/db2/sybase/sql server),就自动满足1NF,关系型数据库中是不允许分割列的。
2NF:表中的记录是唯一的,通常我们设计一个主键来实现
3NF:即表中不要有冗余数据,就是说,表的信息,如果能够被推导出来,是不应该单独的设计一个表字段来存放。
反3NF:没有冗余的数据库未必是最好的数据库,有时为了提高运行效率,就必须降低范式标准,适当保留冗余数据库,具体做法是:在概念数据库模型设计时遵守第三范式,降低范式标准的工作放到物理数据模型设计时考虑,降低范式就是增加字段,允许冗余。比如:订单和订单项、相册浏览次数和照片的浏览次数
2.6.7选择合适的存储引擎
在开发中,我们经常使用的存储引擎myisam/innodb/memory
MyISAM存储引擎
如果表对事物要求不高,同时是以查询和添加为主的,我们考虑使用myisam存储引擎,比如bbs中的发帖表,回复表。
INNODB存储引擎:
对事务要求高,保存的数据都是重要数据,我们建议使用INNODB,比如订单表,账号表
Memory存储引擎
我们数据变化频繁,不需要入库,同时又频繁的查询和修改,我们考虑使用memory,速度极快。
问MyISAM和INNODB的区别(重要)
1、事务安全 myisam不支持事务而innodb支持
2、查询和添加速度 myisam不用支持事务就不用考虑同步锁,查询和添加的速度快
3、支持全文搜索 myisam支持,innodb不支持
4、锁机制 myisam支持表锁,innodb支持行锁
5、外键 MyISAM不支持外键,INNODB支持外键(通常不设置外键,通常是在程序中保证数据的一致)
2.6.8数据库优化之创建合适的索引
索引(index)是帮助DBMS高效获取数据的数据结构
分类:普通索引/唯一索引/主键索引/全文索引
普通索引:允许重复的值出现
唯一索引:除了不能有重复的记录外,其他和普通索引一样(用户名,身份证,email,tel)
主键索引:是随着设定主键而创建的,也就是把某个列设为主键的时候,数据库就会给该 列创建索引,这也就是主键索引,唯一且没有null值
全文索引:用来对表中的文本域(char,varchar,text)进行索引,全文索引针对MyISAM
explain select * from articiles match(title,body) against(‘database’)【会使用全文索引】
2.6.9索引使用小技巧
索引弊端:
1、占用磁盘空间
2、对dml(插入、修改、删除)操作有影响,变慢
使用场景:
a、肯定在where条件经常使用,如果不做查询就没有意义
b、该字段内容不是唯一的几个值(sex)
c、字段内容不是频繁变化
具体技巧:
1、对于创建的多列索引(复合索引),不是使用的第一部分就不会使用索引
alter table dept add index my_ind(dname, loc); //dname 左边的列,loc 就是右边的列
explain select * from dept where dname = ‘aaa’ 会使用到索引
explain select * from dept where loc = ‘aaa’ 就不会使用到索引
2、对于使用like的查询,查询如果是’%aaa’不会使用到索引,而’aaa%’会使用到索引
explain select * from dept where dname like ‘%aaa’ 不会使用索引
explain select * from dept where dname like ‘aaa%’ 会使用索引
所以在like查询时,关键字的最前面不能使用% 或者_ 这样的字符,如果一定要前面有变化的值,则考虑使用全文索引
3、如果条件中有or,有条件没有使用索引,即使其中有条件带索引也不会使用,换言之,就是要求使用的所有字段,都必须单独使用时能使用索引。
explain select * from dept where dname =‘aaa’;
explain select * from dept where loc = ‘aaa’;
explain select * from dept where deptno = ‘102’;
select * from dept where dname =‘xxx’ or loc = ‘xx’;
select * from dept where dname =‘xxx’ or deptno = 45;
select * from dept where dname =‘xxx’ or loc = ‘xx’ or deptno = ‘45’;
4、如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引。
explain select * from dept where dname =‘111’;
explain select * from dept where dname = 111; 数值自动转字符串
explain select * from dept where dname = ddd; 报错
5、如果mysql估计会使用全表扫描要比使用索引快,则不使用索引
表里面只有一条数据
2.6.10数据库优化之分表
分表分为水平(按行)分表和垂直(按列)分表
根据经验,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算法计算出数据存储表的表名,然后访问相应的表。
按如下分10张表
2.6.11数据库优化之读写分离
一台数据库支持的最大并发连接数是有限的,如果用户并发访问太多,一台服务器满足不了要求时就可以集群处理,mysql的集群处理技术最常用的就是读写分离。
主从同步
数据库最终会把数据持久化到磁盘,如果集群必须确保每个数据服务器的数据是一致的,能改变数据库的操作都要往主数据库去写,而其他数据库从主数据库上同步数据。
读写分离
使用负载均衡来实现写的操作都往主数据库去,而读的操作往服务器去。
2.6.12数据库优化之缓存
在持久层(dao)数数据库(db)之间添加一个缓存层,如果用户访问的数据已经缓存起来时,在用户访问时直接从缓存层中获取,不用访问数据库,而缓存是在操作内存级的,访问速度快
作用:减少数据库服务器压力,减少时间。
Java中常用的缓存有,
1.Hibernate的二级缓存,该缓存不能完成分布式缓存
2.可以使用redis作为中央缓存。
2.6.13语句优化小技巧
DDL优化:
1、通过禁用索引来提供导入数据性能,这个操作主要针对有数据库的表,追加数据
//去除键
alter table test3 disable keys;
//批量插入数据
insert into test3 select * from test;
//恢复键
alter table test3 enable keys;
2、关闭唯一检验
set unique_checks=0 关闭;
set unique_checks=1 开启;
3、修改事务提交方式(导入)(变多次提交为一次)
set autocommit=0 关闭
set autocommit=1 开启
DDL优化
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);
DQL优化
Order by优化
1、多用索引排序
2、普通结果排序(非索引排序
group by优化
是使用order by null 取消默认排序)
子查询优化
在客户列表找到不在支付列表的客户
在客户列表找到不在支付列表的客户,查询没买过东西的客户
explain select * from customer where customer_id not in (select distinct customer_id from payment) #子查询 --这种事基于func外链
explain select * from customer c left join payment p on(c.customer_id=p.customer_id) where p.customer_id null --这种事基于“索引”的外链
Or优化
在两个独立索引上使用or的性能优质
1、or两边都是用索引字段判断,性能好
2、or两边,有一边不用,性能差
3、如果employee表的name和email这两列是一个复合索引,但是如果是:name=”A” or email=”@” 这种方式,不会用到索引!
limit优化
select film_id,description from film order by title limit so,s;
select a.film_id,a.description from film a inner join(select film_id from film order by title limit so,s) b on a.film_id=b.film.id;
2.6.14批量插入几百万数据怎么实现
原理:
1、变多次提交为一次
2、使用批量操作
2.6.15有没有使用过redis?redis是什么
redis是一个key-value的nosql数据库,先存到内存中,会根据一定的策略持久化到磁盘,即使断电也不会丢失数据库,支持的数据类型比较多
主要用来做缓存数据库的数据和web集群时当做中央缓存存放session。
2.6.16简单说一下redis的使用场景
缓存:
把经常需要查询的,很少修改的数据,放到读速度快的空间(内存),以便下次访问减少时间,减轻压力,减少访问时间。
计数器:
redis中的计数器是原子性的内存操作
可以解决库存溢出的问题。进销存系统库存溢出
session缓存服务器:
web集群时作为session缓存服务器
缓存队列等
2.6.17redis对象保存方式
json字符串
需要把对象转换为json字符串,当字符串处理,直接使用set、get来设置或者获取
优点:设置和获取比较简单
缺点:没有提供专门的方法,需要把对象转换为json(jsonlib)
字节
需要做序列化,就是把对象序列化为字节保存
如果是数据完全可以使用JSON方式,毕竟redis直接set、get使用起来门槛低很多,redis是没有提供专门的设置对象方法,需要自己进行改写。
如果是担心json转对象会消耗资源的情况,这个问题需要考量几个地方,
第一点:就是使用的json转换lib是否就会存在性能问题
第二点:就是数据的数据量级别,如果存储百万级的大数据对象,建议采用存储序列化对象方式,如果是少量的数据级对象,或者是数据对象字段不多,还是建议采用json转换成string方式。
毕竟redis对存储字符类型这部分优化的非常好,具体采用的方式与方法,还是要看你所使用的场景。
2.6.18redis数据淘汰机制
在redis中,允许用户设置最大使用内存大小server.maxmemory,在内存限定的情况下是很有用的,譬如,在一台8G机子上部署了4个redis服务点,每一个服务点分配1.5G的内存大小,减少内存紧张的情况,由此获取更为稳健的服务。
内存大小有限,需要保持有限的数据
redis内存数据集大小上升到一定大小的时候,就会实施数据淘汰策略,redis提供6中数据淘汰策略。
volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
no-enviction(驱逐):禁止驱逐数据
redis 确定驱逐某个键值对后,会删除这个数据并,并将这个数据变更消息发布到本地(AOF持久化)和从机(主从连接)。
2.6.19Java访问redis
1、使用jedis java客户端访问redis服务器,有点类似通过jdbc访问mysql一样。
2、当然如果是spring进行集群时,可以使用spring data来访问redis,spring data只是对jedis的二次封装
2.6.20redis集群
当一台数据无法满足要求,可以使用redis集群来处理,类似于mysql的读写分离