6/24 设计模式之享元模式 Flyweight Pattern

类别:结构型设计模式

目的:减少潜在的对象创建次数、尽可能延迟创建/重用对象,降低内存占用,并对代码实现结构进行限定

完整代码参考:https://1drv.ms/u/s!AquRvPzqx59Ri3URckgGBGw8WoWh?e=I6BRDg

典型场景

有许多不同种类的对象需要被使用,需要延迟对象的创建、同类对象会创建多次

比如一张地图中包含很多点,每个点会有一个图标表示这个地点的类型,比如餐厅、体育馆、办公楼、图书馆等。把这些点显示在地图上,程序需要先在内存中保存这些点

基本事实:

  1. 一张地图上可能会有成千上万的点需要绘制
  2. 每个地图点在地图上一般会以图片进行显示
  3. 一个图片文件内容占用的内容空间远超普通对象
  4. 为了避免地图加载过程中占用过多内存,有必要优化地图点上的内存空间占用
Read more   2020/3/11 posted in  设计模式 JAVA

5/24 设计模式之组合模式 Composite Pattern

类别:结构型设计模式

目的:表示一组对象,这组对象的用法和单个对象的用法一致

完整代码参考:https://1drv.ms/u/s!AquRvPzqx59Ri3TfmAb69-DF82jQ?e=DR2vwn

典型场景

处理电脑上的文件和文件夹

基本事实

  1. 文件和文件夹可以有多个
  2. 文件和文件夹有多个共同的操作,比如:删除、移动、复制等

这里拿对多个文件夹和文件执行删除操作举例,对应mac下右键Move to Trash按钮

可以看到,可以选中多个文件和文件夹执行删除、复制、移动、获取属性信息等操作

Read more   2020/3/9 posted in  设计模式 JAVA

4/24 设计模式之命令设计模式 Command Pattern

类别:行为型设计模式

目的:解耦行为的接收方和行为的实际处理逻辑

完整代码参考:https://1drv.ms/u/s!AquRvPzqx59Ri3MMlUz2cbydE0Eu?e=X6DGEG

典型场景

gui窗口界面上的一个按钮对象,点击后执行一断逻辑处理代码

硬编码

构造一个按钮类,并在点击(click)时执行业务逻辑代码,参考代码如下:

public class Button {
    private String label;

    public void click() {
        // doBusinessLogic(); 逻辑处理代码
    }

    public String getLabel() {
        return label;
    }

    public void setLabel(String label) {
        this.label = label;
    }
}

核心问题

按钮和按钮点后的业务逻辑代码耦合在一起

  1. button的复用变得困难
  2. 逻辑代码的复用变得困难
Read more   2020/3/6 posted in  设计模式 JAVA

3/24 设计模式之责任链设计模式 Chain Of Responsibility Pattern

类别:行为型设计模式

目的:将为了达成共同目标的一系列具有逻辑顺序的操作进行解耦

完整代码参考:https://1drv.ms/u/s!AquRvPzqx59Ri3IZYwf83oLFp6Pu?e=i6yxH7

典型场景

为一个web请求定义的一些列操作,比如

  1. 用户登陆验证
  2. 处理业务逻辑
  3. 压缩响应数据

注意以上3个操作是顺序的,需要登陆成功后再执行业务逻辑,业务逻辑生成响应数据后,才需要压缩响应数据

构造一个简单的http请求对象备用,参考:

public class HttpRequest {
    private String username;
    private String password;

    public HttpRequest(String username, String password) {
        this.username = username;
        this.password = password;
    }

    public String getUsername() {
        return username;
    }

    public String getPassword() {
        return password;
    }
}
Read more   2020/3/1 posted in  设计模式 JAVA

2/24 设计模式之访问者设计模式 Visitor Pattern

类别:行为型设计模式

目的:不改变类的定义的约束下,为类的对象应用/添加新的行为

典型场景

现存一系列对象,比如由很多html标签对象组成了一个html页面,这里拿几个html标签举例

标签 当前状态 目标状态
a <a href=“#”>link</a> 添加class=“underlinea"
p <p>this is a paragraph</p> 添加style=“font: bold"
h1 <h1>new title</h1> 添加id=“h1-highlight"

当前代码状态如下,注意需要修改的部分

Read more   2020/2/27 posted in  设计模式 JAVA

论坛系统架构设计和商业模型分析

参与了论坛系统的开发,总结一下

技术栈

  1. 使用git进行代码版本控制
  2. 使用jumpserver管理服务器资产权限
  3. 使用kafka做消息队列系统
  4. 使用elasticsearch存放大批量关联数据
  5. 使用内部研发的代码部署审核系统
  6. 使用yii1框架(历史遗留系统了)
  7. 使用qconf做分布式配置中心
  8. 使用logrotate做日志轮转
  9. 使用sphinx做文本分词和搜索
  10. 使用confluence做文档管理
  11. 使用禅道做项目bug管理

内容主表设计

内容系统内容表主体主要是存放内容公有的字段,比如帖子标题、帖子类型、浏览数等

一些特殊的字段,比如帖子内容字段因为占用空间比较大(通常是text数据类型),并不适合放在内容主体表中(影响查询速度),可以单独创建一张表来进行存储

CREATE TABLE `tb_subject` (
  `subject_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `title` varchar(255) NOT NULL DEFAULT '',
  `subject_type` text NOT NULL DEFAULT 0,
  `uid` bigint(20) unsigned NOT NULL DEFAULT 0,
  `view_cnt` int(11) NOT NULL DEFAULT 0,
  `display_yn` tinyint(1) NOT NULL DEFAULT 1,
  `create_date` datetime NOT NULL DEFAULT current_timestamp() COMMENT '创建时间',
  `update_date` datetime NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp() COMMENT '更新时间',
  PRIMARY KEY (`subject_id`),
  KEY `idx_uid` (`uid`,`create_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='贴子主体表';
Read more   2020/2/27

1/24 设计模式之策略设计模式 Strategy Pattern

类别:行为型设计模式

目的:把同类的代码进行单独封装、使得需要使用这部分代码的用户可以按需使用

典型场景

对用户上传的图片应用不同的压缩算法和滤镜

压缩算法:

  1. jpeg格式
  2. png格式

滤镜:

  1. blackAndWhite滤镜
  2. backgroundBlur滤镜

硬编码

public class HardCode {
    public static void main(String[] args) {
        var fileName = "test.jpg";
        var compressor = "jpeg";
        var filter = "blackAndWhite";

        handleUpload(fileName, compressor, filter);
    }

    public static void handleUpload(String fileName, String compressor, String filter)
    {
        if (compressor.equals("jpeg")) {
            System.out.println("应用jpeg压缩算法...");
        } else if (compressor.equals("png")) {
            System.out.println("应用png压缩算法...");
        }

        if (filter.equals("blackAndWhite")) {
            System.out.println("应用blackAndWhite滤镜");
        } else if (filter.equals("backgroundBlur")) {
            System.out.println("应用blackAndBlur滤镜");
        }
    }
}

模式实现

Read more   2020/2/26 posted in  设计模式 JAVA

三分钟上手arch linux操作系统&openbox图形界面初始化

arch linux是高度可定制的极简版操作系统,加上号称最快的linux图形系统openbox,搭配起来是工作和生活得力的工具

获取arch linux

地址列表:https://www.archlinux.org/download/

可以使用163的镜像直接下载,参考:https://mirrors.163.com/archlinux/iso/2020.01.01/archlinux-2020.01.01-x86_64.iso

获取可用的计算机

可以使用真机(笔记本或者台式机),这里使用vmware fusion创建一个2c4g的虚拟机。

规划磁盘空间: 15.5G

空间大小 作用 类型
13GB 系统盘 ext4
2GB 交换空间 swap
0.5GB uefi引导文件 fat32

同步时间

系统时间不对可能造成ssl连接失败导致后续安装出错

timedatectl set-ntp true
timedatectl status
Read more   2020/1/13 posted in  LINUX

三分钟搭建大数据sql开发平台

Read more   2019/12/31 posted in  JAVA 三分钟系列 商业智能 SQL

使用go解析二进制tcp数据包

tcp全名是传输控制协议,tcp协议在ip协议基础上增加了数据包完整性检查等保证传输完整性的机制,使其在现在的数据领域得到了广泛的应用

按照下面的步骤可以快速了解tcp数据包中包含的信息

tcp协议rfc文档解读

rfc参考:https://tools.ietf.org/html/rfc793

核心tcp数据包结构如下

可以看到tcp报文由十余个字段组成,最后一个data字段代表了本次tcp数据报文承载的数据,这个数据一般是应用层的数据,比如http报文数据就是在这个tcp包的data字段中

其中常用字段如下

字段 作用
Source Port 发包机器的端口号
Destination Port 收包机器的端口号
Sequence Number 包编号
Acknowledgment Number 确认包号
urg/ack/psh/rst/syn/fin 标志位,设置是/否的操作标志
Window 流量控制窗口
Checksum 包完整性校验

注意:客户端和服务端使用独立的包编号计数器器
checksum服务端和客户端会分别计算,客户端依靠这个值判断tcp包在传输过程中是否被异常改变/篡改

Read more   2019/12/27 posted in  TCP/IP

twitter公司redis&memcached中间件twemproxy源码分析(一)

twemproxy是redis和memcached连接池中间件

github项目地址:https://github.com/twitter/twemproxy

项目简介参考:https://github.com/twitter/twemproxy#features

文档参考:https://github.com/twitter/twemproxy/blob/master/notes/recommendation.md

核心流程

主流程就是启动了一个事件循环,所有的逻辑通过事件出发调用回调函数执行

Read more   2019/10/17 posted in  源码分析

"删除排序数组中的重复项" 普通解和性能优化解

饭后小憩

官方地址:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array/submissions/

问题描述

给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。

不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。

示例 1:

给定数组 nums = [1,1,2],

函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。

你不需要考虑数组中超出新长度后面的元素。

基本事实

比较容易想到的就是 相邻的元素进行比较,然后删除相同的相邻元素即可,重复这个过程直到数组末尾

另一种不容易想到的就是 把不重复的元素重新覆盖到元素数组中(不能使用额外数组,满足不使用额外的数组空间)

Read more   2019/10/9 posted in  leetcode