一本关于如何读书的书,类似《这样读书就够了》,强调输出,为己所用。

20191019_191030.png

关键字:输出,碎片时间

英国的萨塞克斯大学曾经就缓解压力方面做过研究,结果表明:读书可以缓解 68%的压力,听音乐可以缓解 61%的压力,咖啡可以缓解 54%的压力,散步可以缓解 42%的压力

1 周输出 3 次强化记忆:从短期记忆的海马体转移到长期记忆的颞叶中

方法:

  1. 一边读书,一边做笔记
  2. 向别人讲解书的内容,推荐读过的书
  3. 将读书时的感想,发现,名言记录到社交媒体上分享,可以读完书或当时立即写。
  4. 写书评或摘要,注意:书评要在读完书隔几天在写,保持客观性,顺便复习一遍。
阅读全文 »

概念介绍

  • Broker:简单来说就是消息队列服务器实体。
  • Exchange:消息交换机,它指定消息按什么规则,路由到哪个队列。
  • Queue:消息队列载体,每个消息都会被投入到一个或多个队列。
  • Binding:绑定,它的作用就是把 exchange 和 queue 按照路由规则绑定起来。
  • Routing Key:路由关键字,exchange 根据这个关键字进行消息投递。
  • vhost:虚拟主机,一个 broker 里可以开设多个 vhost,用作不同用户的权限分离。
  • producer:消息生产者,就是投递消息的程序。
  • consumer:消息消费者,就是接受消息的程序。
  • channel:消息通道,在客户端的每个连接里,可建立多个 channel,每个 channel 代表一个会话任务。
20191018_111802.png
阅读全文 »

这是一种评论:
类似于这种将普洱茶装进各种果皮里的茶,首先,好的普洱茶原料是绝对不会用来制作这类再制茶的(因为滋味已经很好了,不需要其他的味道去掩盖杂味,加之好茶贵增加制作成本)。其次,这类茶一般将熟普装进去时候是新鲜的,把果肉挖出后再填进茶叶烘干,制作工艺良莠不齐,是否湿润的内部会让茶叶再次发酵或引起微生物变化甚至霉变都有可能,这是不可估计的。最后,市面上的新会小青柑小红柑是否食用安全不得而知,现在的农残那么严重,厂家自然会给你宣传无污染,天然,绿色。可是果皮中是否有农药残留,不知。

观外观

大家可以打开小青柑的皮盖子,然后看看里面的茶叶填充状态,如果看见里面的干茶芽头大多都是为金黄色,并且条索匀整、粗壮,且干茶色泽深褐色、乌润,并且没有任何杂物的话,那么就是优质的普洱茶;而如果发现打开青柑皮盖后,发现填充的普洱熟茶芽头比较小,条索不均匀,色泽乌黑有杂质,那么就可以说明,这样的围劣质青柑普洱茶;并且冲泡后,口感不佳者,品质多为劣质,大家切莫选购、饮用。

察白霜

首先,“白霜”的主要成分是柠檬烯,为挥发油析出物,在柑橘类水果(特别是其果皮)含量较高。

由于柠檬烯易挥发,若在密闭环境条件下,经过长时间的储藏,这些物质缓慢析出至柑皮表面并氧化为白色物质,形成“白霜”。

其次,白霜的形成与产区和加工工艺息息相关。绝大多数情况下只有新会核心产区的青皮才会有“白霜”的现象,而越是核心产区的柑果,柑皮上的油包越多,起的“白霜”也就越多。

但是即便是核心产区的青皮想要产生“白霜”,也要保证小青柑表面油囊的活性,小青柑的油囊一旦遭到破坏就难以产生“白霜”,小青柑的价值也随之降低。如果想保证油囊的活性及完整性,只有通过低温长时间烘焙的工艺,小青柑表面才会析出“白霜”。

怎么知道是霉变还是白霜

一看:白霜基本是圆状白点,霉变则是发散棉絮状。
二闻:白霜闻起来果香带陈香无杂味,霉变则是难闻的霉味。
三触摸:白霜干燥带有颗粒感,霉变的话触摸霉菌湿滑,缺乏质感,会有脱落。

其实对于小青柑来说,整颗冲泡、掰碎冲泡都是没问题的

日期格式化

strDate := time.Now().Format("2006-01-02 15:04:05")

unixTime := int64(binary.LittleEndian.Uint32(b.value[fpos:]))
block.header.Time = time.Unix(unixTime, 0).Format("2006-01-02 15:04:05")

获取当前时间戳

timeUnix:=time.Now().Unix()            //单位s,打印结果:1491888244
timeUnixNano:=time.Now().UnixNano() //单位纳秒,打印结果:1491888244752784461

unix timestamp

从字符串转

package main
import (
"fmt"
"time"
"strconv"
)
func main() {
i, err := strconv.ParseInt("1518328047", 10, 64)
if err != nil {
panic(err)
}
tm := time.Unix(i, 0)
fmt.Println(tm)
}

从 int 转

package main
import (
"fmt"
"time"
)
func main() {
tm := time.Unix(1518328047, 0)
fmt.Println(tm)
}

从 timestamp 到 UTC 时间

loc, _ := time.LoadLocation("UTC")
now := time.Unix(int64(reversArr), 0).In(loc)
//fmt.Println(" Time : ", now) // UTC
buf["timestamp"] = now.Format("2006-01-02 15:04:05 -07:00 MST")

输出:
Time : 2013-07-05 22:47:09 +0000 UTC
阅读全文 »

设置string默认编码为utf8,只需要在文件头部加入以下代码

#pragma execution_character_set("utf-8") //默认使用UTF8

vs2013/2015

stl.natvis 文件 581 行,后面替换为 ,s8 即可,如下

<!-- VC 2015 -->
<Type Name="std::basic_string&lt;char,*&gt;">
<DisplayString Condition="_Mypair._Myval2._Myres &lt; _Mypair._Myval2._BUF_SIZE">{_Mypair._Myval2._Bx._Buf,s8}</DisplayString>
<DisplayString Condition="_Mypair._Myval2._Myres &gt;= _Mypair._Myval2._BUF_SIZE">{_Mypair._Myval2._Bx._Ptr,s8}</DisplayString>
<StringView Condition="_Mypair._Myval2._Myres &lt; _Mypair._Myval2._BUF_SIZE">_Mypair._Myval2._Bx._Buf,s8</StringView>
<StringView Condition="_Mypair._Myval2._Myres &gt;= _Mypair._Myval2._BUF_SIZE">_Mypair._Myval2._Bx._Ptr,s8</StringView>

VisualStudio 2010 SP1环境

debug提示窗口显示utf8,打开C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\Packages\Debugger\autoexp.dat文件找到第412到413行

std::basic_string<char,*>{
preview ( #if (($e._Myres) < ($e._BUF_SIZE)) ( [$e._Bx._Buf,s8] ) #else ( [$e._Bx._Ptr,s8] ))
stringview ( #if (($e._Myres) < ($e._BUF_SIZE)) ( [$e._Bx._Buf,s8b] ) #else ( [$e._Bx._Ptr,s8b] ))

想要在知识的海洋里面遨游,阻力还是有的。

V2Ray 是 Project V 下的一个工具。Project V 是一个包含一系列构建特定网络环境工具的项目,而 V2Ray 属于最核心的一个。从时间上来说,先有 V2Ray 才有 Project V。如果再通俗易懂一点,V2Ray 是一个与 Shadowsocks 类似的代理软件,可以用来科学上网(翻墙)学习国外先进科学技术。

V2Ray 跟 Shadowsocks 有什么区别
在介绍V2Ray中提到:V2Ray 是一个与 Shadowsocks 类似的代理软件,那么两者之间有什么区别呢?简单来概括的话:

Shadowsocks 功能单一,V2Ray 功能强大
Shadowsocks 简单好上手,V2Ray 复杂配置多
看到这可能有人打退堂鼓了,虽然Shadowsocks 功能单一,但是已经能满足我们需要,而且简单好上手,为什么我们还要去用V2Ray?看待一个事物我们必须用辩证的思维去分析他,V2Ray有两个劣势:配置复杂,产业链不完整。
由于产业链不完整,大部分的V2Ray服务器和配置都是免费提供的,基本上连上就能用,没什么约束,当然可能服务也是说停就停,根本不跟你解释。不过对我们大部分人来说,免费就已经知足了。
虽然V2Ray的配置复杂,但其复杂带来的是更加卓越的功能:

更完善的协议(安全度高,防检测)
更强大的性能(网速快)
更丰富的功能(满足开发党需求)

VMess
VMess 协议是由 V2Ray 原创并使用于 V2Ray 的加密传输协议,如同 Shadowsocks 一样为了对抗墙的深度包检测而研发的。在 V2Ray 上客户端与服务器的通信主要是通过 VMess 协议通信。
对于我们使用者来说,不用太过地去纠结一个协议的原理和运转机制,我们只要会用就行了,需要注意的是,VMess协议是需要配置的,如果你在网上看到类似下图:

20191010_154922.png

首先打开 Profiles 配置选择页面,然后进行配置文件的添加 配置文件的链接,点击下载

Modbus通信协议由Modicon公司(现已经为施耐德公司并购,成为其旗下的子品牌)于1979年发明的,是全球最早用于工业现场的总线规约。由于其免费公开发行,使用该协议的厂家无需缴纳任何费用,Modbus通信协议采用的是主从通信模式(即Master/Slave通信模式),其在分散控制方面应用极其广泛,从而使得Modbus协议在全球得到了广泛的应用。

Modbus通信协议具有多个变种,其具有支持串口(主要是RS-485总线),以太网多个版本,其中最著名的是Modbus RTU,Modbus ASCII和Modbus TCP三种。其中Modbus RTU与Modbus ASCII均为支持RS-485总线的通信协议,其中Modbus RTU由于其采用二进制表现形式以及紧凑数据结构,通信效率较高,应用比较广泛。而Modbus ASCII由于采用ASCII码传输,并且利用特殊字符作为其字节的开始与结束标识,其传输效率要远远低于Modbus RTU协议,一般只有在通信数据量较小的情况下才考虑使用Modbus ASCII通信协议,在工业现场一般都是采用Modbus RTU协议,一般而言,大家说的基于串口通信的Modbus通信协议都是指Modbus RTU通信协议。

Modbus can work on top of RS-232, RS-485 or TCP/IP over Ethernet.

modbus-guide

  • Modbus RTU (binary over serial link)
  • Modbus ASCII (text-based over serial link)
  • Modbus TCP (binary over TCP/IP transport)

Modbus RTU Protocol

Modbus RTU is a master-slave protocol. This means that only one device, the master, is allowed to initiate communication. The other devices on the network are called slaves and they may only respond to the requests. Modbus RTU can support up to 247 devices on the same physical network. It’s possible to modify the protocol to support more slaves, but in most applications the standard limit of slaves if enough.

Modbus RTU encodes data as binary and uses big-endian encoding for 16-bit values. This means that the most significant byte of a 16-bit word is sent first.

20200221_113232.png

There are only two data types in Modbus: coils and registers.

Coils are simply single bits. The bits can be ON (1) or they can be OFF (0). Some coils represent inputs, meaning they contain the status of some physical discrete input. Or they represent outputs, meaning that they hold the state of some physical discrete output signal.

Registers are simply 16-bit unsigned register data. Registers can have a value from 0 to 65535 (0 to FFFF hexadecimal). There is no representation for negative values, no representation for values greater than 65535, and no representation for real data like 200.125.

Registers are grouped into Input Registers and Holding Registers. Like Input Coils, Input Registers report the state of some external input as a value between 0 and 65535. The original intent of an Input Register was to reflect the value of some analog input. It is a digital representation of an analog signal like a voltage or a current. Most Modbus devices today are not I/O devices, and Input Registers simply function identically to Holding Registers.

地址码 功能码 数据区 错误校验码
8位 8位 N × 8位 16位

发送数据

01 03 01 8E 00 04 25 DE

"01" 为模块的地址码,
"03" 为功能码,即表示读寄存器,
"01 8E" 为寄存器地址,即从该寄存器地址开始读取数据,
"00 04" 则表示读取4个寄存器,
而 "25 DE" 则为前面 "01 03 01 8E 00 04" 的CRC校验码,该数值通过CRC16校验算法计算出来的

返回数据

01 03 08 00 01 00 01 00 01 00 01 28 D7

"01" 为模块的地址码,
"03" 表示该指令是读操作返回的指令
"08" 表示数据长度,在此表示的是8个字节数据正文(即4个寄存器,每个寄存器两个字节表示)
"00 01 00 01 00 01 00 01" 是数据正文,表示四个寄存器的状态,
"28 D7" 就是CRC16校验码。


Tx:074-03 03 00 00 00 08 45 EE
Rx:075-03 03 10 A2 7E 73 4B A0 A7 73 32 9C CC 75 16 9C 65 75 80 76 3E
Tx:076-03 03 00 00 00 08 45 EE
Rx:077-03 03 10 A2 7A 73 84 A0 B3 73 32 9C C8 75 3A 9C 82 75 8C 42 F7
Tx:078-03 03 00 00 00 08 45 EE
Rx:079-03 03 10 A2 7E 73 78 A0 AF 73 26 9C C8 75 47 9C AB 75 88 3F 58
Tx:080-03 03 00 00 00 08 45 EE
Rx:081-03 03 10 A2 7A 73 5F A0 B3 73 1A 9C C3 75 5F 9C BB 75 7C BF 6D

20191009_150946.png 20191009_150958.png

ModBus 功能码与数据类型对应表:

20200218_105117.png

RTU 方式读取整数据的例子:

20200218_105133.png

解析一下:主机发送指令,访问从站地址为1,使用功能码03(读保持寄存器),起始地址高8位、低8位:表示想读取的模拟量的起始地址(起始地址为0)。比如例子中的起始地址为38,十进制为:56。寄存器数量高8位、低8位:表示从起始地址开始读多少个模拟量。例子中为1个模拟量。注意,在返回的信息中一个模拟量需要返回两个字节。错误校验为CRC校验。

从站应答:设备地址和命令号和上面的相同。返回的字节数:表示数据的字节个数,也就是数据1,2…n中的n的值。例子中返回了1个模拟量的数据,因为一个模拟量需要2个字节所以共2个字节。数据高低字节:41和24代表返回的1个模拟量的值,即十进制的16676。错误校验为CRC校验。

A library that can operation arbitary json structure

遍历对象数组

param = {"cmdType": 90000,
"param": {
"table": "t_op_log",
"columns": [
{"f_id": "key;"},
{"f_datetime": "type:varchar(20);not null;index:idx_f_datetime;default(cur_datetime)"},
{"f_operation": "type:varchar(200);not null"},
{"f_user_id": "type:integer(8);not null"},
{"f_op_param": "type:varchar(200);not null;default("")"},
{"f_token": "type:integer(8);not null"},
{"f_token_expiration": "type:varchar(200)"},
{"f_hardware_info": "type:varchar(200)"}
]
}
}
import (
"github.com/antonholmquist/jason"
)

json, err := jason.NewObjectFromBytes([]byte(in.Value))
if err != nil {
fmt.Println(err.Error())
}

columns, err := jsonObj.GetObjectArray("param", "columns")
if err != nil {
fmt.Println(err.Error())
}
// 遍历对象数组, index,obj
for _, column := range columns {
fmt.Println(column)
}

works only with integers

range (start, stop[, step])

range(1,5) #代表从1到5(不包含5) [1, 2, 3, 4]
range(1,5,2) #代表从1到5,间隔2(不包含5) [1, 3]
range(5) #代表从0到5(不包含5) [0, 1, 2, 3, 4]

for i in range(6):
print(i, end=', ')

Python range() example to print numbers from range 0 to 6
0, 1, 2, 3, 4, 5,

for idx in range(2, 9, 1):
print('{}'.format(idx))

输出数值 2-8

json to str

json.dumps 会保证输出是合法的 json 字符串

param = {"cmdType": 90001,
"param": {"table": "t_user", "column": ["f_id", "f_ui_id", "f_group_id"], "where": ["f_name", "f_pwd"],"value": ["admin", "4acb4bc224acbbe3c2bfdcaa39a4324e"]}}
resp = rpc_client(json.dumps(param))
阅读全文 »