网络传输的数据结构要点:
要能区分出数据来源
要能区分数据新旧
要能分辨数据正确性
除了对数据结构的直接操作,其他都应该是外部组件
数据状态
正常
过旧
冲突(定义为异常状态需要使用者自己处理)
以上抽象成Condition
可能的复杂点
多数据冲突同一个数据,组件不解决,应该由业务处理
组件需要保证每次同步都将会是原子操作,故而多线程并发会是难点
尽可能使的组件易于扩展(尽量用接口编程)
网络传输的数据结构要点:
要能区分出数据来源
要能区分数据新旧
要能分辨数据正确性
除了对数据结构的直接操作,其他都应该是外部组件
数据状态
正常
过旧
冲突(定义为异常状态需要使用者自己处理)
以上抽象成Condition
可能的复杂点
多数据冲突同一个数据,组件不解决,应该由业务处理
组件需要保证每次同步都将会是原子操作,故而多线程并发会是难点
尽可能使的组件易于扩展(尽量用接口编程)
无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……等有限个元素
当我们需要加入用户更多的信息应该如何实现?
有如下两个我想到的方案
先说第一种,
比如我要新加一种属性,叫用户性别:gender;那么我就可以新建立一张表叫做gender,或者直接用db的外键,或者直接带逻辑代码中用uid查询。
这里的好处是可以保持原来的字段不改变,避免原来的表结构膨胀,可以直接做索引(扩展字段无法索引,随时可能超出64字节的索引量,MYSQL)
第二种,
我们可以在用户表中新增一个null的字段,叫做ext,中间保存的是json字符串,这个字符串由各个业务共同使用各自转换成相应语言中的数据结构
好处也是不增加新表
坏处是这个字段是无法索引的,所以只能存放一些静态的,不需要索引的数据
三月十号提的离职,
接下来两周各种交接工作,第三周开始就开始无聊了。。。
说起来忙的时候反而更愿意学习,闲下来了反而不愿意,宁愿在网上瞎点。
包括连三月初我非常感兴趣的JVM的研究,Windows有时候真的对程序员不友好,起码各种工具的exe没有完整的注册自己,跟着一些教程走简直就是给自己挖坑。
蹲在公司有一点坏处,写的代码不能传网上,包括自己写的,这就很蛋疼了。而且不参与开发的话,就不会产生出一些idea
不过这一周准备过完了,马上就是放假了,期待新入职的公司能够得到一些我没见过的视野。
首先先估算大小:
一个32位整数4bytes
40亿则是4*4.000.000.000bytes = 15625000KB ~= 15258MB ~= 15GB
如果采用bitmap还可以降低为2GB左右的内存
显然,现在随便一台高级点的计算机可以达到此内存级别,那么内存充足的情况下,直接对这个文件做map,然后顺序遍历一遍,空间复杂度为O(n),时间复杂度为O(n)
在内存不足情况下,但是有额外的外存空间,我们做归并排序,然后遍历,时间复杂度为O(n+nlogn)
还有一种做法是标准的二分查找:
我们给定一个分割标准(这里用整数的范围做标准),使得40亿个整数能够均匀的分布在两个文件
然后找到哪部分的文件不够20亿个,重复上一步骤直到整数范围上限和下限相同,则此时上限=下限=缺失的文件
我们为每一个英文字母映射成一个素数,遍历字典,找出英文字母对应的素数乘积值一样的,即是变位词。
这个正确性由算术基本定理保证
[+] 加密实现
[+]将加密和解密的代码和主代码分离
[+] 添加log4j2作为日志系统
[-] 测试代码删除
[m] 改成maven项目
todo:
[+] 增加流的加密
[?] 对象的递归加密
昨晚写JVM收集器的选择,说到编程中到处都是TradeOff,想起了前几天QQ群的一些讨论;
问:怎么样的一个工程才算是比较好的工程
群里面比较多的答复是;
比如有VCS啦,能够DevOps啦,还有关注代码质量啦。
但是在我看来,这些都没说到点子上。我认为一个好的工程应该是和其应用场景及生命周期相关的
Example 1:
我写了一个HelloWorld想学习一门新的语言,比如Java,那么这时候我们只需要一个Vim,一个JDK就足够了,就是一个好的工程了
Example 2:
我做了一个工具,能够自动的收集所在计算机的负载数据,我需要的数据在很长范围内是不会增加或者改变的,那么我随便一个IDE,怎么写得快就怎么写,这样可以快速使用,连VCS都可以不用有
Example 3:
我对外声称了一个比较小型服务,比如计算A+B的结果,那么我只要SVN和一个tomcat加上一个IDE就足够了,什么Spring,什么Struct都不需要。30KB+tomcat大小足以
Example 4:
我对外声称提供越来越多的服务,这时候可以用上DevOps的思想,节省部署的时间和复杂度
在没有提供使用场景和生命周期的情况下,说一个通用的项目应该具备哪些条件就是耍流氓。
在一般意义上,够用就好就足够了
需要关注
响应时间,吞吐量
最古典的Serial收集器在内存占用少于100MB的应用表现最好。
并行的Serial收集器在多核情况下能极大改善吞吐量,但是STW时间比较长
CMS同样在多核情况下表现好,但相比并行Serial收集器则吞吐量有下降但能极大的改善响应时间
包括新的G1收集器在内都无法解决不可控的STW时间
故而最近还有一种提议无收集器JVM,但是这样完全放弃了java的优势
还有一种java实时应用程序,用确定的STW时间来消除不可控的STW,但是极大地降低了吞吐量,且要在代码上作出一定的设计,否则程序无法顺利运行
总结:
Java的性能调优就是一场Trade off的行为