有一些不得不吐槽的

新技术真的好么,我并不觉得,至少我所在的层级很不喜欢各种新技术
我原来从来没用过MyBatis,总听说多好多好,但是在绝大部分场景下,都不如我直接用spring jdbc template来的方便,它那套orm转换预设了太多假设,为了解决那一堆不符合假设的场景又发明一堆概念。

比方说一个很简单的例子:

  • 我的数据库的时间字段是varchar类型保存的,那么我用Spring jdbc大概会需要对一个表对象写大约二十行的代码做orm转换。
  • 但是我用Mybatis也不见得少几行,特别是用xml写sql的时候还要自己指定Handler来做转换。
  • 有一点更不方便,项目大部分都采用spring做对象管理,当基础包和上层应用都用spring管理了,而基础包却依赖了某个特定的spring配置项,然后大家就呵呵了

其实最中心想吐槽的应该是,基础包应该尽可能的少依赖外部,或者说自有配置应该打包输出并封装在自己的项目,不要和上层应用发生耦合,会造成各种的不舒服.

数据同步

网络传输的数据结构要点:

要能区分出数据来源

要能区分数据新旧

要能分辨数据正确性

除了对数据结构的直接操作,其他都应该是外部组件

数据状态

正常

过旧

冲突(定义为异常状态需要使用者自己处理)

以上抽象成Condition

可能的复杂点

多数据冲突同一个数据,组件不解决,应该由业务处理

组件需要保证每次同步都将会是原子操作,故而多线程并发会是难点

尽可能使的组件易于扩展(尽量用接口编程)

Gradle简易使用说明

无idea情况下

建立一个目录,shell进入相应的目录,执行gradle init就能够创建一个java项目了

gradle采用约定大于配置的模式,类似maven,以下是一个gradle项目目录结构:

├─.gradle
│  ├─3.3
│  │  └─taskArtifacts
│  ├─3.5
│  │  ├─file-changes
│  │  ├─fileContent
│  │  └─taskHistory
│  └─buildOutputCleanup
├─.idea
│  ├─libraries
│  └─modules
│      ├─module1
│      └─module2
├─build
│  ├─libs
│  └─tmp
│      └─jar
├─gradle
│  └─wrapper
├─module1
│  ├─build
│  │  ├─classes
│  │  │  ├─main
│  │  │  │  └─com
│  │  │  │      └─michaelssss
│  │  │  └─test
│  │  │      └─com
│  │  │          └─michaelssss
│  │  ├─libs
│  │  ├─reports
│  │  │  └─tests
│  │  │      └─test
│  │  │          ├─classes
│  │  │          ├─css
│  │  │          ├─js
│  │  │          └─packages
│  │  ├─test-results
│  │  │  └─test
│  │  │      └─binary
│  │  └─tmp
│  │      ├─compileJava
│  │      ├─compileTestJava
│  │      │  └─emptySourcePathRef
│  │      └─jar
│  └─src
│      ├─main
│      │  └─java
│      │      └─com
│      │          └─michaelssss
│      └─test
│          └─java
│              └─com
│                  └─michaelssss
└─module2
    ├─build
    │  ├─classes
    │  │  ├─main
    │  │  │  └─com
    │  │  │      └─michaelssss
    │  │  └─test
    │  │      └─com
    │  │          └─michaelssss
    │  ├─libs
    │  ├─reports
    │  │  └─tests
    │  │      └─test
    │  │          ├─classes
    │  │          ├─css
    │  │          ├─js
    │  │          └─packages
    │  ├─test-results
    │  │  └─test
    │  │      └─binary
    │  └─tmp
    │      ├─compileJava
    │      │  └─emptySourcePathRef
    │      ├─compileTestJava
    │      │  └─emptySourcePathRef
    │      └─jar
    └─src
        ├─main
        │  └─java
        │      └─com
        │          └─michaelssss
        └─test
            └─java
                └─com
                    └─michaelssss

idea能直接识别gradle项目,不用做额外配置

使用gradle简易动作:

gradle clean build test –fullstacktrace

有意思的新东西

完全拖拽的方式实现表创建及管理(但是相应的例外建立的模型,和SQL关系不清晰,且无文档)

Gradle解决依赖和版本管理;

发布仍旧为手工发布?(好像是);

gitlab提供了版本管理流程;

平台提供所有组件,业务只需要Gradle引入相应的项目自动解决依赖(貌似看上去挺爽的);

又因为平台提供了所有组件,或者称为服务,所以内部普遍采用RPC的方式;

有自有wiki;

目测缺少bug track,用wiki暂时顶着(好像是)

gitlab提供了版本管理流程

由以上带来的缺点是:

新手入门还是很有成本的。

Gradle是要学习的新东东,另外Gradle不像ant那么的简单,但是可以从maven借鉴大量的概念来学习

没有显式的RPC调用语句,黑箱带来了一定程度上的阅读困难,特别是跨project的调用压根看不到服务提供者的实现细节,从而缺少了注释说明。

拓展性

假设我们有一张用户表:

uid,username,nickname,birthday……等有限个元素

当我们需要加入用户更多的信息应该如何实现?

有如下两个我想到的方案

  1. 根据uid作为外键,然后建立新表
  2. 在此表中加入一个可以动态扩展的字段

先说第一种,

比如我要新加一种属性,叫用户性别:gender;那么我就可以新建立一张表叫做gender,或者直接用db的外键,或者直接带逻辑代码中用uid查询。

这里的好处是可以保持原来的字段不改变,避免原来的表结构膨胀,可以直接做索引(扩展字段无法索引,随时可能超出64字节的索引量,MYSQL)

第二种,

我们可以在用户表中新增一个null的字段,叫做ext,中间保存的是json字符串,这个字符串由各个业务共同使用各自转换成相应语言中的数据结构

好处也是不增加新表

坏处是这个字段是无法索引的,所以只能存放一些静态的,不需要索引的数据

编程珠玑|读书笔记

  • 给定40亿个随机排列的32位整数的顺序文件,找出一个不在文件中的整数

首先先估算大小:

一个32位整数4bytes

40亿则是4*4.000.000.000bytes = 15625000KB ~= 15258MB ~= 15GB

如果采用bitmap还可以降低为2GB左右的内存

显然,现在随便一台高级点的计算机可以达到此内存级别,那么内存充足的情况下,直接对这个文件做map,然后顺序遍历一遍,空间复杂度为O(n),时间复杂度为O(n)

在内存不足情况下,但是有额外的外存空间,我们做归并排序,然后遍历,时间复杂度为O(n+nlogn)

还有一种做法是标准的二分查找:

我们给定一个分割标准(这里用整数的范围做标准),使得40亿个整数能够均匀的分布在两个文件

然后找到哪部分的文件不够20亿个,重复上一步骤直到整数范围上限和下限相同,则此时上限=下限=缺失的文件

  • 给定一个英语词典,找出其中所有变位词集合

我们为每一个英文字母映射成一个素数,遍历字典,找出英文字母对应的素数乘积值一样的,即是变位词。

这个正确性由算术基本定理保证