网络基础

 

对象的内存布局

对象头(header)、实例数据(Instance Data)、对齐填充

java对象头里的Mark Word里默认存储对象的HashCode、分代年龄和锁标记位(包括锁标志位和是否是偏向锁)

锁一共4种状态,级别从低到高分依次是:无锁状态,偏向锁状态,轻量级锁状态和重量级锁状态

 

jvm垃圾收集

1、内存划分:栈内存,堆内存,方法区

2、堆内存划分

新生代,老年代和永久代

新生代又可划分为Eden区,Survivor 1区和Survivor 2区。新创建的对象会分配在Eden区,在经历一次Minor GC后会被移到Survivor 1区,再经历一次Minor GC后会被移到Survivor 2区,直到升至老年代,需要注意的是,一些大对象(长字符串或数组)可能会直接存放到老年代

大多数情况下,对象在新生代Eden区中分配,当Eden没有足够空间进行分配时,虚拟机将发起一次Minor GC(发生在新生代的垃圾收集动作)

新的对象实例会优先分配在新生代,在经历几次Minor GC后(默认15次),还存活的会被移至老年代

Full GC:指发生在老年代的GC

Minor GC发生在新生代,当Eden区没有足够空间时,会发起一次Minor GC,将Eden区中的存活对象移至Survivor区。Major GC发生在老年代,当升到老年代的对象大于老年代剩余空间时会发生Major GC

表的优化

1、定长与变长分离

定长:int,char,time

变长:varchar,text,blob

2、常用字段和不常用字段分离

3、一对多,需要关联统计的字段上,添加冗余字段(论坛版块列表,回复数)

4、列选择原则:

1)字段类型优先级:整型>date,time>char,enum>varchar>blob.text

2)够用就行,不用慷慨

3)尽量避免使用NULL():在磁盘上占用更大的空间,NULL()不利于索引,要用特殊的字符来表示

5、MYSQL索引类型:BTree索引、Hash索引

hash索引是在memory表里的,即在内存中存在

hash索引的弊端:

1)无法对范围查询进行优化

2)无法利用前缀索引

3)无法对排序进行优化

4)必须回行,即通过索引拿到表的位置,必须回到表中取数据

6、BTree索引常见误区

1)在where条件常用的列上都加上索引——独立索引只能用上一个

2)在多列上建立联合索引后,查询哪个列,索引都能发挥作用——必须依照索引的顺序,且满足左前缀要求

索引可以提高查询速度,排序速度和分组统计的速度

7、创建联合索引

create table t4 (
c1 tinyint(1) not null default 0,
c2 tinyint(1) not null default 0,
c3 tinyint(1) not null default 0,
c4 tinyint(1) not null default 0,
c5 tinyint(1) not null default 0,
index c1234(c1,c2,c3,c4)
);

8、分析索引的使用情况:explain

Innodb和myisam都是使用的BTree索引

但是myisam使用的是非聚簇索引——索引表和数据表分离,其索引指向某行在磁盘上的位置,不同索引树之间并无关联

innodb使用的是聚簇索引,数据和索引一块存放,不用回行,其索引,指向对主键的引用,非主键索引树指向主键索引

叶子比较重,且主键无规律,容易出现叶分裂

索引覆盖,优化的目的在于尽量少从磁盘上拿数据
性能分析工具:show profiles—— set profiling=1

9、理想的索引:

1)查询频繁

2)区分度高

3)长度小

4)尽量能覆盖常用查询字段

 index(cat_id,price),index(cat_id,brand_id,shop_price);

10、索引与排序

排序可能发生两种情况:

1)对于索引覆盖,直接在索引上查询时,就是有顺序的,using index

2)如果没有索引,先取出临时数据,形成临时表做firesort(文件排序,可能在磁盘上,也可能在内存中)

我们的争取目标——取出来的数据本身就是有序的,利用索引来排序

对于myisam而言,对所有数据排序时并不是每取一次索引然后去磁盘上取相应数据,而是将所有数据都取出来进行filesort

独立的索引在每次查询中只能使用一个,应该尽量避免查询中出现filesort

where 后面的字段和 order by后面的字段不一致的时候,也会出新filesort现象,因为独立索引只能使用一个,查询时用到了一个索引,在排序时就不能使用排序字段的索引了

11、索引相关的操作语句

冗余索引较为常见,常用的为两个相同字段按先后顺序分别建立不同的索引

12、表修复——索引碎片及维护

方式一:nop操作,不对数据产生实际影响——alter table xxx engine InnoDB

方式二:optimize table  name

注意: innodb来说,

1: 主键索引 既存储索引值,又在叶子中存储行的数据

2: 如果没有主键, 则会Unique key做主键

3: 如果没有unique,则系统生成一个内部的rowid做主键.

4: innodb,主键的索引结构中,既存储了主键值,又存储了行数据,这种结构称为”聚簇索引”

13、SQL语句优化

sql语句的执行时间花在哪了?

查找——沿着索引查找,慢者可能全表扫描

取出——查到行后,把数据取出来

如何查询快?

1)查询——联合索引的顺序,区分度,长度

2)取的快,索引覆盖

3)传输更少,更少的行和列

尽量走索引进行查询

14、explain 解释一个查询语句的执行计划

字段详解:

       id:查询的序号,表明select语句

  select_type:

      simple:不含子查询

      primary:含子查询

        dependent subquery:非from子查询

        derived:from子查询

        union 和 union result

  table:查询的表名

    实际的表名,表的别名,derived(from类型的子查询),null (union)

  type:索引所发挥的作用

    all:做全表扫描,where后面查询条件列中没有索引。利用索引来排序,但是取出来是所有的节点,所以也会出现all的情况

    Index:比all性能稍微好点,all扫描所有的数据行,相当于data_all,indux扫描所有的索引节点,相当于index_all

    range:索引范围扫描

    ref:精准查询,可以直接引用到某些行数据

    eq_ref:

    const,system,null:查询优化到常量级别,甚至不需要查询时间,一般按主键查询时,能出现这种情况

  possible_keys:可能用到的键

  key:真正用到的键

  key_len:表的长度

  ref:两表联查时候的引用关系

  rows:本次查询返回的行数

  extra:额外的信息

    index:用到了索引覆盖,效率非常高

    using where:光靠索引定位不了,还得where进行判断

    using temporary:是指用上了临时表,order by与group by不同列时,或group by,order by别的表的列

    using filesort:文件排序(文件可能在磁盘,也可能在内存)

  

  如果取出的列含有text,或者更大的如mediumtext等,filesort将会发生在磁盘上

  show status like '%_table%':查看磁盘使用情况

15、In型子查询的误区:

mysql的查询优化器,针对In型做了优化,被改成了exists子查询的执行效果,当goods表越大时,查询速度越慢

改进:用连接查询代替子查询

 explain select goods_id,g.cat_id,g.goods_name from  goods as g

 inner join (select cat_id from ecs_category where parent_id=6) as t

 using(cat_id) \G

16、from型子查询

注意::内层from语句查到的临时表, 是没有索引的.

所以: from的返回内容要尽量少.

17、count(*)优化

18、group by、order by

19、union总是要产生临时表

尽量使用union all,不去重,不排序

20、limit 及翻页优化

limit offset,N,  offset非常大时, 效率极低,

原因是mysql并不是跳过offset,然后单取N,

而是取offset+N,返回放弃前offset,返回N.

效率较低,offset越大时,效率越低

show profiles;

set profiling=1;

show profile for query 5

尽量沿着索引爬行

select id,name from lx_com where id>5000000 limit 10;

非要物理删除,还要用offset精确查询,还不限制用户分页,怎么办?

select id,name from lx_com inner join (select id from lx_com limit 5000000,10) as tmp using(id);

数据库底层原理,调优

 

数据表设计原则

1、从空间上考虑用varchar,从效率上考虑,用char

varchar类型的实际长度,是它的值的实际长度+1,+1的字节用于保存实际用了多大长度

2、存储过程

可移植性较差

定义存储过程:

delimiter %

create procedure 过程名(参数1,参数2)

begin

  sql语句

end

调用方式:

call 过程名(参数1,参数2)

存储过程参数传递;

IN参数

in传入参数,把参数传递到过程内部

特点:读取外部变量值,且有效范围仅限存储过程内部

out:传出参数

inout:传入传出参数

into:赋值

mysql中的变量

1)局部变量

局部变量一般用在sql语句块中,比如存储过程的begin/end。其作用域仅限于该语句块,在该语句块执行完毕后,局部变量就消失了。

局部变量一般用declare来声明,可以使用default来说明默认值。

drop procedure if exists add;

create procedure add( in a int, in b int)

begin

    declare c int default 0;

    set c = a + b;

    select c as c;

end;

2)用户变量

用户变量的作用域要比局部变量要广。用户变量可以作用于当前整个连接,但是当当前连接断开后,其所定义的用户变量都会消失。

用户变量使用如下(这里我们无须使用declare关键字进行定义,可以直接这样使用):

select @变量名

对用户变量赋值有两种方式,一种是直接用"="号,另一种是用":="号。其区别在于使用set命令对用户变量进行赋值时,两种方式都可以使用;当使用select语句对用户变量进行赋值时,只能使用":="方式,因为在select语句中,"="号被看作是比较操作符。

3)会话变量

4)全局变量

触发器

与数据表有关,当表出现变化的时候(增、删、改),自动执行其他的特定的操作

触发器的格式

语法:create trigger 触发器名称 触发的时间 触发的动作

on 表名 for each row 触发器状态

触发器状态:随便起名字

触发的时机:before/after 在执行动作之前还是之后

触发的动作:

指的激发触发程序的语句类型:insert,update,delete

触发器创建语法四要素:

1)监视地点(table)

2)监视事件(insert/update/delete)

3)触发时间(after/before)

4)触发事件(insert/update/delete)

查看触发器:show triggers \G

查看触发器创建过程:show create trigger triggername \G

 事务:(只有InnoDB引擎支持)

开启事务:START TRANSACTION

提交当前事务:COMMIT

关闭自动提交:set autocommit=0;

回滚:rollback

MySQL相关的配置文件:

主配置文件:/etc/my.cnf

进程通讯文件:/var/lib/mysql/mysql.sock

日志文件:/var/log/mysqld.log

进程ID文件:/var/run/mysqld/mysqld.pid

二进制文件:在my.cnf中增加

log-bin=mysql-bin.log

慢查询日志文件:在my.cnf中增加

log-slow-queries

存储引擎层:存储和提取数据以及事务处理

 

MyISAM的特性:

1)不支持事务,宕机时会破坏表

2)使用较小的内存和磁盘空间

3)基于表的锁,表级锁(加锁与并发)表级锁定影响性能

4)只缓存index,数据由os缓存

5)不支持外键约束,但是支持全文索引。

MyISAM调优精要:

1、设置合适的索引(缓存机制)

2、调整读写优先级,根据实际需求确保重要操作更优先执行

3、启用延迟插入,改善大批量写入性能

4、尽量顺序操作,让insert数据都写入到尾部,减少阻塞

5、降低并发数,减少对数据库的访问,使用消息队列

6、对于相对静态的数据库数据,充分利用Query Cache或者memcached缓存服务可以极大提高访问速率

7、

InnoDB存储引擎的特性

1)支持事务四个级别ACID

2)支持行锁(行级锁定)

3)聚簇索引

4)支持外键

5)支持崩溃数据自修复

6)具有高效的缓存特性,能缓存索引,也能缓存数据。

默认使用InnoDB引擎配置

default-storage-enigine=innodb

类加载器及其加载过程

 

Hibernate 机制

MYSQL

ORACLE

多线程技术,各种锁机制

1、moniterenter和moniterexit 指令对应于synchronized,更深一步是lock和unlock

2、执行moniterenter指令时,首先要尝试获取对象锁。如果这个对象没被锁定,或者当前已经拥有了那个对象的锁,把锁的计数器加1,相应的,在执行moniterexit指令时会将计数器减1,当计数器为0时,锁就被释放。

3、和synchronized相比,ReentrantLock增加了一些高级功能,主要有等待可中断,可实现公平锁,以及锁可以绑定多个条件。

4、自旋锁:为了让线程等待,只需让线程执行一个忙循环(自旋),但并不放弃处理器的执行时间,这项技术就是自旋锁

自旋锁可以在时间上和自旋次数上进行控制,自适应自旋锁

5、

大数据相关组件及其原理

设计模式

zookeeper原理

数据库和缓存保持数据的一致性

Concurrent包

虚拟机和调优

缓存一致性问题(如何解决数据库和redis缓存的双写操作

一致性Hash算法

内存高占用率分析

java内存模型

1、Java内存模型规定了所有变量都存储在主内存中,每条线程还有自己的工作内存,线程的工作内存中保存了被该线程使用到的变量的主内存副本拷贝,线程对变量的所有操作都必须在工作内存中进行,而不能直接读写准内存中的变量。

2、内存间交互操作

lock、unlock

read、load:两者不能单独出现

use、assign

store、write:两者不能单独出现

3.volatile不保证原子性

特性1:保证此变量对所有线程的可见性

特性2:禁止指令重排序优化

Executor

1.Executor框架的结构

2.ThreadPoolExecutor

ThreadPoolExecutor通常使用工厂类Executors来创建,可以创建的三种类型

SingleThreadExecutor:只有一个线程,适用于需要保证顺序地执行各个任务,并且在任意时间点,不会有多个线程是活动的应用场景

FixedThreadPool:用于需要限制当前线程数量的应用场景,它适用于负载比较重的服务器

CachedThreadPool:是大小无界的线程池,适用于执行很多的短期异步任务的小程序,或者是负载较轻的服务器

 

HashMap和ConcurrentHashMap

在并发编程中使用HashMap可能导致程序死循环,而使用线程安全的HashTable效率又非常低下

在多线程中使用HashMap进行put操作会引起死循环,导致CPU利用率接近100%,因为多线程会导致HashMap的Entry链表形成环形数据结构,一旦形成环形数据结构,Entry的next节点永远不为空。

ConcurrentHashMap的锁分段技术可有效提升并发访问率

chm由Segment数组结构和HashEntry数组结构组成,Segment是一种可重入锁(ReentrantLock)。

Segment的结构和HashMap类似,是一种数组和链表结构,一个Segment里包含一个HashEntry数组,每个HashEntry是一个链表结构的元素。

定位Segment:

在插入和获取元素的时候,必须先通过散列算法定位到Segment,之所以进行再散列,目的是减少散列冲突,使元素能够均匀的分布在不同的Segment上,从而提高容器的存取效率,通过这种再散列能让数字的每一位都参加到散列运算当中,从而减少散列冲突。

get操作:get操作不需要加锁,因为get方法中要使用的共享变量都定义成立volatile类型,因此可以在多线程中保持可见性,可以被多线程同时读

因为根据Java内存模型的先行发生原则,对volatile字段的写入操作先于读操作,即使两个线程同时修改和获取volatile变量,get操作也能拿到最新的值。

put操作:判断是否需要对HashEntry数组进行扩容,第二步定位添加元素的位置

先行发生原则

1)程序次序规则

2)管程锁定规则

3)volatile变量规则:对一个volatile变量的写操作先行发生于后面这个变量的读操作

 

Synchronized

同步代码块使用了 monitorenter 和 monitorexit 指令实现。

同步方法中依靠方法 修饰符上的 ACC_SYNCHRONIZED 实现

锁的四种状态:无锁状态,偏向锁状态,轻量级锁状态,重量级锁状态

轻量级锁能提升程序同步性能的依据是“对于绝大部分的锁,在整个同步周期内都是不存在竞争的”,轻量级锁使用CAS 操作避免了使用互斥量的开销

 monitor是线程私有的数据结构,每一个线程都有一个可用的monitor列表,同时还有一个全局可用的列表

每个线程的当前栈帧中都有一个Lock Record锁记录,用于存储锁对象目前的Mark Word的拷贝

虚拟机将使用CAS操作将Mark Word更新为指向Lock Record的指针,如果成功,则拥有轻量级锁

如果有两条以上的线程争用同一个锁,那轻量级锁就不再有效,要膨胀为重量级锁

轻量级锁:利用了CPU原语Compare-And-Swap(CAS,汇编指令CMPXCHG)

如果说轻量级锁是在无竞争的情况下使用CAS操作去消除同步使用的互斥量,那偏向锁就是在无竞争的情况下把整个同步都消除掉,连CAS操作都不做了

CAS(Compare and swap)原理

思想,三个参数,一个当前内存值V、旧的预期值A、即将更新的值B,当且仅当预期值A和内存值V相同时,将内存值修改为B并返回true,否则什么都不做,并返回false

CAS是通过unsafe类的compareAndSwap方法实现的

Unsafe是CAS的核心类,由于Java方法无法直接访问底层系统,需要通过本地(native)方法来访问,Unsafe相当于一个后门,基于该类可以直接操作特定内存的数据

compareAndSwap:第一个参数是要修改的对象,第二个参数是对象中要修改变量的偏移量,第三个参数是修改之前的值,第四个参数是预想修改后的值

CAS的缺点:ABA问题

如果变量V初次读取的时候是A,并且在准备赋值的时候检查到它仍然是A,那能说明它的值没有被其他线程修改过了吗?

解决办法:java并发包中提供了一个带有标记的原子引用类AtomicStampedReference,它可以通过控制变量值的版本来保证CAS的正确性

LOCK(AQS)

当通过lockInterruptibly()方法获取某个锁时,如果不能获取到,只有进行等待的情况下,是可以响应中断的。

而用synchronized修饰的话,当一个线程处于等待某个锁的状态,是无法被中断的,只有一直等待下去

 

REDIS哨兵的主要作用:集群监控和故障转移

 

SHELL命令

posted on 2018-03-28 00:53  sonofthesea  阅读(295)  评论(0编辑  收藏  举报