摘要: 一、定义 索引定义:索引(Index)是帮助MySQL高效获取数据的数据结构。本质:索引是数据结构。 二、B-Tree m阶B-Tree满足以下条件: 每个节点至多可以拥有m棵子树。 根节点,只有至少有2个节点(要么极端情况,就是一棵树就一个根节点,单细胞生物,即是根,也是叶,也是树)。 非根非叶的节点至少有的Ceil(m/2)个子树(Ceil表示向上取整,如5阶B树,每个节点至少有3个子树,也... 阅读全文
posted @ 2019-02-03 23:56 robin·张 阅读(406) 评论(0) 推荐(0) 编辑
摘要: 主索引 将主文件分块,每一块对应一个索引项。每个存储快的第一条记录,又称为锚记录。 主索引是按照索引字段值进行排序的一个有序文件,通常建立在有序文件的基于主码的排序字段上。 主索引是稀疏索引。 辅助索引 定义:定义在主文件的任意一个或者多个非排序字段上的辅助存储结构。 辅助索引通常对字段(该字段非排序)的每一个不同值有一个索引项。 字段值不唯一,引入中间桶保存指针列表。 辅助索引是稠密索引。 二... 阅读全文
posted @ 2019-02-03 23:01 robin·张 阅读(2480) 评论(0) 推荐(0) 编辑
摘要: 聚集索引 索引中键值的逻辑顺序决定了表中相应行的物理顺序(索引中的数据物理存放地址和索引的顺序是一致的),可以这么理解:只要是索引是连续的,那么数据在存储介质上的存储位置也是连续的。 聚集索引就像我们根据拼音的顺序查字典一样,可以大大的提高效率。在经常搜索一定范围的值时,通过索引找到第一条数据,根据物理地址连续存储的特点,然后检索相邻的数据,直到到达条件截至项。 InnoDB引擎的数据文件本身就是... 阅读全文
posted @ 2019-02-03 22:26 robin·张 阅读(1242) 评论(0) 推荐(1) 编辑
摘要: 客户端方案 禁掉提交按钮。 表单提交后使用Javascript使提交按钮disable。这种方法防止心急的用户多次点击按钮。但有个问题,如果客户端把Javascript给禁止掉,这种方法就无效了。 使用Post/Redirect/Get模式 在提交后执行页面重定向,这就是所谓的Post-Redirect-Get (PRG)模式。简言之,当用户提交了表单后,你去执行一个客户端的重定向,转到提交成功信... 阅读全文
posted @ 2019-02-02 23:03 robin·张 阅读(930) 评论(0) 推荐(0) 编辑
摘要: 主要是因为i++这个操作不是原子性的,它会编译成 i = i +1; 其实是做了3个步骤,一个是读取,修改,写入 。所以会出现多线程访问冲突问题。 可以结合Java内存模型来进行说明。 阅读全文
posted @ 2019-02-01 23:44 robin·张 阅读(671) 评论(0) 推荐(0) 编辑
摘要: 先看下三次握手四次挥手的状态变化: 通常会遇到下面两种情况: 服务器保持了大量TIME_WAIT状态 服务器保持了大量CLOSE_WAIT状态 因为linux分配给一个用户的文件句柄是有限的,而TIME_WAIT和CLOSE_WAIT两种状态如果一直被保持,那么意味着对应数目的通道就一直被占着,而且 阅读全文
posted @ 2019-02-01 23:39 robin·张 阅读(296) 评论(0) 推荐(0) 编辑
摘要: TCP头部 源端口和目的端口在TCP层确定双方进程,序列号表示的是报文段数据中的第一个字节号,ACK表示确认号,该确认号的发送方期待接收的下一个序列号,即最后被成功接收的数据字节序列号加1,这个字段只有在ACK位被启用的时候才有效。 当新建一个连接时,从客户端发送到服务端的第一个报文段的SYN位被启用,这称为SYN报文段,这时序列号字段包含了在本次连接的这个方向上要使用的第一个序列号,即初始序列... 阅读全文
posted @ 2019-01-31 23:02 robin·张 阅读(308) 评论(0) 推荐(0) 编辑
摘要: get和post的区别可以从三个层面来说:浏览器/服务器层面、HTTP协议层面、语义层面。 浏览器/服务器层面 二者在浏览器层面有着多方面的不同: GET把参数写在URL中,POST通过body来传参。 GET后退按钮/刷新无害,POST数据会被重新提交(浏览器应该告知用户数据会被重新提交)。 GET书签可收藏,POST为书签不可收藏。 GET能被缓存,POST不能缓存 。 GET编码类型app... 阅读全文
posted @ 2019-01-30 23:25 robin·张 阅读(230) 评论(0) 推荐(0) 编辑
摘要: session其实分为服务器端Session和客户端Session。 当用户首次与Web服务器建立连接的时候,服务器会给用户分发一个sessionid作为标识。用户每次提交页面,浏览器都会把这个sessionid包含在 HTTP头中提交给Web服务器,这样Web服务器就能区分当前请求页面的是哪一个客户端。这个sessionid就是保存在客户端的,属于客户端Session。 tomcat生成的ses... 阅读全文
posted @ 2019-01-29 23:41 robin·张 阅读(249) 评论(0) 推荐(0) 编辑
摘要: 二者的区别简单说就是Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。 关于Cookie Cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端会把Cookie保存起来。 当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检... 阅读全文
posted @ 2019-01-29 23:08 robin·张 阅读(305) 评论(0) 推荐(0) 编辑
摘要: 先说结论:servlet不是线程安全的。 servlet运行过程 Servlet程序是由WEB服务器调用,web服务器收到客户端的Servlet访问请求后: ①Web服务器首先检查是否已经装载并创建了该Servlet的实例对象。如果是,则直接执行第④步,否则,执行第②步。 ②装载并创建该Servlet的一个实例对象。 ③调用Servlet实例对象的init()方法。 ④创建一个用于封装HTTP请... 阅读全文
posted @ 2019-01-28 23:17 robin·张 阅读(213) 评论(0) 推荐(0) 编辑
摘要: AQS即队列同步器AbstractQueuedSynchronizer(以下简称同步器),是用来构建锁或者其他同步组件的基础框架。 AQS使用了一个int成员变量表示同步状态。 AQS通过内置的FIFO双向队列来完成获取锁线程的排队工作 同步器包含两个节点类型的应用,一个指向头节点,一个指向尾节点,未获取到锁的线程会创建节点线程安全(compareAndSetTail)的加入队列尾部。同步队列遵... 阅读全文
posted @ 2019-01-27 22:33 robin·张 阅读(198) 评论(0) 推荐(0) 编辑
摘要: 无锁竞争的情况下为了减少锁竞争的资源开销,引入偏向锁。 阅读全文
posted @ 2019-01-27 22:19 robin·张 阅读(144) 评论(0) 推荐(0) 编辑
摘要: 轻量级锁所适应的场景是线程交替执行同步块的情况。 阅读全文
posted @ 2019-01-27 22:13 robin·张 阅读(152) 评论(0) 推荐(0) 编辑
摘要: Synchronized是通过对象内部的一个叫做监视器锁(monitor)来实现的。但是监视器锁本质又是依赖于底层的操作系统的Mutex Lock来实现的。而操作系统实现线程之间的切换这就需要从用户态转换到核心态,这个成本非常高,状态之间的转换需要相对比较长的时间,这就是为什么Synchronized效率低的原因。因此,这种依赖于操作系统Mutex Lock所实现的锁我们称之为“重量级锁”。 JD... 阅读全文
posted @ 2019-01-27 22:10 robin·张 阅读(136) 评论(0) 推荐(0) 编辑
摘要: CAS,在Java并发应用中通常指CompareAndSwap或CompareAndSet,即比较并交换。 CAS是一个原子操作,它比较一个内存位置的值并且只有相等时修改这个内存位置的值为新的值,保证了新的值总是基于最新的信息计算的,如果有其他线程在这期间修改了这个值则CAS失败。CAS返回是否成功或者内存位置原来的值用于判断是否CAS成功。 JVM中的CAS操作是利用了处理器提供的CMPXCHG... 阅读全文
posted @ 2019-01-27 22:06 robin·张 阅读(165) 评论(0) 推荐(0) 编辑
摘要: 如果一系列的连续操作都对同一个对象反复加锁和解锁,甚至加锁操作是出现在循环体中的,那即使没有线程竞争,频繁地进行互斥同步操作也会导致不必要的性能损耗。 如果虚拟机探测到有这样一串零碎的操作都对同一个对象加锁,将会把加锁同步的范围扩展(膨胀)到整个操作序列的外部(由多次加锁编程只加锁一次)。 一种需要锁粗化的极端的情况是: for(int i=0;i<size;i++){ synchroni... 阅读全文
posted @ 2019-01-27 22:04 robin·张 阅读(632) 评论(0) 推荐(0) 编辑
摘要: 锁消除是指虚拟机即时编译器在运行时,对一些代码上要求同步,但是被检测到不可能存在共享数据竞争的锁进行削除。锁削除的主要判定依据来源于逃逸分析的数据支持,如果判断到一段代码中,在堆上的所有数据都不会逃逸出去被其他线程访问到,那就可以把它们当作栈上数据对待,认为它们是线程私有的,同步加锁自然就无须进行。 比如StringBuffer的append方法用了synchronized关键词,它是线程安全的... 阅读全文
posted @ 2019-01-27 22:02 robin·张 阅读(409) 评论(0) 推荐(0) 编辑
摘要: JavaSE1.6为了减少获得锁和释放锁带来的性能消耗,引入了“偏向锁”和“轻量级锁”。 在JavaSE1.6中,锁一共有4种状态,级别从低到高依次是:无锁状态、偏向锁状态、轻量级锁状态和重量级锁状态,这几个状态会随着竞争情况逐渐升级。 锁可以升级但不能降级,意味着偏向锁升级成轻量级锁后不能降级成偏向锁。这种锁升级却不能降级的策略,目的是为了提高获得锁和释放锁的效率。 阅读全文
posted @ 2019-01-27 21:44 robin·张 阅读(119) 评论(0) 推荐(0) 编辑
摘要: synchronized是基于Monitor来实现同步的。 Monitor 的工作机理: 线程进入同步方法中。 为了继续执行临界区代码,线程必须获取 Monitor 锁。如果获取锁成功,将成为该监视者对象的拥有者。任一时刻内,监视者对象只属于一个活动线程(The Owner) 拥有监视者对象的线程可以调用 wait() 进入等待集合(Wait Set),同时释放监视锁,进入等待状态。 其他线程调... 阅读全文
posted @ 2019-01-27 21:42 robin·张 阅读(395) 评论(0) 推荐(0) 编辑
摘要: ThreadLocal ThreadLocal是一个本地线程副本变量工具类。主要用于将私有线程和该线程存放的副本对象做一个映射,各个线程之间的变量互不干扰,在高并发场景下,可以实现无状态的调用,特别适用于各个线程依赖不通的变量值完成操作的场景。 下图为ThreadLocal的内部结构图: 从上图可知ThreadLocal的结构 每个Thread线程内部都有一个Map。 Map里面存储线程本地对... 阅读全文
posted @ 2019-01-26 23:11 robin·张 阅读(205) 评论(0) 推荐(0) 编辑
摘要: Java线程池ThreadPoolExecutor的构造器: public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, ... 阅读全文
posted @ 2019-01-25 23:44 robin·张 阅读(1284) 评论(0) 推荐(0) 编辑
摘要: Java的线程池都是通过ThreadPoolExecutor来构建。 public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, ... 阅读全文
posted @ 2019-01-25 23:24 robin·张 阅读(4266) 评论(0) 推荐(0) 编辑
摘要: volatile关键字有两个特性: volatile变量对所有线程的可见性,指当一条线程修改了这个变量的值,新值对于其他线程来说是可以立即得知的。 volatile变量可以禁止指令重排序优化。 因为JVM要求线程每次使用工作内存中的volatile变量时,都必须从主内存中刷新获取最新的值;执行线程每次修改工作内存中的volatile变量后也必须立刻将之同步回主内存,这样一个线程修改了volati... 阅读全文
posted @ 2019-01-21 23:45 robin·张 阅读(120) 评论(0) 推荐(0) 编辑
摘要: Java内存模型规定了所有的变量都存储在主内存(MainMemory)中;线程的工作内存中保存了被该线程使用到的变量的主内存副本拷贝;线程对变量的所有操作(读取、赋值等)都必须在工作内存中进行,而不能直接读写主内存中的变量。 不同的线程之间也无法直接访问对方工作内存中的变量,线程间变量值的传递均需要通过主内存来完成,线程、主内存、工作内存三者的交互关系如图所示: 这里所讲的主内存、工作内存与通常... 阅读全文
posted @ 2019-01-19 23:50 robin·张 阅读(247) 评论(0) 推荐(0) 编辑
摘要: 线程池的核心参数 corePoolSize:核心池的大小。在创建了线程池后,默认情况下,线程池中并没有任何线程,而是等待有任务到来才创建线程去执行任务,除非调用了prestartAllCoreThreads()或者prestartCoreThread()方法,从这2个方法的名字就可以看出,是预创建线程的意思,即在没有任务到来之前就创建corePoolSize个线程或者一个线程。默认情况下,在创建... 阅读全文
posted @ 2019-01-06 23:03 robin·张 阅读(311) 评论(0) 推荐(0) 编辑
摘要: 执行countdown的某个子线程可能会因为某些原因无法执行countdown,这样就会导致await线程一直阻塞下去。 在线程池中多次调用await方法,因为await方法会阻塞一段时间,有可能导致线程池可用线程被大量阻塞。 阅读全文
posted @ 2019-01-05 23:38 robin·张 阅读(11092) 评论(0) 推荐(0) 编辑
摘要: java sleep()和wait()的区别? sleep()和wait()都能阻塞当前线程。 区别1: sleep()属于Thread类;wait()属于Object类。 区别2: 调用sleep()方法的过程中,线程不会释放对象锁。 调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备获取对象锁进入运行状态... 阅读全文
posted @ 2019-01-05 00:08 robin·张 阅读(916) 评论(0) 推荐(0) 编辑
摘要: 在Java语言中,数据类型分为值类型(基本数据类型)和引用类型,值类型包括int、double、byte、boolean、char等简单数据类型,引用类型包括类、接口、数组等复杂类型。 浅克隆和深克隆的主要区别在于是否支持引用类型的成员变量的复制,下面将对两者进行详细介绍。 浅clone: 在浅克隆中,如果原型对象的成员变量是值类型,将复制一份给克隆对象;如果原型对象的成员变量是引用类型,则将引用... 阅读全文
posted @ 2019-01-03 23:07 robin·张 阅读(406) 评论(0) 推荐(0) 编辑
摘要: Map的key和value是否允许null? 直接写程序验证一下: import java.util.HashMap; import java.util.Hashtable; import java.util.Map; import java.util.TreeMap; import java.util.concurrent.ConcurrentHashMap; /** * @author r... 阅读全文
posted @ 2019-01-02 22:39 robin·张 阅读(27631) 评论(3) 推荐(0) 编辑
摘要: 题目: 有一个很大的文件,这文件中的内容全部都是数字,要求尝试从这个文件中找出最大的10个数字。 分析: 看起来像是一个比较简单的问题。不用大数据框架的话,也能比较轻易的实现:就是逐个读取文件中的每个数字,放到一个大顶堆结构中;将大顶堆放满以后,每读取一个数字就将之和大顶堆中的最小值进行比较,如果其大于这个最小值的话,就将其放入堆中,并将堆中的最小值删除;这样读取到最后,堆中剩下来的内容就是to... 阅读全文
posted @ 2017-09-27 22:02 robin·张 阅读(596) 评论(0) 推荐(0) 编辑
摘要: 题目 有两个文件A和B,两个文件中都有几百万行数字,现在需要找出A文件和B文件中数字集合的交集、并集、以及A对B的差集。 简单说一下思路: 这个问题关键在于key和value的设计。这里我将文件中的数字设置为key,将文件名称设置为value。这样在reduce阶段很容易就能找出A、B两个文件中数字的交并差集了。 并集就是reduce阶段能输出的全部记录;交集则需要做下过滤,即一个记录中的val... 阅读全文
posted @ 2017-09-21 22:18 robin·张 阅读(1334) 评论(1) 推荐(0) 编辑
摘要: 题目: 需要将MR的执行结果保存到3个文件中,该怎么做。 又是一个送分题。 对于Hadoop的MapReduce来说只需要设置一下reduce任务的数量即可。MR的Job默认reduce数量是1,需要调用job的setNumReduceTasks()方法来调整reduce任务的数量。 对于spark来说,可以调用coalesce方法或repartition方法来调整分区的数量,这样也可以调整最终... 阅读全文
posted @ 2017-09-19 22:09 robin·张 阅读(234) 评论(0) 推荐(0) 编辑
摘要: 题目: 一个文件,大小约为100G。文件的每一行都是一个数字,要求对文件中的所有数字进行排序。 对于这个题目,了解过Hadoop的同学可以笑而不语了。即使用spark实现也是非常简单的事情。 先说下如何用Hadoop实现。实际上也没什么好说的:Map任务逐行读入数字,而后在Reduce中输出就可以了,简单粗暴到令人发指。 看下代码好了: package com.zhyea.dev; impor... 阅读全文
posted @ 2017-09-18 07:07 robin·张 阅读(521) 评论(0) 推荐(0) 编辑
摘要: 从今天我们开始学习HBase。希望大家能够通过这个课程对HBase有一个初步的认识,并且能够使用HBase提供的命令行以及Java API完成一些通用的操作。 今天的内容是一些入门性的知识:包括HBase的简单介绍、HBase的逻辑模型以及HBase的物理模型。 HBase简介 HBase是Google BigTable的开源实现。在05年前后,谷歌发布了三篇非常重要的论文,受这三篇论文的启发才有... 阅读全文
posted @ 2017-05-04 07:15 robin·张 阅读(599) 评论(0) 推荐(0) 编辑
摘要: 这次看一些关于JVM内存分析的内容。 两个程序 程序一 首先来看两个程序,这里是程序一:JVMStackTest,看下代码: package com.zhyea.robin.jvm; public class JVMStackTest { private static int count = 0; private void recur() { ++co... 阅读全文
posted @ 2017-04-30 08:08 robin·张 阅读(408) 评论(0) 推荐(0) 编辑
摘要: 前面两节我们已经多次接触过case关键字了。case关键字不仅可以用在match/case中来执行模式匹配,也可以用来修饰类。不过用case修饰的类也主要是用来做模式匹配。在上一节曾经提到过match可以是Any类型的所有类,为什么还需要使用case关键字来修饰呢?假定有这样一个场景:我们要接收和处理股票交易信息,买卖消息通常会带有一些信息,诸如股票名称、数量。把这些信息存到对象里会很方便,但是如... 阅读全文
posted @ 2016-09-20 22:05 robin·张 阅读(1616) 评论(0) 推荐(0) 编辑
摘要: 再来看一下之前的一段代码: def process(input: Any) { input match { case (a: Int, b: Int) => println("Processing (int, int)... ") case (a: Double, b: Double) => println("Processing (double, double)... ") ca... 阅读全文
posted @ 2016-09-18 22:41 robin·张 阅读(985) 评论(0) 推荐(0) 编辑
摘要: 在java中有switch/case这样的模式匹配语句,可以匹配的类型包括int,byte,char,short, enum,在java8又支持了字符串。 在scala中也有类似的模式匹配语句,即match-case。这个好现在之前使用过一次。scala中的match-case匹配的类型更为广泛,它是对Any类型起作用的。 来看个例子: def activity(day: String) { ... 阅读全文
posted @ 2016-09-18 21:53 robin·张 阅读(488) 评论(0) 推荐(0) 编辑
摘要: 方法命名约定 之前在学习《运算符重载》一节时曾经说过一个方法命名约定:方法的第一个字符决定了方法的优先级。现在再说另一个命名约定:如果方法以冒号(:)结尾,则调用目标是运算符后面的实例。 比如下面这个例子: class Cow { def ^(moon: Moon) = println("Cow jumped over the moon") } class Moon { def ^:(c... 阅读全文
posted @ 2016-09-15 22:52 robin·张 阅读(550) 评论(0) 推荐(0) 编辑