go json转换

确定类型变换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package main
import (
"encoding/json"
"fmt"
)
type F struct {
H string
K int
}
type A struct {
B string
C int
D map[string]int
E []int
F F
}
func main() {
txt := `{"b":"hello word","c":1,"d":{"a":1,"b":2},"e":[2,3,4,5],"f":{"h":"a","k":1}}`
var ab A
json.Unmarshal([]byte(txt), &ab)
fmt.Println(ab.B)
fmt.Println(ab.C)
for key, val := range(ab.D){
fmt.Println(key, val)
}
for _, e := range(ab.E){
fmt.Println(e)
}
fmt.Println(ab.F.H)
fmt.Println(ab.F.K)
}

确定类型的转换,需要明确知道json文档会转成什么类型,可以嵌套,可以是自定义类型。比较适合文档数据库的模型对接。

不确定类型变换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package main
import (
"encoding/json"
"fmt"
)
func Decode(obj map[string]interface{}){
for k, v := range obj {
switch vv := v.(type) {
case string:
fmt.Println(k, "is string", vv)
case int:
fmt.Println(k, "is int", vv)
case float64:
fmt.Println(k,"is float64",vv)
case []interface{}:
fmt.Println(k, "is an array:")
for i, u := range vv {
fmt.Println(i, u)
}
default:
fmt.Println(k, "is of a type I don't know how to handle")
}
}
}
func main() {
txt := `{"a":1,"b":"hello","c":{"a":1,"b":2.5},"d":["a","b","c"]}`
var ab map[string]interface{}
json.Unmarshal([]byte(txt), &ab)
Decode(ab)
}

不确定类型的转换,不用知道json文档会转成什么类型,可以通过类型推断value.(type)或者reflect.ValueOf(value)搭配switch使用,不太好的是每个解析转换地方都要编码。

递归模型变换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package main
import (
"encoding/json"
"fmt"
)
func JsonDecode(str []byte) map[string]interface{} {
var dict map[string]interface{}
err := json.Unmarshal(str, &dict)
if err != nil {
fmt.Println(err)
return nil
}
return dict
}
func JsonEncode(dict interface{}) []byte {
str, err := json.Marshal(dict)
if err != nil {
fmt.Println(err)
return nil
}
println(string(str))
return str
}
type A struct {
B string
C int
D *A
}
func main() {
var a A
var hk A
a = A{
B:"hello word!",
C:1,
D:&A{
B:"hello ABC",
C:2,
D:nil,
},
}
fmt.Println(a.B)
str, _ := json.Marshal(a)
println(string(str))
json.Unmarshal(str, &hk)
fmt.Println(hk.D.B)
}

递归类型的转换,允许深度的层次扩增,不允许广度的动态类型。

静态语言和动态语言的在json处理上体现的非常明显,动态语言处理实在太方便了,即开即用,而静态语言处理就比较吃力,但是实际上开发的时候,应该用确定的东西,尽量避开不确定,一劳永逸,类型推断方便使用的时候确定数据类型,递归模型处理还是不错的,某些特定场景很有用。

Linux的文件权限设计思想

1
2
[lavenderuni@~]# ls -l bitauth.md
-rw-r--r-- 1 lavenderuni staff 1137 10 25 14:43 bitauth.md
  • 0 — 表示没有权限,二进制为000
  • 1 –x 表示有执行权限,二进制为001
  • 2 -w- 表示有写权限,二进制为010
  • 3 -wx 表示有写和执行权限,二进制为011
  • 4 r– 表示有读权限,二进制为100
  • 5 r-x 表示有读和执行权限,二进制为101
  • 6 rw- 表示有读和写权限,二进制为110
  • 7 rwx 表示有读、写和执行权限,二进制为111

假如给定一个数字6,3,4,如何判定在这个数字里面包含某一种权限呢?

bit运算

  • 读权限 r=4,二进制表示为100
  • 写权限 w=2,二进制表示为010
  • 执行权限x=1,二进制表示为001

6表示为110
110 & 100 = 100 = 4 !=0 有读权限
110 & 010 = 010 = 2 !=0 有写权限
110 & 001 = 000 = 0 ==0 没有执行权限

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#!/usr/bin/env python
# coding:utf-8
def bit_judge(auth_num):
auth_r = 4
auth_w = 2
auth_x = 1
auth_str = ''
if auth_num & auth_r == 0:
auth_str += '-'
else:
auth_str += 'r'
if auth_num & auth_w == 0:
auth_str += '-'
else:
auth_str += 'w'
if auth_num & auth_x == 0:
auth_str += '-'
else:
auth_str += 'x'
return auth_str
if __name__ == '__main__':
print bit_judge(4)
print bit_judge(6)

相除求余

6表示为110
(6 / 4) % 2 ==1 有读权限
(6 / 2) % 2 ==1 有写权限
(6 / 1) % 2 ==0 没有执行权限

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#!/usr/bin/env python
# coding:utf-8
def dividemod_judge(auth_num):
auth_r = 4
auth_w = 2
auth_x = 1
auth_str = ''
if (auth_num / auth_r) % 2 == 1:
auth_str += 'r'
else:
auth_str += '-'
if (auth_num / auth_w) % 2 == 1:
auth_str += 'w'
else:
auth_str += '-'
if (auth_num / auth_x) % 2 == 1:
auth_str += 'x'
else:
auth_str += '-'
return auth_str
if __name__ == '__main__':
print dividemod_judge(6)
print dividemod_judge(4)

思考

mysql中数据设计类似权限数据,或者动态tag数据,都可以用多个bit位表示,是不是可以不用关联表,将数据降维,放在一个字段存储呢

公开 = 1
加密 = 2
封锁 = 4
置顶 = 8

  • 公开blog 给status进行或运算
    update blog set status = status | 1;
  • 加密blog 给status进行或运算
    update blog set status = status | 2;
  • 封锁blog
    update blog set status = status | 4;
  • 解锁blog
    update blog set status = status ^ 4;
  • 查询所有被置顶的blog
    select from blog where status & 8;
    等价于select
    from blog where (status & 8) != 0;

缺点是查询的时候没有办法使用索引,因为位运算无法移动到=号的右边。

ubuntu apt

问题

1
2
3
4
5
6
7
8
9
Reading package lists... Error!
W: GPG error: http://download.opensuse.org Release: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY D54CC349F42D5F07
E: Encountered a section with no Package: header
E: Problem with MergeList /var/lib/apt/lists/packages.linuxmint.com_dists_qiana_import_i18n_Translation-en
E: The package lists or status file could not be parsed or opened.
Reading package lists... Error!
E: Encountered a section with no Package: header
E: Problem with MergeList /var/lib/apt/lists/packages.linuxmint.com_dists_qiana_import_i18n_Translation-en
E: The package lists or status file could not be parsed or opened.

解决方法

1
2
3
(workspace) ➜ ~ apt-key list | grep "expired:"
(workspace) ➜ ~ apt-key adv --recv-keys --keyserver keys.gnupg.net "C300EE8C"
(workspace) ➜ ~ apt-key adv --recv-keys --keyserver keys.gnupg.net "7BD9BF62"

五大常用算法

分治

把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并

动态规划

每次决策依赖于当前状态,又随即引起状态的转移。一个决策序列就是在变化的状态中产生出来的,所以,这种多阶段最优化决策解决问题的过程就称为动态规划

贪心

在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。常见的贪心算法有:Prim算法、Kruskal算法(都是求最小生成树的)

回溯

回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径

分支限界

类似于回溯法,也是一种在问题的解空间树T上搜索问题解的算法。但在一般情况下,分支限界法与回溯法的求解目标不同。回溯法的求解目标是找出T中满足约束条件的所有解,而分支限界法的求解目标则是找出满足约束条件的一个解,或是在满足约束条件的解中找出使某一目标函数值达到极大或极小的解,即在某种意义下的最优解


分治和贪心算法其实都是map-reduce的过程,分治的reduce是compare出最优的,贪心算法的reduce是sum(*局部最优解),属于广度优先;回溯和分支限界都属于深度优先;动态规划是一种复杂的形态,暂时未有好的概括,敬请期待。

http

http long polling

  • 单个请求的超时时间尽量长一些
  • 每个请求在接收回调里面发起下一个请求
  • 服务端对于该请求用一个全局队列缓存数据
1
2
3
4
[lavenderuni@~]# cd longpolling
[lavenderuni@~]# python run.py
浏览器打开http://localhost:8888/static/demo.html

http comet streaming

  • 请求发送完成后,保持连接keep-alive
  • 保持连接过程中,服务端可以不断推送数据到客户端
  • 结束标志是发送了多少数据,是否到了业务边界
  • web端目前靠xmlhttprequest的readyState=3来接收数据
1
2
3
4
[lavenderuni@~]# cd streaming
[lavenderuni@~]# python run.py
浏览器打开http://localhost:8888/static/demo.html

http1.1 pipeline

通过同一个tcp数据包发送多个http请求,http管线化向网络上发送更少的tcp数据包,以便减轻网络负载

1
2

http2

  • 一个HTTP/2连接可保持多个stream
  • 流可被客户端或服务器单独或共享创建和使用
  • 流可被任一端关闭
  • 在流内发送和接收数据都要按照顺序
  • 流的标识符自然数表示,1~2^31-1区间,有创建流的终端分配
  • 流与流之间逻辑上是并行、独立存在
  • 流有优先级(priority),优先级高的先处理
  • 流的并发数最好多于100
  • 流量控制阀协调网络带宽资源利用,由接收端提出发送端遵守其规则
  • 流具有完整的生命周期,从创建到最终关闭,经历不同阶段
1
2

websocket

双工协议

1
2

csrf是跨域伪造请求攻击

1
2
3
4
5
6
7
8
9
[lavenderuni@~]# python run1.py # 开启http://127.0.0.1:8888/
[lavenderuni@~]# python run2.py # 开启http://127.0.0.1:9999/
1. 浏览器打开http://localhost:8888/static/demo1.html
2. 点击跳转到http://127.0.0.1:9999/static/demo2.html
3. 观察demo2.html页面的模拟ajax get请求传到localhost:8888的cookie
4. 观察demo2.html页面的img src请求传到localhost:8888的cookie
5. 点击evil way发起模拟ajax post请求传到localhost:8888的cookie
6. 点击iframe里面的evil way发起form请求传到localhost:8888的cookie

相关测试参照testlab的http

最佳五本书-scala

scala是一门可以装逼,可以实战的,面向过程和面向对象结合的语言。

想学scala,从5本最值得推荐的书开始下载

  • Programming in Scala: A Comprehensive Step-by-Step Guide, 2nd Edition by Martin Odersky

scala

scala之父Martin Odersky亲自操刀,销量非常好,从从业者的角度介绍编程语言的基本使用、高级特性,可以使你成为一个更优秀高效的开发人员。

  • Scala for the Impatient by Cay S.Horstmann

scala

由Java核心技术作者Cay S.Horstmann撰写,通过简洁实用的代码例子向开发者简要说明Scala能做什么和怎么做,为了有助于快速掌握和运用,将Scala的概念和技术介绍篇章像博客一样渐渐展开。

  • Scala in Depth by Joshua D.Suereth

scala

作者Joshua D.Suereth是Typesafe公司的一名软件工程师,也是scala的代码贡献者之一。
本书通过Scala社区出现的最佳实践和设计一个个例子,帮你快速将scala整合到项目开发中,引导你了解这门强大的技术语言。

  • Scala in Action by Nilanjan Raychaudhuri

scala

Nilanjan Raychaudhuri是Scala的优秀实践者之一,本书中通过清晰的逻辑和大量的实例分析,全面介绍了丰富深刻的语言概念和特性,并介绍了日常开发中的编程挑战如何在Scala里面实现。

  • Programming Scala: Scalability = Functional Programming + Objects (Animal Guide) by Dean Wampler and Alex Payne

scala

本书有两位作者,Dean Wampler是编程语言Scala的共同开发者,曾就职于Object Mentor。Alex Payne是Twitter的早期员工之一。书中清楚地解释了Scala作为JVM语言的优势。用代码例子,教你如何将丰富的java类库引入解决企业web项目的实际需求,对Scala的命令行工具、第三方工具和库、IDE插件的使用,提供了有用的帮助。

scala是操控大数据工具spark的最好工具语言。等什么呢?一起学吧。

nginx 指令提取url的参数url的uri

以上两个url的参数redirect都是另一个url,想提取redirect的uri,例如/a/b?cd=将军令,该如何做呢?

以下测试配置可以做到,其中set_unescape_uri的作用是将转码过的url解码,属于set-misc-nginx-module;echo是测试打印用的,属于echo-nginx-module

关键点在于if ( $obj_uri ~ ^(http?://)([^:^/])(:\d)?(.*)? ) 用正则对字符串做切割,分成4段,当4个参数传入if作用域。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
worker_processes 1;
error_log /usr/local/var/log/nginx/error.log;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
access_log /usr/local/var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
echo "hello, world!";
}
location /test {
set $obj_uri $arg_uri;
set_unescape_uri $obj_uri;
if ( $obj_uri ~ ^(http?://)([^:^/]*)(:\\d*)?(.*)? ){
set $obj_uri $4;
echo $obj_uri;
}
if ( $obj_uri ~ ^(https?://)([^:^/]*)(:\\d*)?(.*)? ){
set $obj_uri $4;
echo $obj_uri;
}
echo $obj_uri;
}
}
include servers/*;
}

效果

1
2
/a/b?cd=将军令
/a/b/c?d=丑小鸭

c struct of python list and dict

python list和dict虽然好用,但是也有坑。

list

list对象c定义是指针数组:
python的list是变长的,并非等同于链表的变长,而是采用指针数组,保证了多种操作的性能平衡,同时支持元素类型的动态性。

1
2
3
4
5
typedef struct {
PyObject_VAR_HEAD
PyObject **ob_item;
Py_ssize_t allocated;
} PyListObject;
  • PyObject_VAR_HEAD为变长对象头,其中的ob_size表示list长度
  • ob_item为容器,存储PyObject对象指针
  • allocated表示已分配多少存储空间

list的生命周期:

  • alloc,根据PyListObject free_lists里面的缓存情况和策略,判断是否创建list对象
  • 为ob_item分配内存
  • append操作,追加元素list.append(obj),根据ob_item预留空间策略判断是否resize,在ob_item尾部添加指针,指向obj
  • =操作,更新元素list[i]=obj,就是数组的指针指向新的value对象
  • insert操作,插入元素list.insert(obj),根据ob_item预留空间策略判断是否resize,查找插入点,将插入点后的元素向后移,在插入点增加指针,指向obj
  • remove操作,删除元素list.remove(obj),查找删除点,删除该位置的指针,将删除点后的元素向前移,根据ob_item预留空间策略判断是否resize
  • pop操作,弹出元素list.pop(obj),将尾部指针返回,并删除尾部指针,根据ob_item预留空间策略判断是否resize
  • 回收ob_item的内存
  • dealloc 根据PyListObject free_lists里面的缓存情况和策略,判断是否销毁list对象

list的append、pop性能优于insert、remove,list的slice操作和extends操作都会有resize。

dict

dict对象c定义是哈希表:
哈希表查找的时间复杂度为O(1),dict采用开放寻址法解决hash冲突,开放寻址法比拉链法能更好地利用CPU cache,cache命中率较高。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
typedef struct {
Py_ssize_t me_hash;
PyObject *me_key;
PyObject *me_value;
} PyDictEntry;
typedef struct _dictobject PyDictObject;
struct _dictobject {
PyObject_HEAD
Py_ssize_t ma_fill; /* # Active + # Dummy */
Py_ssize_t ma_used; /* # Active */
Py_ssize_t ma_mask; /* equal to size of ma_table - 1; calc index*/
PyDictEntry *ma_table;
PyDictEntry *(*ma_lookup)(PyDictObject *mp, PyObject *key, long hash);
PyDictEntry ma_smalltable[PyDict_MINSIZE];
};
  • entry的Unused:me_key == me_value == NULL,即未使用的空闲状态
  • entry的Active:me_key != NULL, me_value != NULL,即该entry已被占用
  • entry的Dummy:me_key == dummy, me_value == NULL
  • PyObject_HEAD的ob_size用不上,dict没有长度
  • ma_fill记录Active + Dummy状态的entry数
  • ma_used记录Active状态的entry数
  • ma_mask等于slot总数 - 1
  • ma_table为容器,存储PyDictEntry对象指针
  • ma_lookup是搜索函数,因为Python中key不一定是String,所有搜索函数针对dict key做优化,当遇到string key使用lookdict_string,否则调用默认的lookdict
  • ma_smalltable为小字典容器(小于8个key-value)ma_smalltable,超出后再从内存分配空间

dict的生命周期:

  • alloc,根据PyDictObject free_lists里面的缓存情况和策略,判断是否创建dict对象,关联搜索方法lookdict_string
  • 为ma_table分配内存
  • set操作,添加元素dict[key]=val/dict.set(key, val),将key-val生成PyDictEntry object,检查冲突探测链不存在,计算哈希位置,如果发生冲突,通过二次探测算法,寻找下一个位置,直到找到可用位置,并根据ma_table预留空间策略决定是否resize,添加可用位置的指针,指向PyDictEntry object,并将该位置放入冲突探测链
  • set操作,更新元素dict[key]=val/dict.set(key, val),将key-val生成PyDictEntry object,检查冲突探测链存在,找到该位置,将指针指向新的PyDictEntry object
  • get操作,查找元素dict[key]/dict.get(key),遍历冲突探测链,找到该位置,返回该位置的指针指向的PyDictEntry object的value
  • pop操作,弹出元素dict.pop(key),遍历冲突探测链,找到该位置,返回该位置的指针指向的PyDictEntry object的value,删除对应指针,将PyDictEntry object从Active转换成Dummy,并根据ma_table预留空间策略决定是否resize
  • popitem,随机删除key-val,性能优于pop操作
  • del操作,删除元素del dict[key],遍历冲突探测链,找到该位置,删除对应指针和指向的PyDictEntry object,并根据ma_table预留空间策略决定是否resize
  • 回收ma_table的内存
  • dealloc 根据PyDictObject free_lists里面的缓存情况和策略,判断是否销毁dict对象

tuple、set的解构和list类似,tuple在list基础上加了不可更改限制,只能create,set是在list的基础上加了重复检测方法。

redis vs memcached

redis和memcached都属于nosql数据库,数据都在内存,都是key-value的数据库,当然,redis能存储复杂的struct类型的value,各种开发语言的客户端都支持的很好。redis和memcached都是极好的缓存工具,什么时候该用redis,什么时候该用memcached呢?
意译redis vs memcached

Memcached的优势

  • Memcached采用LRU策略淘汰旧数据,适合存放小体积的数据或者静态数据,同样的基本数据在Memcached里面的内存消耗要少,对于动态数据、序列化大体积数据没有什么优势,容易产生内存碎片。

  • Memcached支持多线程,可以应对性能的压力,一致性hash可以减少数据丢失。redis可以通过集群来抗压,但是部署维护相对复杂。

Redis的优势

  • Redis是单线程的,适合存储各种复杂数据类型,提供了string、list、set、hash、sortedset等数据类型,不会丢数据,可以通过aof或者快照来持久化,甚至可以替代mongo。

  • Redis的淘汰策略优于Memcached,提供了6中淘汰算法,而且淘汰机制有三层。

    • 当读/写一个已经过期的key时,会触发惰性删除策略,直接删除掉这个过期key
    • 惰性删除策略无法保证冷数据被及时删掉,Redis会根据配置文件的hz参数,调用databasesCron()函数触发清理策略,定期主动淘汰一批已过期的key,每次淘汰任务执行的最大时长timelimit根据hz参数计算而来,和hz是倒数关系,主动淘汰频率越高,则每次淘汰最长占用时间就越短,避免每次主动淘汰阻塞应用请求
    • 当前已用内存超过maxmemory限定时,根据用户配置的maxmemory-policy参数(一般为LRU/TTL),选取算法对redis里面的maxmemory-samples个key进行抽样清理(maxmemory-samples的增加,会提高LRU或TTL的精准度,同时会导致清理时消耗更多的CPU时间;最好不要触发这个清理)
  • Redis的key长度是512MB,Memcached限制key长度在250 bytes以内。

  • Redis可以搭载lua脚本。

哈希国度

哈希国度

utopia

人类和各种其他生物进化了几千年,按照现有的分布方式,地球的三维空间逐渐满足不了日益膨胀的发展。

渡渡鸟,蓝马羚,旅鸽,卡罗莱那鹦鹉,红鸭,普氏野马,袋狼…..很多动物,其实还有植物,都已经成为了传说,基本原因都是因为人类的活动范围扩张和无知造成的。动植物改造环境的效率低,所以具有很强的适应环境的能力,而人类改造环境的能力越来越强,效率越来越高,导致动植物完全适应不了人类的改造速度和改造范围,这是种间竞争,就是强势物种干掉弱势物种。

同时,人类自身规模的增长,导致种内斗争日益加剧,例如战争、和平时期的社会悲剧。动植物也有种内斗争,例如雄性求偶、争夺水源、撕抢食物…..整体而言,人类的种内斗争要比动植物世界来的复杂,范围更广,因为人类个体的活动范围也比动植物的要广,一个人类终其一生可能足迹遍布全球甚至外太空,然而动植物活动范围不过方圆几里。历史上大大小小的战争都是人类的种内斗争的体现,原因也是千奇百怪,有信仰引发的,有红颜引发的,有城池引发的,有理想引发的,还有误会引发的…..

在远古时代,人类和动植物的生存繁衍能力相差不大,至少是在上帝的控制范围之内,现代人觉得那个时候很和谐,地球很健康,因为大自然通过种间竞争和种内斗争平衡了一切生灵的发展状态,即使有物种灭绝也是大部分生灵的共同作用。而今人类的能力超前强大,人类的行为对所有生物的发展影响最大,包括自己。

人类该如何把握自身的发展,让地球维持健康呢?我觉得还是要从人类行为的效率出发,很多的人类行为都是盲目的,无序的,混沌的,导致了空间的浪费,资源的浪费,加剧了地球上的种间竞争和种内斗争,加速了各种灭亡。我是it从业者,业内有一种技术叫Hash,一般翻译做“散列”,也有音译为“哈希”的。哈希就是把任意长度的输入(又叫做预映射,pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值,是一种压缩映射的转换,散列值的空间通常远小于输入的空间。简单来说,就是一个萝卜一个坑,最好没有空的坑和没有坑的萝卜。

其实人类行为的分布,何尝不是一种哈希呢?

将地球看成存储空间,人类还有动植物分布在世界的角落,有很多地方是稀疏的,有很多地方是密集的,然而从哈希的角度看,都是不合理的,浪费的,所以导致了不平等,不和谐,不对称。像纽约、北京一类的大城市,聚集了大量的人口,即使是一城之内的分布也是不均匀的,就出现了贫民窟、城中村,衣食住行拥堵,民族主义仇杀等种种问题。还有人类的繁殖,盲目开垦,工业污染,科技污染等等,都是因为上帝无法控制人类的自主动态分布。而目前人类的自主依旧很盲目,导致人类占据了太多不需要的空间和资源,于是动植物的发展范围在缩小。这么多人类悲伤的事情,就像机器的hash冲突一样。

既然上帝无法控制了,人类自身已经掌握了权利,为什么要放任自己的行为的分布呢?我想上帝hash方式是一种混沌,而人类需要找出一种能自我理解,自我控制的hash方式,当然it界的很多hash方式尽管很优秀,还是无法应对人类发展以及地球发展需要的如此庞杂又动态的分布,毕竟it界的hash方式的空间都是简单的。

我们的社会制度、生活规则、科技工具、法律、道德、信仰、环保意识等等一些公约形态都可以看做人类hash方式的一部分,人类的hash是一种富类hash,只是还不够完备智能,还不足以处理巨大的地球数据,当然不能替代上帝的混沌hash方式。社会制度就是一种hash制度,国民们需要不断地积累经验教训,抓住社会问题的hash冲突本质,而不是经过通过忍让、逃避、欺骗、忘记来解决问题。发展出一套完备的hash制度能让国家变成哈希国度,也许就是一些哲学家梦里的乌托邦。

如果有一天人类的富类hash方式能够取代上帝的混沌hash方式,就能像大自然一样主动调节达到地球的平衡发展。