- 博客(49)
- 收藏
- 关注
原创 Self-assessment Checklists of HSK
Dear friends, I’m a postgraduate student of Renmin University of China, majoring in Teaching Chinese as a Second language, I’m doing a research about learner’s Chinese level, and need your help, pleas...
2018-12-08 14:42:21
488
原创 从慢查询实例中分析mysql索引及查询优化(一)
写这个博客也算是阴差阳错。上次做了个需求:退款列表导出(可以翻翻之前的博客,有写)。虽然事情过了那么久,现在我还是想要吐槽下,这个需求是真的坑。。这个博客大概是这么分布的:第一篇就根据实际场景来分析下索引及查询上的优化;第二篇和第三篇(如果我还能写得出来第三篇的话。。)来系统地整理下mysql的索引及查询的优化。———————————————— 接下来是正文 ———————————————...
2018-08-04 23:30:49
988
原创 开发概述——退款记录导出至excel
最近做了一个(奇坑的)需求,用户退款信息导出至excel。听起来似乎是一个简单的小功能,但是做起来却发现有数不清的大坑- -,整个项目我大约花了2-3周时间去开发(当然中间穿插着一些其他的需求),并后续仍在优化或解决bug。不过现在已经完成,大部份的坑也已经被填满了。首先来说下整体的开发流程图:对于这个需求,首先我们需要明确一点:必须要异步来做,导出任务很耗时间(当记录较多时,时间会比较长),如果...
2018-07-08 11:21:16
867
原创 Java用POI读取excel文件,报异常:NotOLE2FileException: Invalid header signature; read xxx, expected 0xE11AB1A1
这几天在开发时遇到了极其坑爹的问题。开发的主要功能是在导出某些订单数据至Excel,因为自己一个一个去写表头这种操作代码耦合性实在太强,到时想要修改表头格式又需要回到去代码中修改,所以这是一种很愚蠢的零分操作!那么在这里就用到了POI的Excel模版功能(POI是apache提供给java对office进行读写操作的库,也是前些天开发时才了解到)。模版作为一种资源文件就被我存放在聚合工程的某一mo...
2018-06-18 20:59:45
29444
12
原创 Java中@Param注解
@Param:用来在DAO层中声明参数,如:List<News> selectByUserIdAndOffset(@Param("userId") int userId, @Param("offset") int offset, @Param("limit") int limit);当使用了使用@Param注解来声明参数时,如果使用 #{} 或 ${} 的方式都可以。 @Selec...
2018-04-18 16:26:51
26645
原创 Redis源码(十三)——集群
这是Redis源码系列最后一篇博客咯~之前因为出去玩所以隔了很久才更新~ 在前面的博客中提到我们可以选择哨兵Sentinel+主从复制的功能来实现高可用的Redis数据库方案,从而完成复制和故障转移的需求。事实上通过Redis集群(cluster)也能起到相同的作用。集群通过分片(sharding)来进行数据共享,并提供复制和故障转移的功能。那接下来就来介绍下Redis集群的相关功能及实现。
2018-02-09 13:36:00
399
原创 Redis源码(十二)——哨兵Sentinel
如果当系统中只有一台Redis服务器运行时,假设服务器宕机了,那么所有的服务都将不可用,这对系统来说是不可忍受的。那么备份就是一个很自然的想法了。前面的博客中我们讲到了Redis的主从复制,应用Redis主从复制的功能,我们对主服务器配置几台从服务器从而对主服务器进行备份,主从服务器内的数据保持一致。但是仅仅做了主从是不够的——当主服务器挂了以后,从服务器只能提供读服务,而无法提供写服务,系统仍然
2018-01-24 11:21:13
856
原创 Redis源码(十一)——Redis的主从复制
Redis中可以发送SLAVEOF命令让一个服务器A成为另一个服务器B的“slave”,从而去复制B,称A为从服务器(slave),B为主服务器(master) 关于复制,2.8版本以前及以后实现有一些不同,2.8版本以前的复制在断线重连后效率较低,所以我们在这里只分析下2.8版本以后的复制。复制功能分为同步(sync)和命令传播(command propagate)两个步骤。
2018-01-23 11:06:35
696
原创 Redis源码(十)——Redis的客户端和服务器
在前面的博客中,有些内容已经涉及到了Redis服务器或者客户端的一些属性,如上一篇博客关于Redis的RDB持久化中关于save选项来设置服务器的状态等。那么接下来这篇博客中就分析下Redis的客户端以及服务器的属性及操作。 一、Redis客户端redis.h中的redisClient结构定义了Redis的客户端:/* With multiplexing we need to ta
2018-01-22 10:34:24
1925
原创 Redis源码(九)——Redis的持久化:RDB及AOF
我们知道Redis的数据库数据是储存在内存中的,那么如果Redis服务器进程被kill了或关闭了,那么服务器中的所有数据都会消失,所以我们需要对Redis的数据进行持久化即保存在硬盘中。 Redis有两种持久化的方案——RDB和AOF(Append OnlyFile)。 一、RDB持久化RDB持久化通过将数据库中的键值对保存到rdb文件中来对Redis进行备份。src下的
2018-01-21 14:36:35
505
原创 Redis源码(八)——Redis的数据库
在前面的博客中,对Redis的底层数据结构和Redis中的几种对象做了相对详尽的分析,但是对于Redis——作为一种高速分布式数据库,我们并没有对Redis的一些典型功能例如存取键、设置过期时间、主从复制等作出介绍。接下来我们将对Redis的一些功能作出详细的分析。作为一种数据库,Redis的数据库功能是最基本也是最核心的功能,接下来就对此进行介绍。 一、数据库的结构定义 在
2018-01-17 20:55:07
661
原创 Redis源码(七)——Redis中五种对象
在前面的博客中,介绍了Redis中用所有底层数据结构,如简单动态字符串(SDS)、链表、字典、跳跃表,整数集合和压缩链表。Redis就利用上述的六种底层数据结构来构造了五种数据库对象——字符串、列表、哈希、集合和有序集合。 我们知道Redis是一个“key-value”数据库,其中的key和value都是用对象表示。Redis中每个对象都是由RedisObject结构体表示:t
2018-01-15 21:12:01
428
原创 Redis源码(六)——压缩列表
一、压缩列表(ziplist)的定义与实现 压缩列表是一种为了节约内存而开发的顺序数据结构,是列表及哈希对象的底层实现之一。当列表中只有少量的列表元素,且列表元素是小整数值或者较短的字符串,Redis就会用压缩列表作为列表对象的底层实现;当哈希对象中只包含少量键值对,而且键值都是小整数或者长度较短的字符串,Redis就用压缩列表作为哈希的实现。src中的ziplist.c和z
2018-01-11 20:24:34
404
原创 Redis源码(五)——整数集合
一、整数集合(intset)的定义与实现 整数集合是Redis中集合的底层实现之一,当集合只包含整数且集合的元素数目不大是,Redis是使用整数集合作为集合的底层实现的。整数集合的实现在src的intset.h和intset.c中:typedef struct intset { // 编码方式 uint32_t encoding; //
2018-01-10 22:26:45
320
原创 Redis源码(四)——跳跃表
跳跃表(skiplist)的定义与实现 在对排行榜数据进行排序时,我们会用到Redis中的有序集合对象(sorted set),跳跃表就是有序集合的底层实现之一。跳跃表是一种有序的数据结构,每个节点中都维持着多个指向其他节点的指针,所以可以快速地访问节点。跳跃表的查找速度平均为O(logN),最差为O(N)。 src下的redis.h中用zskiplistNode和zs
2018-01-09 21:11:27
300
原创 Redis源码(三)——字典
一、字典(dictionary)的定义与实现 在使用Redis中,我们会经常用到哈希(hash)对象。哈希对象中存在key、field和value,每一个field都对应一个value。我曾经使用哈希对象来缓存不同平台上的书籍数据——平台id为key,书的id为field,需要的数据为value。哈希对象的底层就是通过字典来实现的。 src下的dict.h和dict.c
2018-01-04 21:12:14
311
原创 Redis源码(二)——链表
Redis中的链表是一个应用十分广泛的底层数据结构,常用的Redis列表(List)底层实现之一就是链表。我曾用Redis的列表缓存过分布式服务节点的ip。Redis列表的一些操作命令在这里就不做赘述了,有兴趣的同学不妨装个Redis自己动手实践下。 言归正传,继续来讲Redis的底层数据结构——链表。熟悉数据结构的同学一定对链表不会陌生。在src下的adlist.h和adlist.
2018-01-04 19:22:12
283
原创 Redis源码(一)——简单动态字符串
一、什么是简单动态字符串 字符串是Redis中最简单的一个数据结构,打开Redis的源码后可以发现,Redis的底层是通过C语言来实现的,然而Redis并没有使用C语言中的字符串类型,而是重构了一种新的字符串类型——简单动态字符串(simple dynamic string,SDS)。那么Redis为什么要自己去开发一种抽象字符串类型呢?在我提供的代码中,src下的sds
2018-01-03 20:17:53
477
原创 Redis源码——开篇
接下来的博客主攻Redis的源码,我们知道Redis是现在很流行的一个缓存数据库,大多的公司都会选择使用Redis作为数据库的缓存。在找实习以及找工作中的面试中,很多面试官也会对Redis技术很感兴趣。对于一项技术,比会去使用它更重要也是更高层的是理解内部的源码实现,剖析作者这么设计的原理及思维。所以很多面试官会很喜欢问候选人关于Redis内部的技术实现。作为一个小菜鸟,在面试时我也被问了不少Re
2018-01-02 19:07:40
428
1
原创 2017这一年
终于赶在2017年末看完了两本书——《分布式服务架构》和《设计模式》。前者碍于相关经验的缺失,只能说走马观花般看个大概;后者的23种设计模式已经在我的博客中写成了相关的技术博客——尽管把学习的过程写成了博客,但对于23种设计模式我也不能说是融会贯通,仍然需要在实际应用中再次深化,在此也很希望能有看过我博客的朋友给出一些指导性的意见。 写博客是暑假实习时候萌生的想法,作为一只在实习前只
2017-12-31 19:49:00
301
1
原创 设计模式——访问者模式
一、什么是访问者模式? 在每个自定义对象中定义一个accept(请求访问)方法,这个方法以对象为参数,调用访问者的对象的visit方法来操作此对象。访问者模式对于开闭原则没有很好的支持,它允许修改节点中的方法,因此访问者模式应该应用在访问类结构比较稳定的时候。 访问者模式涉及到以下几个角色: 1. 抽象访问者:定义访问接口 2. 具体访问者:实现
2017-12-30 11:54:18
243
原创 设计模式——迭代器模式
一、什么是迭代器模式? 我们在Java中经常会遇到集合对象,这些集合对象内部有着各种各样的实现。如果我们去遍历集合中的数据,那么就需要各种各样的实现。迭代器模式就可以解决这种场景,它分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样就可以既不暴露集合内部的结构,又可以让外部程序访问集合内的数据。就像Collection集合类中有List和Set,要去访问他们内部的数据,我们只需要
2017-12-29 11:14:47
200
原创 设计模式——解释器模式
一、什么是解释器模式? 解释器模式定义语言的语法,并建立解释器来解释语法中的句子。如正则表达式等的解释器。 解释器模式涉及到以下几个角色: 1. 抽象表达式角色:定义了具体的表达式需要实现的抽象解释方法或接口 2. 具体表达式角色:指定了具体的表达式的解释 3. 环境(Context)角色: 包含了解释器之外的一些全局信息 4. 客
2017-12-28 11:21:03
249
原创 设计模式——命令模式
一、什么是命令模式? 命令模式将一个请求封装成一个对象,从而可以对不同的请求作出不同的回应。比如在公司,老板发出一条命令给小组leader,leader又派发给手下的组员。这个过程使老板、命令、leader和执行命令的组员几者解耦,任何一方都不用去依赖其他人,只需要做好自己分内的事情,老板只需要结果,他并不需要知道到底哪个员工完成了命令,员工也不需要知道这个命令是谁发布的,只需要按照
2017-12-27 11:10:49
222
原创 设计模式——策略模式
一、什么是策略模式? 策略模式就是定义一系列的算法,并将它们封装,使他们可以相互替换。策略模式使得算法以独立于客户而变化。 策略模式涉及到以下几个角色: 1. 抽象策略角色:定义了具体策略需要实现的抽象方法或接口 2. 具体策略角色:封装具体的算法 3. 环境角色:内部持有策略类对象的引用 举一个简单易懂的例子——计算器,计算
2017-12-26 11:03:04
251
原创 设计模式——状态模式
一、什么是状态模式? 状态模式允许一个对象在其内部状态改变时改变它的行为,可以让对象根据不同的外部情况做出不同的响应。比如在访问论坛网站的时候,我们希望根据用户的性质来区分他们的一些权限,比如游客不能回帖,普通用户不能删帖,而管理员可以有很多特殊权限如置顶,加精等。 简单的来说,状态模式有以下两个角色: 1. 状态(State)角色:封装着不同语境(Con
2017-12-25 10:50:22
285
原创 设计模式——模板方法模式
一、什么是模板方法模式? 我们经常会遇到一个问题:我们明确了某个方法的执行步骤及其顺序,但是某几个步骤的具体实现我们暂时未知,需要按照具体的情况具体处理。模板方法就是定义了某个方法的执行步骤及顺序,而将某些与具体实现的步骤延迟到子类中去执行。模板方法模式把那些不知道具体实现的步骤封装成抽象的方法,子类通过继承去实现各个抽象。 举个形象的例子,如果我们要画画,那么首先我们规定了画画
2017-12-24 11:22:30
363
原创 设计模式——备忘录模式
一、什么是备忘录模式? 备忘录(Memento)模式又叫做标记(Token)模式。备忘录中存放着对象的历史状态,当对象状态改变后,想要恢复先前的状态时,就可以使用备忘录来恢复。 备忘录模式中存在以下角色: 1. 发起者(Originator)角色:创建一个备忘录,内部记录其此时的状态,需要时可以使用备忘录来恢复状态 2. 备忘录(Memento
2017-12-23 11:46:44
376
原创 设计模式——原型模式
一、什么是原型模式? 原型模式是一种创建型的设计模式,是通过已存在的对象实例克隆出一个对象,而不是通过调用构造方法创建的,克隆对象与源对象具有相同的属性。 Java中通过clone()方法来实现对对象的克隆,所以原型模式应用很简单。 根据表现形式原型模式可以分为两种:(1)简单形式 (2)登记形式 二、原型模式框图
2017-12-22 11:30:39
262
原创 设计模式——抽象工厂模式及与工厂模式的区别
一、什么是抽象工厂模式? 抽象工厂模式提供一个创建一系列相关或相互依赖的对象的接口,而无需指定它们具体的类。这样的描述我们会觉得和工厂模式比较像,那么工厂模式和抽象工厂模式的区别是什么呢?这两种设计模式主要的区别在于产品,工厂模式是用来创建同一个产品的不同类型的(详情请看上一篇博客中卖包子的案例,大肉包和牛肉包它们都是包子的不同类型展示),但是抽象工厂模式是用来创建不同类的产品
2017-12-21 11:08:25
15052
11
原创 梦谈——狗爷
今天晚上,我本来早早地回寝室了。大约凌晨2 3点的时候A君与B君[注1]问我要不要一起出去吃夜宵,虽然外面看起来很冷,我还是毫不犹豫地答应了。约好地点,我与他俩说我要换个衣服会晚点过去。换完衣服,寝室楼外已经晨曦微露,我坐上我的电动扭扭车[注2]握好方向盘,像是开了一辆马萨拉蒂,以5km的时速开向目的地。到了夜宵店,A和B已经点了三笼小笼包就着豆浆吃了起来,那装小笼包的屉子和脸盆一般大,里边层层叠
2017-12-19 12:00:52
475
原创 设计模式——工厂模式
一、什么是工厂模式? 工厂模式就是创建一个对象的工厂接口,创建对象不再是通过new这个对象来直接实现,而是通过工厂来对对象进行创建。应用工厂模式可以降低系统间的耦合度。工厂模式中一般有以下角色:1. 抽象产品类:是具体产品对象的基类2. 具体产品类:实现了抽象产品类接口,每一个具体产品类都会对应一个工厂3. 抽象工厂:工厂模式的基类,定义了工
2017-12-19 11:05:58
538
2
原创 设计模式——建造者模式
一、什么是建造者模式? 当一个对象的创建包含该对象的部件部分及部件的装配过程时,建造者模式可以将对象的部件生成过程及装配过程进行分离解耦,从而使系统结构变得更加清晰。举个栗子:我们知道电脑是由CPU,硬盘和内存组成的,那么如果我们要创建一个电脑,首先的思路就是我们去制造CPU、硬盘和内存,然后进行组装,这样就生成了一台电脑。仔细一想,这个模式存在很多问题,它将部件的生成和组装放在了一起,那
2017-12-15 11:25:58
341
原创 设计模式——享元模式
一、什么是享元模式? 享元模式的主要目的是实现对象的共享,当系统中有多个相同的对象,那么不需要实例化多个对象,只需要共享一个对象即可,这和对象池的概念类似,通常与工厂模式一起使用。比如有一家店做外卖,如果每以个订的食物都作为一个对象,那么几千单就有几千个食物对象,这是一种耗费内存的操作。事实上,一家店的菜单上食物一共也就几十种,这几千个订单完全可以共享相同的食物对象,这就是享元模式的一个应
2017-12-14 10:16:16
256
原创 设计模式——中介模式
一、什么是中介模式?中介即Mediator,用中介对象来讲交互的几个对象进行封装,对象间不再直接进行通讯,而是通过中介间接沟通,降低了对象之间的耦合程度。当对象之间进行复杂的交互,对象之间的依赖混乱,这个时候就可以使用中介模式。二、中介模式框图使用中介模式的一个典型的场景是相亲。以前的相亲涉及到了男女两方及互相的父母,如果男方想向女方提出约会的请求,这个时候男方
2017-12-13 10:00:23
237
原创 设计模式——单例模式的几种写法
一、单例模式单例模式是一种创建型的模式,指某个类采用单例模式后,在这个类被创建后,只产生一个实例以供外部访问,且提供一个全局的访问点。单例模式在开发中具有相当大的重要性,并且代码实现相对简洁。所以其是为数不多的在面试中会被问到且要求手撸代码的设计模式哦:)。 二、几种单例的写法及比较1. 饱汉模式package designpatterns.sing
2017-12-08 13:53:16
282
原创 设计模式——责任链模式
一、什么是责任链模式?责任链模式中,存在多个对象,每个对象持有对下一个对象的引用而形成一条链,请求在这条链上传递,直到其中某一对象决定处理该请求。然而请求发出者并不清楚最终哪一个对象会处理该请求,所以,责任链模式可以在不影响客户端的情况下,对系统进行动态的调整和重新组织。责任链虽然叫做链,但是事实上它的结构可能是一个单向的链表,也可能是一个单向环形链表,也有可能是一个树状结
2017-12-06 10:21:19
213
原创 设计模式——桥接模式
一、什么是桥接模式?《大话设计模式》中有一个场景:当我们要进行绘画时,有两种选择:蜡笔和水彩。蜡笔是将笔和颜料混合在一起成为了一个整体,那么如果我们需要大号、中号、小号各12种颜色的蜡笔,总共36支,这无疑是一笔很大的花费,那么如果使用水彩呢?水彩用的是毛笔,我们只需要大中小三支毛笔,以及12种需要的颜料就可以完成这项任务,这样总共只需要15种物品,大大减少了需要的物品数目。这就是典型的桥接模
2017-12-04 10:26:56
375
1
原创 设计模式——组合模式
一、什么是组合模式?让我们想象一个场景,原本我们在网上买东西是一件一件支付的,享受的折扣也只有店家提供的满减红包,但是在双十一的时候,退出了“跨店满减”活动,这个时候我们需要把要购买的商品打包一起支付以享受更加优惠的折扣。这就是典型的组合模式的一个运用。组合模式将对象组成树形结构,使得用户对于单个对象和组合对象的使用一致。组合模式有时又叫“部分-整体模式”,消除了单个对象与组合对象在使
2017-12-02 18:46:57
403
原创 设计模式——外观模式
一、定义:如果有一个系统,内部分为三个子系统:S1,S2,S3,当用户A调用了子系统S1,S2的接口,用户B也调用了子系统S1,S2的接口。那么当子系统S1,S2发生变化时,它们将会影响到所有调用了子系统的客户,子系统与用户的直接交互无疑使他们之间高度耦合,这个时候用外观模式就是很合适的。外观模式将子系统的接口集成在一个高层接口中,使用者可以直接调用高层的接口而忽略其内部子系统的变化,
2017-12-01 11:43:15
186
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人