0%

List

ArrayList

ArrayList由Object数组构成,用int类型的size属性记录数组中实际对象的数量,实现了随机访问接口RandomAccess。默认容量是10,最大容量为Integer.MAX_VALUE-8。使用int modCount记录结构变更(增减数组长度)次数,使用指针迭代ArrayList时,
指针中的expectedModCount初始为modCount,当在迭代中发现expectedModCount和modCount不相等时,认为结构被其他线程改变了,此时将抛出异常。
每次插入、批量新增和删除元素都会对结构作出改变,并对modCount+1,底层通过使用System.arraycopy实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/*
* @param src the source array.源数组。
* @param srcPos starting position in the source array.要复制的起始位置,包含此位置的元素。
* @param dest the destination array.目标数组。
* @param destPos starting position in the destination data.目标数组放置复制元素的其实位置。
* @param length the number of array elements to be copied.要从源数组复制的元素数量。
* @exception IndexOutOfBoundsException if copying would cause
* access of data outside array bounds.
* @exception ArrayStoreException if an element in the <code>src</code>
* array could not be stored into the <code>dest</code> array
* because of a type mismatch.
* @exception NullPointerException if either <code>src</code> or
* <code>dest</code> is <code>null</code>.
*/
public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length);
Read more »

java内存区域与内存溢出

java的内存区域

常规的认识中,java的内存区域分为堆和栈,这其实是个很泛的划分。

内存区域

  • 堆内存:所有线程共享的区域,存放对象实例。
  • 方法区(永久代、非堆内存):所有线程共享此区域,存放已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码数据。在逻辑上属于堆内存一部分,但为了区别开,通常叫做Non-Heap(非堆)。永久代只是GC分代收集中的概念,并不等同于方法区,在jdk1.8之后,废弃了方法区,引入了元数据区(MetaSpace),此区域为直接内存,可自动扩容,避免了PermGen的溢出错误。
  • 运行时常量池:属于方法区一部分。Class文件中除了类的模板、字段、方法、接口等描述信息外,还有一项信息是常量池信息。常量池用于存放编译期生成的各种字面量和符号的引用。运行期产生的常量也可以放入,典型的比如字符串常量。JDK1.7之后已经从方法区移除。
  • 虚拟机栈:描述了java方法执行的内存模型。存储方法执行都会创建一个栈帧,用于存储局部变量表、操作数栈、动态链表,方法出口等信息,方法的调用到执行完毕对应栈帧的出栈和入栈。
  • 本地方法栈:记录native方法的信息,具体信息根据虚拟机实现而定。
  • 程序计数器:很小的内存空间,记录当前线程所执行的字节码指令地址。
  • 直接内存:使用native函数库直接分配的堆外内存,大小不受java堆大小限制,只会受到物理机内存限制。
Read more »

ubuntu下编译JDK7

心里准备

安装会遇到各种问题,需要静下心来解决,很多问题谷歌上的和自己本身的不一样,但总的来说编译完成的时候还是觉得很高兴的。
各种错的参考地址:http://www.centoscn.com/image-text/install/2015/0908/6140.html
后面才发现的= =,之前折腾好久

环境介绍

操作系统:

1
2
dream@dream:~/jvm/openjdk$ uname -a
Linux dream 4.4.0-28-generic #47-Ubuntu SMP Fri Jun 24 10:09:13 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

ubuntu 64位,16.04LTS

jdk

因为jdk的编译很多也是java编写的,所以也需要一个基础版本的jdk用来编译它,叫bootsrap jdk。

  1. bootstrap jdk:sun的jdk6u45,注意尽量不要使用编译目标的同版本或以后版本,会出一些问题。尽量安装编译目标的readme中的环境来。下载并解压。
  2. 目标版本:openjdk7,下载并解压。
Read more »

数据库事务

在看elasticsearch时看到译者注释数据库事务,感觉不太准确,写这文章,复习下。

数据库事务的特征

数据库事务特征ACID。

A Atomicity 原子性

事务是一个原子性质的操作单元,事务里面的对数据库的操作要么都执行,要么都不执行,

C Consistent 一致性

在事务开始之前和完成之后,数据都必须保持一致状态,必须保证数据库的完整性。也就是说,数据必须符合数据库的规则。

I Isolation 隔离性

数据库允许多个并发事务同事对数据进行操作,隔离性保证各个事务相互独立,事务处理时的中间状态对其它事务是不可见的,以此防止出现数据不一致状态。可通过事务隔离级别设置:包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)

D Durable 持久性

一个事务处理结束后,其对数据库的修改就是永久性的,即使系统故障也不会丢失。

Read more »

git入门

git是一个免费开源的分布式版本控制系统。

安装

gitbash下载,图形化管理工具下载

工作区与版本库,暂存区

工作区

电脑中看到的目录,就是工作区。

版本库

被git管理的目录叫做版本库,此目录下任何文件都被git追踪管理,包括修改,新增,删除,每次修改git都有相应的历史记录,以便可以进行变更追踪以及恢复。

  • 本地仓库:在本机的仓库,记录本机的变更记录。
  • 远程仓库:在远程主机上的仓库,记录所有相关的操作,当远程仓库和本机仓库关联起来以后,才组成一个完整git系统。在本地进行的操作一旦提交,远程仓库就会应用这些操作在远程仓库上。
    Read more »

Zookeeper开源运维管理系统

阿里开源zookeeper运维管理系统TaoKeeper。

Zookeeper的健康指标

物理资源

CPU、内存、磁盘空间、磁盘IO。

应用资源

  • 连接数
  • 注册的watcher数
  • ZNode是否可读,可写(ACL权限)
  • ZK事件通知的延时是否过大
  • zk的节点是否健康(是否离线)
  • 数据状态
  • 请求延时状态
  • 节点的角色
Read more »

Zookeeper运维管理

日志配置

zk的日志使用log4j日志组件。
默认日志输出目录:

  1. winwos为安装目录下,zookeeper.log
  2. linux为安装目录下bin/zookeeper.out

zk默认不开启日志文件输出。
日志相关属性配置在conf/log4j.properties中配置。日志文件输出位置必须在环境设置脚本zkEnv中进行设置:set ZOO_LOG_DIR=/usr/log。或者通过JVM启动参数指定:-Dzookeeper.log.dir=/usr/log

zk其他属性配置

配置方式:

  1. 通过java的JVM系统参数指定(在zkServer脚本中配置,3.4.8版本在140行:nohup “$JAVA” “-Dzookeeper.log.dir=${ZOO_LOG_DIR}” JVM参数可以加在这个地方):-Djava.library.path
  2. 通过zk的配置文件zoo,conf配置。
Read more »

maven入门

为什么要使用maven

Maven是什么

Apache Maven is a software project management and comprehension tool. Based on the concept of a project object model (POM), Maven can manage a project’s build, reporting and documentation from a central piece of information.

maven是一个跨平台的项目管理和构建工具。maven的核心理念是约定大于配置,maven本身已经提供了一套默认设置,这意味着很多东西,使用Maven时都已经默认配置好了,使用者除非必要,不需要去修改那些约定好的内容,比如项目结构,插件等等。

为什么要使用Maven

maven使用一个xml配置文件管理项目的相关依赖信息以及构建信息,项目的所有相关设置都在这个入口进行,降低了项目管理的复杂度:进行项目中依赖jar版本统一管理,使项目与开发环境(本地配置,开发工具)解耦。与传统项目构建方式相比,maven将对lib的强依赖转换为引用依赖,一定程度上的减少了不同项目对依赖jar的重复添加。

1
2
3
4
eg:
project1需要使用jstl.jar,project2也需要使用jstl.jar,以往的方式是在2个项目的lib中都放入jstl.jar文件。
也就是说在计算机里会同时有2个一样的jar包(另外可以使用引入的方式避免重复,但一般都不会这样做,因为协作的时候不应该依赖本地环境)。
如果有N个项目,那简直爆炸了,相同jar包被在本机存在了N个。如果使用maven,那么我们只需在配置文件中配置一下就解决了问题,所有的项目都将使用同一个jar,至于删除,那没关系,maven会自动去仓库下载此jar。
Read more »

分布式锁

JVM和数据库都提供锁,但是JVM的锁只在同一虚拟机中起作用,数据库锁也只能在本数据库起作用或者通过XA与关联数据库一同协作。
在集群和分布式环境中,JVM的锁就无法起作用了,关于分布式数据库锁,目前还是以应用程序控制最多,另外单数据环境下,在比如秒杀这样的情景下,如果使用数据库锁,代价还是比较大。

使用Redis的方案

将数据库库存拷贝到Redis,秒杀时2步走,第一步用户点击按钮时查询Redis库存是否还有,如果有就进入第二步同时Redis库存减去,第二步用户填写验证信息或者确认订单,点击下单或者提交验证信息时查询真实库存,如果还有,可以下单,如果没有,提示抢光。
原理:视觉欺骗,用户是不知道真实的库存数量的,系统所做的只是将符合库存量的用户队列允许进入下单流程中,其他的挡在系统外。
基于这个原理,有很多的实现,比如nginx也可以做到,并且很高效。

蘑菇街秒杀方案

因为商品数量不多,库存数量不用一个字段记录,而是有多少库存量就创建多少行商品记录,这个记录中记录本记录是否被消费,然后用户抢购时是竞争数据库行锁。

1
2
Tips:
这个只是**七公**说的大概,竞争行锁这个还是要依赖数据库机制,所以具体要看mysql数据库引擎类型。
Read more »

zk配置和管理

高并发分布式系统的特征:同一服务需要部署多个。整个大的业务系统由多个子业务系统构成,彼此之间需要相互调用。

产生的问题

  1. 同一服务多台服务器,如何管理服务配置。
  2. 服务的消费者如何动态的发现服务提供者。
  3. 怎么知道部署了多少业务系统以及每个业务系统提供了多少个服务接口。

dubbo

逻辑结构

逻辑图

Read more »