java面试⑦高级部分
常用:
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.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不支持(mysql5.6 innobodb好像也支持)
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’;
注意:要想使用or,又想让索引生效,只能将or条件中的每个列都加上索引
http://www.cnblogs.com/crazylqy/p/7535687.html
4、如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引。
explain select * from dept where dname =‘111’;
explain select * from dept where dname = 111; 数值自动转字符串
explain select * from dept where dname = ddd; 报错
5、如果mysql估计会使用全表扫描要比使用索引快,则不使用索引
表里面只有一条数据
6.性别适合用索引吗
因为只有两个值,比较很简单,排序也方便,加索引所消耗的系统资源比不加更多.
性别字段的选择性低,使用索引查找还不如遍历表的效率高,即使加了索引SQL Server也不会使用该索引查找。因为它会重复很多次,“如果只有很少的非重复值,如只有 1 和 0,则大多数查询将不使用索引,因为此时表扫描通常更有效”
索引
首先你得理解索引是用来干什么的
然后再来介绍为什么性别字段为什么不适合建立索引
下面是索引的定义
索引的用途
索引是以表列为基础的数据库对象,它保存着表中排序的索引列,并且记录了索引列在数据表中的物理存储位置,实现了表中数据的逻辑排序,其主要目的是提高SQL Server系统的性能,加快数据的查询速度和减少系统的响应时间。
使用索引的代价
建立索引的几点原则。
(1) 定义有主键的数据列一定要建立索引。因为主键可以加速定位到表中的某一行。
(2) 定义有外键的数据列一定要建立索引。外键列通常用于表与表之间的连接,在其上创建索引可以加快表间的连接。
(3) 对于经常查询的数据列最好建立索引。
① 对于需要在指定范围内快速或频繁查询的数据列,因为索引已经排序,其指定的范围是连续的,查询可以利用索引的排序,加快查询的时间。
② 经常用在WHERE子句中的数据列,将索引建立在WHERE子句的集合过程中,对于需要加速或频繁检索的数据列,可以让这些经常参与查询的数据列按照索引的排序进行查询,加快查询的时间。
(4) 对于那些查询中很少涉及的列、重复值比较多的列不要建立索引。例如,在查询中很少使用的列,有无索引并不能提高查询的速度,相反增加了系统维护时间和消耗了系统空间;又如,“性别”列只有列值“男”和“女”,增加索引并不能显著提高查询的速度。
(5) 对于定义为text、image和bit数据类型的列不要建立索引。因为这些数据类型的数据列的数据量要么很大,要么很小,不利于使用索引。
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、使用批量操作
3.jdbc
url = "jdbc:mysql://localhost:3306/test01?rewriteBatchedStatements=true";
使用JDBC批量操作往数据库插入100W+的数据貌似也挺快
http://www.cnblogs.com/crazylqy/p/7535776.html
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的读写分离