1MB=1024KB? 1000KB?

如题,这个问题第一感觉是1MB肯定等于1024KB,只有在硬盘生产厂商那里才会使用1000进制。事实是如此吗?最近被人补了一课,了解单位换算中的两种标准。

按照国际单位制的标准: 1MB=1000KB (1Megabyte = 1000Kilobyte)
按照IEC 60027-2标准: 1MiB=1024KiB (1Mebibyte = 1024 Kibibyte)

字节的次方单位
十进制前缀
(SI)
名字 缩写 次方
Kilobyte KB 103
Megabyte MB 106
Gigabyte GB 109
Terabyte TB 1012
Petabyte PB 1015
Exabyte EB 1018
Zettabyte ZB 1021
Yottabyte YB 1024
二进制前缀
(IEC 60027-2)
名字 缩写 次方
Kibibyte KiB 210
Mebibyte MiB 220
Gibibyte GiB 230
Tebibyte TiB 240
Pebibyte PiB 250
Exbibyte EiB 260
Zebibyte ZiB 270
Yobibyte YiB 280

所以严格来说如果显示为1MB,则说明使用的是国际单位制标准,等于1000KB。1MiB说明是使用的IEC 60027-2标准,等于1024KiB。

  • 但是注意,Microsoft Windows系统中仍在大量使用公制前缀的二进制写法(比如显示为1MB的文件,按理说应该是使用的SI标准,等于1000KB,但是实际windows却按IEC 60027-2标准来处理的,实际文件大小是1024KB)。
  • Mac OS X自Snow Leopard(v10.6)发行以来,文件大小均是以十进制前缀记录的(比如显示为14KB,87.1MB)。(但是在shell环境里,部分软件使用的M,K等标识符表示1024进制,比如ls;但是df命令使用的是Gi,Mi等SI单位制的符号)

 

References:

https://zh.wikipedia.org/wiki/国际单位制

https://zh.wikipedia.org/wiki/千字节

聊聊固态硬盘(SSD)的接口和协议

固态硬盘固态驱动器(英语:Solid-state drive或Solid-state disk,简称SSD)是一种以集成电路制作的电脑存储设备。

最近如果你要买SSD,可能会频繁接触到M.2,NVMe,PCIe这几个名词。我上一次单独买SSD时,虽然已经是M.2接口了,但是当时没见NVMe协议,最近正好关心了SSD,就正好接机学习了解下。

  1. 接口:M.2是一种接口规范,与之类似的有U.2SATA接口mSATA接口,SATA Express接口,PCIe接口等。
    注意:SATA同时也是一种系统总线的名称,所以要区别SATA接口和SATA总线。SATA Express协议使用的接口是由两个传统的SATA样式的接口和一个小接口组成,因此也能当作两个SATA来用。
  2. 逻辑设备接口规范NVMe(NVM Express,或者Non-Volatile Memory Host Controller Interface Specification (NVMHCIS),AHCI(Advanced Host Controller Interface)
  3. 总线: SATA,SATA Express,PCI,PCI Express(PCIe)

 

下面这个短视频有很生动的介绍:

https://www.youtube.com/watch?v=alb6-zp52mA&t=505s

NVM Express(缩写NVMe),或称非易失性内存主机控制器接口规范(英语:Non-Volatile Memory Host Controller Interface Specification,缩写:NVMHCIS),是一个逻辑设备接口规范。它是基于设备逻辑接口的总线传输协议规范(相当于通讯协议中的应用层),用于访问通过PCI Express(PCIe)总线附加的非易失性存储器介质(例如采用闪存固态硬盘驱动器),虽然理论上不一定要求PCIe总线协议。NVMe是一种协议,是一组允许SSD使用PCIe总线的软硬件标准;而PCIe是实际的物理连接通道。

所以当下性能最佳的SSD的技术方案组合应该是:M.2接口+NVMe+PCIe。早些年在NVMe普及之前,有M.2接口+AHCI+SATA的SSD。SATA接口+AHCI+SATA总线的SSD也有,估计都是没有M.2接口的老电脑升级用吧,现在京东上都还有卖的。

 

References:

https://zh.wikipedia.org/wiki/PCI_Express

https://zh.wikipedia.org/wiki/SATA

https://zh.wikipedia.org/wiki/SATA_Express

       (SFFWG Renames PCIe SSD SFF-8639 Connector To U.2)

https://zh.wikipedia.org/wiki/NVM_Express

https://zh.wikipedia.org/wiki/M.2

 

 

《中国近代史》读书笔记

《中国近代史》——蒋廷黻(著)

最后更新时间:2021-01-06

黻(

  1. 古代礼服上黑与青相间的花纹:黼~。
  2. 同“韨”。

琦善

琦(qí)

  1. 美玉。
  2. 珍奇,美好:~玮(奇丽的意思)。瑰意~行。

马戛尔尼(乔治·马戛尔尼,George Macartney)

戛(jiá)

  1. 长矛。
  2. 敲,敲打。
  3. 常礼;常法。
  4. 刮。
  5. 象声词:~然长鸣。

恭亲王奕(yì)䜣(xīn)

郭嵩焘(guo song tao)

伊里布和耆英

耆(qí)

  1. 年老,六十岁以上的人:~老。~年。~绅。~宿(sù)(指在社会上有名望的老年人)。
  2. 强横。

 

端王载漪子溥(pǔ)隽(jùn)

漪(yī)

水波纹:~沦。~澜。清~。涟~(细小的波纹)。

隽(jùn)

古同“俊”。

 

《中国近代史》是蒋廷黻所著的,于1938年首次出版的中国近代史研究的重要著作。他作为一个“知外交”的学者和政客,从外交的角度讲述中国近代史以及从外交的角度分析近代历史事件发生的原因,背景。

在讲述鸦片战争爆发前后清政府(实际更多是地方官员自主决定)与英国(商人、政府代表)交涉的过程中,通过史料讲述了清政府官员对外的极其无知,从上到下不了解外面的世界,不愿意给外国平等交往的机会;在交涉的过程中,又极其自大,不守诚信,不主动了解敌人情况,很多事情都凭道听途说和意淫。战争失败后,不能接受失败思检讨问题,认清差距,反而对外争执一些无关紧要的内容,对关于主权的事情放任英国制定规则(当然作者也知道,我们是以后来着的角度来看待这个问题,觉得痛心棘手,当时人并不觉得)。

协定关税和治外法权是我们近些年所认为不平等条约的核心,可是当时的人却并不这样看治外法权,在道光时代的人的目光中,不过是“让夷人管夷人”。他们想那是最方便、最省事的办法。至于协定关税,他们觉得也是方便省事的办法。每种货物应该纳多少税都明白地载于条约,那就可以省去争执。负责交涉条约的人如伊里布、耆英、黄恩彤诸人知道战前广东地方官吏的苛捐杂税是引起战争原因之一,现在把收税标准明文规定岂不是一个釜底抽薪,一劳永逸的办法?而且,新的收税标准平均到5%,比旧日的自主关税还要略微高一点。负交涉责任者计算以后的海关收入比以前还要多,所以他们洋洋得意,以为他们的外交是成功的。其实,他们牺牲了国家的主权,贻害不少。总而言之,道光年间的中国人完全不懂国际公法和国际形势,所以他们争所不应争的,放弃所不应放弃的。

想起了书中关于海关税收的内容了。在下篇“外交策略不进反退“一节中,作者认为在康熙中后期的外交是积极的,对外平等的(在涉及和俄国签订尼布楚条约的章节有讲到)。之后的时间里基本都是开倒车。关于税收税率和规则有一段很深刻的描述:

清政府正式设海关监督,规定粤海关由内务府派,闽海关由福州将军兼,浙海关及江海关的由各省巡抚兼。按法律,中国旧关税制度完备极了、公道极了。康熙的训谕说:“各省关钞之设,原期通商利民以资国用”;“国家设关榷税,必征输无弊,出入有经,庶百物流通,民生饶裕”。世宗的旨趣相同:“国家之设关税,所以通商而非累商,所以便民而非病民也。”乾隆也说过:“朕思商民皆为赤子,轻徭薄赋,俾人民实沾惠泽,乃朕爱养黎庶之本怀。”户部颁有税则,其平均率不到百分之五,比《南京条约》以后的协定税则还要低廉。

……

很明显的,中国自十七世纪末年起,已有了法定的、公开的海关税则。

实际上,中国海关收税的情形不但离高尚道德甚远,且与法律绝不相符。直到鸦片战争,外商不知中国的税则的模样。历康雍乾嘉四朝,外人索看海关税则多次,每次概被衙门拒绝。关税分两种:船钞与货税。照户部的章程,船钞应丈量船的大小而定:大船约纳一千二百两,中船约九百六十两,小船约五百四十两。实际除船钞外,还须“官礼”。在十七世纪末年,官礼的多少,每次须讲价。到康熙末年,十八世纪初年,官礼渐成固定:不问船的大小,概须送一千九百五十两,比正钞还多。货税也有正税及“陋规”。陋规最初也是由收税者及纳税者临时去商议,到康熙末年,大约已达货价百分之六,比正税亦大。雍正初年,杨文乾以巡抚兼关监督的时候,官礼报部归公,于是官吏在货税上加了百分之十的陋规,名曰“缴送”。正税及各种陋规总起来约当百分之二十,这是中国实行的税则。

在讲曾国藩时,作者认为,曾国藩技术革新和思想守旧两条路一起走,在对抗太平天国过程中起到重要作用。但是对于一个国家、民族振兴而言是远远不够的,是必然会失败的。作者认为失败原因两点:曾国藩为代表的改革派本身由于成长经历,思想素质等原因不愿因全面改革(比如不赞同政体改革,……);另外一点就是反对者总舵,阻力太大。

作者虽然“知外交”,但却不是鼓吹外交决定一切的人。书里,作者有一句特别让我感慨:“在近代世界,败仗是千万不能打的。”。所以作者在讲到中日在朝鲜的争端时有说到:“近代战争固不是儿戏。不战而求和当然要吃亏……但战败以后而求和,吃亏之大远过于不战而和。”

总体而言我觉得这本书还是蛮好的。对于1840~1912年间,几个大事件和时人为之努力(改革)的分析很精彩。

 

 

名句摘录:

中西的关系是特别的。在鸦片战争以前,清政府不肯给外国平等待遇;在以后,西方国家不肯给清政府平等待遇。

 

在维持清政府作为政治中心的大前提之下,曾国藩的工作分两方面进行。一方面他要革新,那就是说,他要接受西洋文化的一部分;另一方面他要守旧,那就是说,恢复中国固有的美德。革新守旧同时举行,这是曾国藩对中国近代史的大贡献。

 

曾国藩及其他自强运动的领袖虽然走的路线不错,然而他们不能救国救民族。此其故何在?在于他们的不彻底。他们为什么不彻底呢?一部分因为他们自己不要彻底,大部分因为时代不容许他们彻底。我们试先研究领袖们的短处。

恭亲王奕、文祥、曾国藩、李鸿章、左宗棠这五个大领袖都出身于旧社会,受的都是旧教育。他们没有一个人能读外国书,除李鸿章以外,没有一个人到过外国。就是李鸿章的出洋尚在甲午战败以后,他的建设事业已经过去了。这种人能毅然决然推行新事业就了不得,他们不能完全了解西洋文化是自然的,很可原谅的。他们对于西洋的机械是十分佩服的,十分努力要接受的。他们对于西洋的科学也相当尊重,并且知道科学是机械的基础。但是,他们自己毫无专业的机械常识,此外更不必说了。他们觉得中国的政治制度及立国精神是至善至美,无须学西方的。事实上他们的建设事业就遭了旧的制度和旧的精神文化的阻碍。

 

总之,资本主义可变为帝国主义,也可以不变为帝国主义。未开发的国家容易受资本主义的国家的压迫和侵略,也可以利用外国的资本来开发自己的富源及利用国际的通商来提高人民的生活程度。资本主义如同水一样:水可以资灌溉,可以便利交通,也可以成灾,要看人怎样对付。

同时我们不要把帝国主义看得过于简单,以为世界上没有资本主义就没有帝国主义了。…… 据我们所知,历史上各种政体,君主也好,民主也好,各种社会经济制度,资本主义也好,封建主义也好,共产主义也好,都有行帝国主义的可能。

 

在近代世界,败仗是千万不能打的。

 

我们不要以为顽固分子不爱国,从鸦片战争起,他们是一贯的反对屈服,坚强的主张抗战。

 

近代战争固不是儿戏。不战而求和当然要吃亏……但战败以后而求和,吃亏之大远过于不战而和。

 

马戛尔尼的外交失败是由于中西方邦交观念之不相容。中国抱定“天朝统驭万国”的观念,不承认有所谓“国际”者存在;西方在近代则步步地推演出国际生活及其所需的惯例和公法。马戛尔尼的失败证明中国绝不愿意自动或和平地放弃这种传统观念。因此中国外交史有一大特点:除康熙亲政初年外,中外曾无平等邦交的日子。在鸦片战争以前,中国居上,外国居下;鸦片战争以后则相反。

 

 

 

Unix Timestamp(Unix时间戳)

UNIX时间,或称POSIX时间是UNIX或类UNIX系统使用的时间表示方式:从UTC 1970年1月1日0时0分0秒起至现在的总秒数,不考虑闰秒。在多数Unix系统上Unix时间可以透过date +%s指令来检查。(Unix time (also known as Epoch timePOSIX timeseconds since the Epoch, or UNIX Epoch time) is a system for describing a point in time. It is the number of seconds that have elapsed since the Unix epoch.) (英 [ˈiːpɒk]   美 [ˈepək])

从这个解释可以看出来,同一时刻,在全世界任一时区,获取的Unix时间戳是相同的。

所以,针对PHP而言,time()函数获取的到时间戳与时区无关。

time ( ) : int

Returns the current time measured in the number of seconds since the Unix Epoch (January 1 1970 00:00:00 GMT).

那么,进一步延伸,对于一个给定的日期时间字符串,例如:2020-01-01 00:00:00,那么获取这个日期时间对应的时间戳就是与时区有关的。因为不同时区下的2020-01-01 00:00:00距离UTC的1970-01-01 00:00:00的时间间隔是不一样的。

strtotime ( string $datetime [, int $now = time() ] ) : int

对于PHP而言,在使用strtotime函数时,如果日期时间字符串中没有包含时区信息,那么会使用默认的时区date_default_timezone_get()。(Each parameter of this function uses the default time zone unless a time zone is specified in that parameter. Be careful not to use different time zones in each parameter unless that is intended. )

$dateStr = '2020-01-01 00:00:00';

$timezone = 'Asia/Shanghai';
date_default_timezone_set($timezone);
echo sprintf("%13s)%25s ==> %s\n", $timezone, $dateStr, strtotime($dateStr));

$dateStrWithTimezone = '2020-01-01T00:00:00+08:00';
date_default_timezone_set($timezone);//优先读取日期时间字符串里的时区信息,此处单独设置的时区对下一行的strtotime无效
echo sprintf("%13s)%25s ==> %s\n", $timezone, $dateStrWithTimezone, strtotime($dateStrWithTimezone));

$timezone = 'UTC';
date_default_timezone_set($timezone);
echo sprintf("%13s)%25s ==> %s\n", $timezone, $dateStr, strtotime($dateStr));
echo sprintf("%13s)%25s ==> %s\n", $timezone, $dateStrWithTimezone, strtotime($dateStrWithTimezone));

output:
Asia/Shanghai)2020-01-01 00:00:00 ==> 1577808000
Asia/Shanghai)2020-01-01T00:00:00+08:00 ==> 1577808000
UTC)2020-01-01 00:00:00 ==> 1577836800
UTC)2020-01-01T00:00:00+08:00 ==> 1577808000 //优先读取日期时间字符串里的时区信息,runtime设置的时区对strtotime无效

 

date ( string $format [, int $timestamp = time() ] ) : string

Format a local time/date

同样的道理,同一个时间戳在不同的时区下,对应的日期时间字符串是不一样的。

date_default_timezone_set('UTC');
$timestamp = 1577836800;//UTC 2020-01-01 00:00:00
$sourceDatetime = new \DateTime(date('Y-m-d H:i:s', $timestamp));
echo sprintf("source datetime:%s(%s)\n", $sourceDatetime->format('Y-m-d H:i:s'), $sourceDatetime->getTimezone()->getName());

$timezone = 'Asia/Shanghai';
$targetDatetime = (new \DateTime(date('Y-m-d H:i:s', $timestamp)))
    ->setTimezone(new \DateTimeZone($timezone));
echo sprintf("target datetime:%s(%s)\n", $targetDatetime->format('Y-m-d H:i:s'), $targetDatetime->getTimezone()->getName());

output:
source datetime:2020-01-01 00:00:00(UTC)
target datetime:2020-01-01 08:00:00(Asia/Shanghai)

 

References:

https://zh.wikipedia.org/wiki/UNIX时间

记录cp命令在GNU/Linux和BSD(MacOS)下表现不一致的一个行为

最后更新时间:2021-04-22

重现步骤如下:

现有的目录结构:

├── source

│   └── source.txt

├── target

 

cp -r source target1   //target1 dir not exists

GUN/BSD
├── source

│   └── source.txt

├── target

└── target1

└── source.txt

 

cp -r source target   //target dir exists

GUN/Linux BSD(MacOS)
├── source

│   └── source.txt

├── target

└── source

└── source.txt

├── source

│   └── source.txt

├── target

│   └── source.txt

测试环境:

GNU coreutils 8.22(CentOS)

GNU coreutils 8.30(Ubuntu 20.04)

BSD macOS Catalina 10.15.7

 

总结/Summary:

使用cp -r source target 复制目录时,如果目标目录不存在,则GUN/Linux&BSD(mac OS)的cp行为一致;如果目录已经存在,则BSD(mac OS)下会和目标目录不存在时行为一致,但是GUN的cp会创建在目标目录下创建子目录。

 

PS:

如果目标目录已经存在,可以使用 cp -r source/.  target (GUN/Linux下target目录存在or不存在都支持,BSD(mac OS)下target目录存在or不存在都支持) or   cp -r source/* target(仅适用于GUN/Linux下target目录存在的情况,BSD(mac OS)下语法错误)

所以简单起见:直接使用cp -r source/.  target。GUN/Linux和BSD(mac OS)都支持,并且target目录存不存在都支持。

 

Console and TTY and PTY

Console:

在早期的电脑上,往往具有带有大量开关和指示灯的面板,可以对电脑进行一些底层的操作,这个面板就叫做Console。其概念来自于管风琴的控制台。一台电脑通常只能有一个Console,很多时候是电脑主机的一部分,和CPU共享一个机柜。

 

Terminal and TTY(终端):

一台大型主机往往需要支持许多用户同时使用,每个用户所使用操作的设备,就叫做Terminal——终端,终端使用通信电缆与电脑主机连接,甚至可以通过电信网络(电话、电报线路等等)连接另一个城市的电脑。

TTY是电传打字机Teletypewriter的缩写,TTY曾经是最流行的终端设备。现在大多数场景TTY基本就是表示terminal。

Linux有7个TTY?
从控制台切换到 X 窗口,一般采用Ctrl+Alt+F7 ,为什么呢?因为系统默认定义了6个虚拟控制台(Ctrl+Alt+F1 ~ F6), 7个用于x-windows实际上,很多人一般不会需要这么多虚拟控制台的,关闭多余的控制台减少对系统资源的占用,可以自己更改配置文件减少它的数量(在支持systemd的系统里,配置文件位置:/etc/systemd/logind.conf, https://freedesktop.org/software/systemd/man/logind.conf.html,所以具体系统开启了多少个tty,要看配置文件,可能各个发行版本不一样,比如Ubuntu18.04/20.04就是默认6个,而且默认是把tty1留给了x-windows(Ctrl+Alt+F1))。

 

PTY(Pseudo TerminalPseudo TTY, or PTY, 虚拟终端/伪终端):

pts/ptmx(pts/ptmx结合使用,进而实现pty)

所谓伪终端是逻辑上的终端设备,多用于模拟终端程序。例如,我们在X Window下打开的终端,以及我们在Windows使用telnet 或ssh等方式登录Linux主机,此时均在使用pty设备(准确的说在使用pty从设备)

 

echo test > /dev/tty1会把单词test发送到连接在tty1的设备上。

1、/dev/pts0, /dev/pts1, …

2、/dev/tty0, …

3、/dev/console 表示物理终端(控制台)

4、/dev/ttyS0, …  表示串行终端

tty命令可以查看当前登录的终端类型,比如/dev/tty2,/dev/pts/0

Go to WebAssembly

什么是WebAssembly?

WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable target for compilation of high-level languages like C/C++/Rust, enabling deployment on the web for client and server applications.

让我们用tinygo来写一个WebAssembly的模块,然后用js调用吧。首先下载TINYGO:(https://tinygo.org/,请下载对应版本的二进制文件)。然后将bin/tinygo(or tinygo.exe)加入到PATH路径。

然后先创建一个main.go文件(文件名必须是main.go,因为js里有用到文件名),文件内容如下:

package main

// This calls a JS function from Go.
func main() {
    println("Go: Hello World") // expecting 5
    println("Go: add(2+3):", add(2, 3)) // expecting 5
    println("Go: multiply(2*3):", multiply(2, 3)) // expecting 6
}

// This function is imported from JavaScript, as it doesn't define a body.
// You should define a function named 'main.add' in the WebAssembly 'env'
// module from JavaScript.
func add(x, y int) int

// This function is exported to JavaScript, so can be called using
// exports.multiply() in JavaScript.
//go:export multiply
func multiply(x, y int) int {
    return x * y;
}

然后用tinygo编译这个go文件,生成wasm文件。

目前最新版的tinygo0.12.0,最高只支持golang 1.13(目前最新版本的golang1.14),编译的命令中文件名必须是main.go,不能写”./main.go”

tinygo build -o wasm.wasm -target wasm main.go

Error:  tinygo build -o wasm.wasm -target wasm ./main.go

 

然后用go写一个简单的文件服务器(用于启动http服务器,因为wasm加载必须在http/https的环境下),注意对于wasm文件,要设置Content-Type为application/wasm

package main

import (
    "log"
    "net/http"
    "strings"
)

const dir = "./html"

func main() {
    fs := http.FileServer(http.Dir(dir))
    log.Print("Serving " + dir + " on http://localhost:8080")
    http.ListenAndServe(":8080", http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
        resp.Header().Add("Cache-Control", "no-cache")
        if strings.HasSuffix(req.URL.Path, ".wasm") {
            resp.Header().Set("Content-Type", "application/wasm")
        }
        fs.ServeHTTP(resp, req)
    }))}

然后在服务器目录下创建html目录,目录里新建index.html文件(注意js代码中设置env的代码):

<html>
<head>
    <title>WebAssembly</title>
</head>
<body>
<script src="wasm_exec.js"></script>
<script type="text/javascript">
    const go = new Go(); // Defined in wasm_exec.js
    const WASM_URL = 'wasm.wasm';
    go.importObject.env['main.go.add'] = function (x, y) {
        return x + y
    };
    var wasm;

    console.log("'instantiateStreaming' in WebAssembly => " + ('instantiateStreaming' in WebAssembly ? "Y" : "N"));
    if ('instantiateStreaming' in WebAssembly) {
        WebAssembly.instantiateStreaming(fetch(WASM_URL), go.importObject).then(function (obj) {
            wasm = obj.instance;
            go.run(wasm);
            console.log('JS: multiplied two numbers:', wasm.exports.multiply(5, 3));
        }).catch((err) => {
            console.error(err);
        });
    } else {
        fetch(WASM_URL).then(resp =>
            resp.arrayBuffer()
        ).then(bytes =>
            WebAssembly.instantiate(bytes, go.importObject).then(function (obj) {
                wasm = obj.instance;
                go.run(wasm);
            })
        )
    }

</script>
</body>
</html>

index.html里面引用的wasm_exec.js文件就在tinygo下载包里,wasm.wasm就是我们刚刚编译生成的文件。

浏览器里打开这个网页 http://localhost:8080/index.html,发现控制台就能输出:

23:25:58.955 ‘instantiateStreaming’ in WebAssembly => Y

23:25:58.964 Go: Hello World

23:25:58.964 Go: add(2+3): 5

23:25:58.964 Go: multiply(2*3): 6

23:25:58.964 JS: multiplied two numbers: 15

23:25:58.966 Fetch finished loading: GET “http://localhost:8080/wasm.wasm”.

References:

https://webassembly.org/

https://tinygo.org/

 

《带着爸爸去留学》观影感言

时光如梭,一看,上一篇的读书笔记已是一年之前的了。过去一年忙于生存,少有闲暇和心情看书/剧、思考,鼠年加油!

想来看这部电视剧,是因为在网上看到一个片段: 董美玲(黄小栋他妈)请求黄成栋不要再说了(真相),请他消消气,要发火就对她发火,然后他们在餐馆点菜,黄成栋点了一桌绿色菜。

本着吃瓜群众的好奇(八卦)心态,在这个春节假期就看了这部剧。

前面几集感觉就是:毁三观。感觉几个小孩都欠揍。之前家庭里都太惯着他们,让他们没有培养独立处理事情的能力,本剧是借着留学来说这些事情,在我看来即使不留学,在国内他们也会做出一些类似的奇葩事情来。不过结局我觉得倒是不错,虽然过程曲折,孩子们受过了不少伤,但是孩子们都成长了,开始能够成熟的面对生活中遇到的事情。

看了这部剧,更坚定了我的看法:夫妻关系才是一个家庭的第一位,尤其不能将对小孩的爱凌驾于夫妻关系之上。夫妻相互扶持,对待小孩要爱护,但是也要适当放手,要培养他们独立的生活能力。要知道将来陪TA过完一生的肯定不是父母,TA只有知道如何独立,如何对待亲人、朋友、另一半(如果有),他可能有幸福的生活。总结起来就是:父母爱子女则为之计深远。

爱就是克制。

PHP中foreach循环时使用引用的一个坑

记录一个广为流传的关于使用PHP引用的坑。

$arr = ['abc', 'ben', 'cam', 'day'];
foreach($arr as $key=>&$val){
    $val = strtoupper($val);
}
foreach($arr as $val){
    echo "$val\n";
    print_r($arr);

}
echo "===END===\n";
print_r($arr);

解释:

//第二次使用$val做foreach循环时,此时$val还是保持着对$arr数组里的最后一个元素($arr[3])的引用。
//所以对于这个foreach,
//1st ==> $arr[3]=’abc’
//2nd ==> $arr[3] = ‘ben’
//3rd ==> $arr[3] = ‘cam’
//4th ==> $arr[3] = ‘day’

所以正确的做法是在使用引用的foreach结束后马上unset($val)
或者干脆不用使用引用,foreach时使用$key=>$val格式,然后使用$arr[$key]方式修改变量并保存。

Wall Clock and Monotonic Clock

Wall clock(time) VS Monotonic clock(time)

Wall clock(time)就是我们一般意义上的时间,就像墙上钟所指示的时间。

Monotonic clock(time)字面意思是单调时间,实际上它指的是从某个点开始后(比如系统启动以后)流逝的时间,jiffies一定是单调递增的!

而特别要强调的是计算两个时间点的差值一定要用Monotonic clock(time),因为Wall clock(time)是可以被修改的,比如计算机时间被回拨(比如校准或者人工回拨等情况),或者闰秒( leap second),会导致两个wall clock(time)可能出现负数。(因为操作系统或者上层应用不一定完全支持闰秒,出现闰秒后系统时间会在后续某个点会调整为正确值,就有可能出现时钟回拨(当然也不是一定,比如ntpdate就有可能出现时钟回拨,但是ntpd就不会))

 

PHP 7.3新增了hrtime函数

hrtime ([ bool $get_as_number = FALSE ] ) : mixed

Returns the system’s high resolution time, counted from an arbitrary point in time. The delivered timestamp is monotonic and can not be adjusted.

<?php


while(true){
    var_dump(time());
//    $micro = microtime(true);
//    var_dump($micro);
//    echo PHP_EOL;

    //var_dump(hrtime());
    $nanosecond = hrtime(true);
    var_dump($nanosecond/1000/1000/1000);//nanosecond => second
    echo PHP_EOL;
    echo PHP_EOL;
    echo PHP_EOL;
    echo PHP_EOL;

    sleep(5);
}

执行此脚本,然后在过程中手动更改系统时间。执行结果如下

 

……

int(1554975423)

float(481987.58385405)

 

int(1554975428)

float(481992.58812)

 

int(1554975433)    ==>    北京时间:2019/4/11 17:37:13

float(481997.59318082)

 

int(1554889031)   ==>      北京时间:2019/4/10 17:37:11

float(482002.59569814)

 

int(1554889036)

float(482007.59825222)

……

 

hrtime()的返回值就是一直单调递增的,而time()的返回值就可能出现跳跃。所以在计算时间差时要用hrtime(),注意PHP版本至少要7.3 。