什么是职场PUA?

回复

常识zkbhj 回复了问题 • 1 人关注 • 1 个回复 • 207 次浏览 • 2020-08-28 10:02 • 来自相关话题

黑天鹅和灰犀牛是什么意思?

回复

常识zkbhj 回复了问题 • 1 人关注 • 1 个回复 • 197 次浏览 • 2020-08-27 20:42 • 来自相关话题

我的阅读分享:《挪威的森林》

读后感zkbhj 发表了文章 • 0 个评论 • 135 次浏览 • 2020-08-23 15:50 • 来自相关话题

阅读书目:《挪威的森林》
作者:[日]村上春树 著
书籍类型:青春爱情小说
页数:385页
阅读开始时间:2020年8月15日
阅读结束时间:2020年8月23日15:15:21
如何发现这本书:京东热销书单
阅读次数:第1次
阅读类型:精读
推荐等级:★★★★★
阅读建议:最强烈的感受就是:早该读村上春树的这本《挪威的森林》,如果高中时代的我度过了这本书,也许又是另外一个更加精彩的青春时代。
青春就是用身体去感受这个世界,聆听身体和内心最真实的声音和感受,也只有那个时候,才会有那种纯真,不掺杂任何复杂因素的情感。友情和爱情,应该是青春时期所有人的主旋律,贯穿前后,不一而足。可能我们没有经历想主人公渡边一样复杂的关系,但肯定所有人,无论男女,都经历过青春的迷惘,懵懂,憧憬,勇敢,和无畏,体验之后,才觉人生完整,青春不悔。
也许有些观点不敢苟同,但是那就是青春,不一样的烟火,不用成年人的观点去衡量,因为根本不配,和那种美好相提并论。

豆瓣地址:https://book.douban.com/subject/27200257/






  查看全部


阅读书目:《挪威的森林》
作者:[日]村上春树 著
书籍类型:青春爱情小说
页数:385页
阅读开始时间:2020年8月15日
阅读结束时间:2020年8月23日15:15:21
如何发现这本书:京东热销书单
阅读次数:第1次
阅读类型:精读
推荐等级:★★★★★
阅读建议:最强烈的感受就是:早该读村上春树的这本《挪威的森林》,如果高中时代的我度过了这本书,也许又是另外一个更加精彩的青春时代。
青春就是用身体去感受这个世界,聆听身体和内心最真实的声音和感受,也只有那个时候,才会有那种纯真,不掺杂任何复杂因素的情感。友情和爱情,应该是青春时期所有人的主旋律,贯穿前后,不一而足。可能我们没有经历想主人公渡边一样复杂的关系,但肯定所有人,无论男女,都经历过青春的迷惘,懵懂,憧憬,勇敢,和无畏,体验之后,才觉人生完整,青春不悔。
也许有些观点不敢苟同,但是那就是青春,不一样的烟火,不用成年人的观点去衡量,因为根本不配,和那种美好相提并论。

豆瓣地址:https://book.douban.com/subject/27200257/



5a73fad7N67f784ef.jpg

 

商品名称上有的标R有的标TM,有什么区别?

回复

常识zkbhj 回复了问题 • 1 人关注 • 1 个回复 • 183 次浏览 • 2020-08-18 09:58 • 来自相关话题

我的阅读分享:《长夜难明》

读后感zkbhj 发表了文章 • 0 个评论 • 151 次浏览 • 2020-08-14 19:28 • 来自相关话题

阅读书目:《长夜难明》
作者:紫金陈 著
书籍类型:推理小说
页数:288页
阅读开始时间:2020年8月2日
阅读结束时间:2020年8月14日13:23:21
如何发现这本书:京东热销书单
阅读次数:第1次
阅读类型:精读
推荐等级:★★★★
阅读建议:个人感觉还不错,推理角度的话并没有太过烧脑的剧情和逻辑,但是整部小说的情景设置和人物刻画还是可以的,表现的社会问题也很尖锐和突出。期待即将上映的根据这本小说改编的电视剧《沉默的真相》,由廖凡主演。
豆瓣地址:https://book.douban.com/subject/26923390/






  查看全部


阅读书目:《长夜难明》
作者:紫金陈 著
书籍类型:推理小说
页数:288页
阅读开始时间:2020年8月2日
阅读结束时间:2020年8月14日13:23:21
如何发现这本书:京东热销书单
阅读次数:第1次
阅读类型:精读
推荐等级:★★★★
阅读建议:个人感觉还不错,推理角度的话并没有太过烧脑的剧情和逻辑,但是整部小说的情景设置和人物刻画还是可以的,表现的社会问题也很尖锐和突出。期待即将上映的根据这本小说改编的电视剧《沉默的真相》,由廖凡主演。
豆瓣地址:https://book.douban.com/subject/26923390/



1e8c9bf8dda1776a.jpg

 

#面试题集锦#实现单链表反转

面试zkbhj 发表了文章 • 0 个评论 • 150 次浏览 • 2020-08-14 17:16 • 来自相关话题

反转一个链表

示例:输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
结构体定义struct ListNode {
int val;
struct ListNode *next;
};
 





 思路一

先对原链表做头删操作,再对新链表做头插
定义一个新head头指针,标记为newHead,将它初始为NULL,并非指向NULL,最后我们选择返回这个newHead指针作为新链表的头指针。
定义一个结点node作为"临时中转站",初始化与否并无大影响。进行循环遍历链表各个结点,判定head指针是否为空,即是否到达了原链表的结尾。如果不为空,说明还没有到达尾部。如果程序第一次运行就没有进入循环,说明传入了一个空链表,此时返回newHead新链表的头指针,同样返回NULL,这样处理也是合理的。以下开始逆序链表逻辑:在当前指针不为NULL时,先对原链表做头删操作,再对新链表做头插操作。即使用循环进行操作:让node指针指向传入函数链表的头指针head,两指针指向保持相同。然后让head指针指向它的next结点,此时旧链表已经完成了头删操作。第一个结点已经被"切割"下来。接下来要做的就是对新链表进行头插操作,使结点放入新链表。让node指针的next下一个结点指向新链表的头指针newHead,完成结点的链接,即头插入新的链表中。然后更新newHead指向为新链表的头结点。进行下一次循环。最终head指针指向了原链表的结尾,即为NULL,退出循环,此时新链表已经反转完毕,情况如图:最终返回新链表头指针newHead即可。





 struct ListNode *reverseList(struct ListNode* head) {
struct ListNode *newHead = NULL;
struct ListNode *node;
while (head != NULL) {
//1. 对之前的链表做头删
node = head;
head = head->next;

//2. 对新链表做头插
node->next = newHead;
newHead = node;
}
return newHead;
}
思路二





利用选择语句,找到空链表的情况,此情况返回NULL空指针,因为空链表不能反转,或者说反转之后还是一个空链表,返回空。利用三个指针p0"前指针"、p1“当前指针”、p2"后指针"来分批处理链表元素,p0置为NULL,它将作为链表的尾结点向前推进处理,p1指向旧链表的头指针head,p2指向旧链表的头指针的next结点。开始遍历链表,循环判定因子为p1,当它为空时到达链表尾部跳出循环。否则在表中执行循环内逻辑:将p1指向的当前结点的下一个结点指向p0,即前一个结点。此时p0为NULL,那么p1的下一个结点就为空了,它现在是最后一个结点。然后将p0指针指向p1,将p1指针指向p2,注意这两步不可以调换顺序,否则正确向后挪移一位。此时完成了三个指针的一轮更迭。判定p2指针是否为空,如果为空说明此时p2到达了链表结尾,当前指针p1的指向为最后一个结点,它的next即为空。如果不为空,将p2更新到下一个结点,进行下一次循环。下一次进行循环时,就会把截断结点链接到新链表的头部,同时更新三个指针。继续循环。循环终止条件为:p1指向了链表尾部的NULL,此时p1的前指针p0即指向了反转后的链表,它就是新链表的head头指针。此时返回p0即可。





 struct ListNode *reverseList(struct ListNode* head) {
if (head == NULL) {
return NULL;
}
struct ListNode *p0 = NULL;
struct ListNode *p1 = head;
struct ListNode *p2 = head->next;
while (p1 != NULL) {
p1->next = p0;

p0 = p1;
p1 = p2;
if (p2 != NULL) {
p2 = p2->next;
}
}
return p0;
}
参考文档:
https://blog.csdn.net/qq_42351880/article/details/88637387
 
  查看全部
反转一个链表

示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL

结构体定义
struct ListNode {
int val;
struct ListNode *next;
};

 

QQ截图20200814170600.jpg

 思路一

先对原链表做头删操作,再对新链表做头插
  1. 定义一个新head头指针,标记为newHead,将它初始为NULL,并非指向NULL,最后我们选择返回这个newHead指针作为新链表的头指针。

  1. 定义一个结点node作为"临时中转站",初始化与否并无大影响。
  2. 进行循环遍历链表各个结点,判定head指针是否为空,即是否到达了原链表的结尾。如果不为空,说明还没有到达尾部。如果程序第一次运行就没有进入循环,说明传入了一个空链表,此时返回newHead新链表的头指针,同样返回NULL,这样处理也是合理的。
  3. 以下开始逆序链表逻辑:在当前指针不为NULL时,先对原链表做头删操作,再对新链表做头插操作。即使用循环进行操作:
  4. 让node指针指向传入函数链表的头指针head,两指针指向保持相同。
  5. 然后让head指针指向它的next结点,此时旧链表已经完成了头删操作。第一个结点已经被"切割"下来。接下来要做的就是对新链表进行头插操作,使结点放入新链表。
  6. 让node指针的next下一个结点指向新链表的头指针newHead,完成结点的链接,即头插入新的链表中。然后更新newHead指向为新链表的头结点。进行下一次循环。
  7. 最终head指针指向了原链表的结尾,即为NULL,退出循环,此时新链表已经反转完毕,情况如图:
  8. 最终返回新链表头指针newHead即可。


QQ截图20200814170610.jpg

 
struct ListNode *reverseList(struct ListNode* head) {
struct ListNode *newHead = NULL;
struct ListNode *node;
while (head != NULL) {
//1. 对之前的链表做头删
node = head;
head = head->next;

//2. 对新链表做头插
node->next = newHead;
newHead = node;
}
return newHead;
}

思路二

QQ截图20200814171211.jpg

  1. 利用选择语句,找到空链表的情况,此情况返回NULL空指针,因为空链表不能反转,或者说反转之后还是一个空链表,返回空。
  2. 利用三个指针p0"前指针"、p1“当前指针”、p2"后指针"来分批处理链表元素,p0置为NULL,它将作为链表的尾结点向前推进处理,p1指向旧链表的头指针head,p2指向旧链表的头指针的next结点。
  3. 开始遍历链表,循环判定因子为p1,当它为空时到达链表尾部跳出循环。否则在表中执行循环内逻辑:将p1指向的当前结点的下一个结点指向p0,即前一个结点。此时p0为NULL,那么p1的下一个结点就为空了,它现在是最后一个结点。
  4. 然后将p0指针指向p1,将p1指针指向p2,注意这两步不可以调换顺序,否则正确向后挪移一位。此时完成了三个指针的一轮更迭。
  5. 判定p2指针是否为空,如果为空说明此时p2到达了链表结尾,当前指针p1的指向为最后一个结点,它的next即为空。如果不为空,将p2更新到下一个结点,进行下一次循环。
  6. 下一次进行循环时,就会把截断结点链接到新链表的头部,同时更新三个指针。继续循环。
  7. 循环终止条件为:p1指向了链表尾部的NULL,此时p1的前指针p0即指向了反转后的链表,它就是新链表的head头指针。此时返回p0即可。


QQ截图20200814171221.jpg

 
struct ListNode *reverseList(struct ListNode* head) {
if (head == NULL) {
return NULL;
}
struct ListNode *p0 = NULL;
struct ListNode *p1 = head;
struct ListNode *p2 = head->next;
while (p1 != NULL) {
p1->next = p0;

p0 = p1;
p1 = p2;
if (p2 != NULL) {
p2 = p2->next;
}
}
return p0;
}

参考文档:
https://blog.csdn.net/qq_42351880/article/details/88637387
 
 

如何给页面增加文字水印?

回复

前端开发zkbhj 回复了问题 • 1 人关注 • 1 个回复 • 327 次浏览 • 2020-08-06 14:31 • 来自相关话题

o'clock是什么的缩写?

常识zkbhj 发表了文章 • 0 个评论 • 173 次浏览 • 2020-08-06 10:40 • 来自相关话题

-What time is it?

-It's 7 o'clock.


o'clock 表示点钟,这个小学英语课堂上就学过的词,想必大家再熟悉不过了吧。

但是,问题来了:o 和 clock 之间用了一个缩写符号 ',那么它究竟省略掉了哪些东西?

故事还要从没有 clock 的那个时代说起。

上古时代的人类,依靠观察日夜交替、季节更迭和星辰变幻的规律,作为游牧、耕作和祭祀等活动的时间依据。后来,智慧的人类发明了日晷(sundial)、沙漏(hourglass)和水钟(water clock,请注意不是水表)等工具,用以衡量一定长度的时间。

当然,我们中国还有「一袋烟的工夫」、「一炷香的工夫」这些体现传统浪漫主义情怀、随性而接地气的时间表达方式……

直到 14 世纪,现代意义上的时钟雏形才得以发明,但因并未迅速普及开来,其他的时间计量工具也同样在并行使用。所以,为了避免与其他计时工具混淆,人们需要特别说明,自己报出的时间读数,是来自时钟的:

It's 7 of the clock.

人嘛,都是有惰性的。16、17世纪,随着时钟的应用越来越广泛,人们开始将 of 的 f 和 the 一带而过,简略地读成了 o'clock.

好了,答案来了:o'clock = of the clock.

而到了 18 世纪,o'clock 的说法才真正变得流行起来。当时,of the 两个词略读成 o' (/ə/) 的方式为大众普遍采用,比如万圣节标志性的南瓜灯 Jack-o'-lantern,即是 Jack of the lantern 的缩写形式。

虽然钟表早已普及,甚至现在逐渐被电子设备所取代,但 o'clock 这种说法早已成为了英语中的一种习惯,并一直沿用至今。

作者:笔戈科技
链接:https://www.jianshu.com/p/95e592319750
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 查看全部


-What time is it?

-It's 7 o'clock.



o'clock 表示点钟,这个小学英语课堂上就学过的词,想必大家再熟悉不过了吧。

但是,问题来了:o 和 clock 之间用了一个缩写符号 ',那么它究竟省略掉了哪些东西?

故事还要从没有 clock 的那个时代说起。

上古时代的人类,依靠观察日夜交替、季节更迭和星辰变幻的规律,作为游牧、耕作和祭祀等活动的时间依据。后来,智慧的人类发明了日晷(sundial)、沙漏(hourglass)和水钟(water clock,请注意不是水表)等工具,用以衡量一定长度的时间。

当然,我们中国还有「一袋烟的工夫」、「一炷香的工夫」这些体现传统浪漫主义情怀、随性而接地气的时间表达方式……

直到 14 世纪,现代意义上的时钟雏形才得以发明,但因并未迅速普及开来,其他的时间计量工具也同样在并行使用。所以,为了避免与其他计时工具混淆,人们需要特别说明,自己报出的时间读数,是来自时钟的:


It's 7 of the clock.


人嘛,都是有惰性的。16、17世纪,随着时钟的应用越来越广泛,人们开始将 of 的 f 和 the 一带而过,简略地读成了 o'clock.

好了,答案来了:o'clock = of the clock.

而到了 18 世纪,o'clock 的说法才真正变得流行起来。当时,of the 两个词略读成 o' (/ə/) 的方式为大众普遍采用,比如万圣节标志性的南瓜灯 Jack-o'-lantern,即是 Jack of the lantern 的缩写形式。

虽然钟表早已普及,甚至现在逐渐被电子设备所取代,但 o'clock 这种说法早已成为了英语中的一种习惯,并一直沿用至今。

作者:笔戈科技
链接:https://www.jianshu.com/p/95e592319750
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

#每日精进#2020年8月6日

总结zkbhj 发表了文章 • 0 个评论 • 157 次浏览 • 2020-08-06 09:31 • 来自相关话题

【早读:《深入理解计算机系统》】

第二章 信息的表示和处理

表示代码int sum(int x, int y) {
return x + y;
}当我们在不同的机器上编译上面的程序得到的机器代码都不尽相同:

Linux32     55 89 e5 8b 45 0c 03 45 08 c9 c3
Windows  55 89 e5 8b 45 0c 03 45 08 5d c3
Sun           81 c3 e0 08 90 03 00 09


因此,二进制代码是不兼容的,无法在不同机器之间移植。

这得到一个计算机系统的基本概念:从机器的角度来看,程序仅仅只是字节序列,机器没有关于原始程序的任何信息。

布尔代数简介

计算机的核心都是围绕1和0来演化的。对于0和1的起源,要追溯到1850年前后乔治·布尔的工作,所以这个也叫布尔代数。即通过将逻辑值TRUE和FALSE编码为二进制1和0设计出的一种代数,以研究逻辑推理的基本原则。






上面分别列出了~(NOT)、&(AND)、|(OR)和^(EXCLUSIVE-OR)四种基本运算。

后来创立信息论领域的Claude Shannon首先建立了布尔代数和数字逻辑之间的联系。

将上述基础的布尔运算扩展到位向量运算。位向量就是固定长度为w、由0和1组成的串。

假设 w=4,a=[0110],b=[1100]。那么四种运算 a&b、a|b、a^b、~b 结果分别如下:





 
布尔运算&对|满足分配率:a&(b|c) = (a&b)|(a&c);反过来,|也满足对&的分配率,即:a|(b&c) = (a|b) & (a|c)。

位向量的一个有用应用就是表示有限集合,即用位向量来给集合进行编码。

C语言的一个有用特性就是支持按位布尔运算。|、&、~、^这些运算可以用到任何“整型”的数据类型上。void inplace_swap(int *x, int *y){
*y = *x ^ *y;
*x = *x ^ *y;
*y = *x ^ *y;
}
上面这段代码,就是利用了两个事实来实现*x和*y所指向的变量值进行了交换操作。两个事实分别是:

异或运算是可交换和可结合的;

对于任意的a, a ^ a = 0;

所以上述程序的计算过程如下:

初始:*x = a    *y = b
第一步:*x = a   *y = a ^ b
第二步:*x = a ^ (a ^ b) = (a ^ a) ^ b = b   *y = a ^ b
第三部:*x = b   *y = b ^ ( a ^ b) = (b ^ b) ^ a = a


但是注意,这种方式和通常的交换两个数值的技术不一样,当移动一个值时,我们不需要第三个位置来临时存放另外一个值。这种交换方式并没有性能上的优势,它仅仅是一个智力游戏!

位级运算常见的用法就是实现掩码运算:掩码是一个位模式,表示从一个字中选出的位的集合。

比如对于掩码0xFF(最低的8位都是1)表示一个字的低位字节。x&0xFF会得到一个由x的最低有效字节组成的值。 
 
 
【英文中几点钟的说法o'clock是什么的缩写?】

o'clock = of the clock.

在14世纪以前,人类还没有发明出来时钟,都是通过一些其他途径来获取和感知时间,比如日晷、沙漏等。直到 14 世纪,现代意义上的时钟雏形才得以发明。当时的时钟会自己报时“说出”:It's 7 of the clock!后来,随着时钟的普及和大众化,人们开始将 of 的 f 和 the 一带而过,简略地读成了 o'clock。
 https://ask.zkbhj.com/?/article/370 查看全部

【早读:《深入理解计算机系统》】

第二章 信息的表示和处理

表示代码
int sum(int x, int y) {
return x + y;
}
当我们在不同的机器上编译上面的程序得到的机器代码都不尽相同:


Linux32     55 89 e5 8b 45 0c 03 45 08 c9 c3
Windows  55 89 e5 8b 45 0c 03 45 08 5d c3
Sun           81 c3 e0 08 90 03 00 09



因此,二进制代码是不兼容的,无法在不同机器之间移植。

这得到一个计算机系统的基本概念:从机器的角度来看,程序仅仅只是字节序列,机器没有关于原始程序的任何信息。

布尔代数简介

计算机的核心都是围绕1和0来演化的。对于0和1的起源,要追溯到1850年前后乔治·布尔的工作,所以这个也叫布尔代数。即通过将逻辑值TRUE和FALSE编码为二进制1和0设计出的一种代数,以研究逻辑推理的基本原则。

20200806092721.jpg


上面分别列出了~(NOT)、&(AND)、|(OR)和^(EXCLUSIVE-OR)四种基本运算。

后来创立信息论领域的Claude Shannon首先建立了布尔代数和数字逻辑之间的联系。

将上述基础的布尔运算扩展到位向量运算。位向量就是固定长度为w、由0和1组成的串。

假设 w=4,a=[0110],b=[1100]。那么四种运算 a&b、a|b、a^b、~b 结果分别如下:

20200806092735.jpg

 
布尔运算&对|满足分配率:a&(b|c) = (a&b)|(a&c);反过来,|也满足对&的分配率,即:a|(b&c) = (a|b) & (a|c)。

位向量的一个有用应用就是表示有限集合,即用位向量来给集合进行编码。

C语言的一个有用特性就是支持按位布尔运算。|、&、~、^这些运算可以用到任何“整型”的数据类型上。
void inplace_swap(int *x, int *y){
*y = *x ^ *y;
*x = *x ^ *y;
*y = *x ^ *y;
}

上面这段代码,就是利用了两个事实来实现*x和*y所指向的变量值进行了交换操作。两个事实分别是:

异或运算是可交换和可结合的;

对于任意的a, a ^ a = 0;

所以上述程序的计算过程如下:


初始:*x = a    *y = b
第一步:*x = a   *y = a ^ b
第二步:*x = a ^ (a ^ b) = (a ^ a) ^ b = b   *y = a ^ b
第三部:*x = b   *y = b ^ ( a ^ b) = (b ^ b) ^ a = a



但是注意,这种方式和通常的交换两个数值的技术不一样,当移动一个值时,我们不需要第三个位置来临时存放另外一个值。这种交换方式并没有性能上的优势,它仅仅是一个智力游戏!

位级运算常见的用法就是实现掩码运算:掩码是一个位模式,表示从一个字中选出的位的集合。

比如对于掩码0xFF(最低的8位都是1)表示一个字的低位字节。x&0xFF会得到一个由x的最低有效字节组成的值。 
 
 
英文中几点钟的说法o'clock是什么的缩写?】


o'clock = of the clock.


在14世纪以前,人类还没有发明出来时钟,都是通过一些其他途径来获取和感知时间,比如日晷、沙漏等。直到 14 世纪,现代意义上的时钟雏形才得以发明。当时的时钟会自己报时“说出”:It's 7 of the clock!后来,随着时钟的普及和大众化,人们开始将 of 的 f 和 the 一带而过,简略地读成了 o'clock。
 https://ask.zkbhj.com/?/article/370

#每日精进#2020年8月5日

总结zkbhj 发表了文章 • 0 个评论 • 171 次浏览 • 2020-08-05 11:20 • 来自相关话题

【早读:《深入理解计算机系统》】

第二章 信息的表示和处理

寻址和字节顺序

在几乎所有机器上,多字节对象被存储为连续的字节序列,对象的地址为最小的地址。

排列表示一个对象的字节有两个通用的规则:

小端法:在内存中按照从最低有效字节到最高有效字节的顺序存储对象;
大端法:在内存中按照从最高有效字节到最低有效字节的顺序存储对象;一旦选择了特定的操作系统,那么字节顺序也就固定下来。Android和IOS只能够运行于小端模式下。

两种方式没有谁好谁坏之分,对于那种字节排序的选择都是任意的。
大小端的说法来自于Jonathan Swift的《格利弗游记》一书,其中交战的两个派别无法就打开一个半熟的鸡蛋应该从哪一端打开达成一致意见。
不同的端模式下,会有以下影响:
1、通过网络在不同端模式的机器间传递数据时,发送和接收时,需要转换网络标准;
2、在检查机器级程序时,对数据的解读方式;
3、在编写规避正常的类型系统的程序时。​#include <stdio.h>

typedef unsigned char *byte_pointer;
//typedef char *byte_pointer;

void show_bytes(byte_pointer start, size_t len) {
size_t i;
for (i = 0; i < len; i++)
printf("%p\t0x%.2x\n", &start, start);
printf("\n");
}

void show_int(int x) {
show_bytes((byte_pointer) &x, sizeof(int));
}

void show_float(float x) {
show_bytes((byte_pointer) &x, sizeof(float));
}

void show_pointer(void *x) {
show_bytes((byte_pointer) &x, sizeof(void *));
}

​在这段程序中,“byte_pointer start”告诉编译器,应该把这个指针看成指向一个字节序列,而不是指向一个原始数据类型的对象。然后,这个指针会被看成是对象使用的最低字节地址。
这种强制类型转换不会改变真实的指针,它们只是告诉编译器以新的数据类型来看待被指向的数据。
使用ASCII码作为字符码的任何系统上都是将得到相同的结果,与字节顺序和字节大小规则无关。因而,文本数据比二进制数据具有更强的平台独立性。
 
【HTML页面里怎么实现代码包含?】
https://ask.zkbhj.com/?/question/387
 
【Yii2框架中如何区分不同的场景指定赋值字段和检验规则】
 
场景(scenario)

分析上面问题,会发现关键点是批量赋值(massive assignment)和数据校验(validate)两个方法。如果对不同的场景指定赋值字段和检验规则,问题就迎刃而解。

Yii中的scenario有 安全属性 和 活跃属性 两个概念。安全属性用在批量赋值的load方法,只有安全属性才能被赋值;活跃属性用在规则校验的validate方法,在活跃属性集中并且定义了校验规则的属性才会被校验。活跃属性和安全属性的关系是,安全属性是活跃属性的子集。

\yii\base\Model类定义了默认场景:SCENARIO_DEFAULT(值为default)。默认场景下,出现在rules方法中的属性既是活跃属性,又是安全属性(这句话基本正确,看后续解释)。为不同场景指定活跃属性、安全属性以及校验器,可以通过覆盖senarios或rules两个方法实现(几乎每个Model类都会重写rules方法,senarios用得少)。

rules

先看rules方法。默认的属性加校验器定义方式,让每个属性既是安全属性,也是活跃属性。如果想让某个属性不是安全属性(不能通过load批量赋值),在属性名前加感叹号!即可。例如student中的user_id字段:public function rules()
{
return [
["!user_od", "required"],
["!user_id", "integer"],
["!user_od", "unique"],
// other rules
];
}user_id是活跃属性,在写入数据库时会被校验。但它不是安全属性,不能通过load方法进行赋值,解决了安全隐患。

再看rules方法按场景区分校验器规则的做法:定义校验器时on属性指定规则在哪些场景下生效,except属性则排除一些场景(如果不指定on和except,规则对所有场景生效)。例如:public function rules()
{
return [
["password", "string", "length" => [8, 16], "on" => ["signup"]], // 仅在signup场景时才被验证
["status", "integer", "except" => ["signup"], // 除了signup场景,其他情况都校验
// other rules
];
}在原来基础上新增感叹号和on/except属性,非常简便的就定义了非安全属性以及分场景指定校验规则。

scenarios

另外一种更清晰定义安全属性和活跃属性的做法是重写scenarios方法。scenarios方法返回一个数组,数组的键是场景名称,值是活跃属性集合(包饭安全属性)。例如student表的可能实现如下:public function scenarios()
{
return [
self::SCENARIO_DEFAULT => ["!user_id", "grade", "class", xxxx],
"update" => ["grade", "class", xxxx],
];
}默认情形下(学生报名),年级、班级这些信息是安全属性,但user_id不是,只能在程序内部赋值,并在插入数据时被校验;在修改信息时,user_id不是活跃属性,既不能被批量赋值,也不需要校验(事实上它不应该改变)。

scenarios方法只能定义活跃属性和安全属性,无法定义校验规则,需要和rules配合使用。
https://www.cnblogs.com/yangxunwu1992/p/6669380.html

 
【关于未来几年国内经济形势的分析总结】】
 
疫情发生以来,国内外经济形势发生了重大变化。国际局势也从全球化走向了逆全球化的道路,美国通过各种手段(贸易战、“中国病毒”论、打压华为、打压Tik Tok、关闭领事馆、干涉中国内政等)不断打压中国,各大企业也在不断将企业撤出中国。
 
最近最热门的经济词汇就是经济内循环,意思是说,以后要以国内市场为主,国内生产出来的东西,主要在自己国内消化掉,重新转化为生产力。也就是走内需拉动经济增长的路子。这是在疫情发生以及国内外形式发生如此变化之后的无奈之举。
 
我们过去拉动经济的三驾马车是外贸,基建和房地产,内需一向很薄弱,这几年内需份额有所提高,但还不足以成为拉动经济增长的主要动力。
 
最主要体现在居民收入不足,杠杆过高,中产被绑在房地产的战车上面等。
 
从微观层面看,中国消费结构呈现两边高中间低的M字型结构(健康的结构应该是相反的,两边低中间高,中产成为消费的主力)。所以中国目前的情况就是有钱人并不会受到高房价的影响而降低消费,反而还因此提高了消费能力,还在消费升级。然后相对经济收入低的人群消费能力本就低,地摊经济很火就说明这个问题。中产,由于购房等压力,从中端消费跌落到低端消费。
 
所以,国内要实现以经济内循环为主,国际循环为辅的国内国际双循环的新发展格局,有以下几种办法:
1、提高居民购买力
主要就是降房价和提高居民收入,提高居民收入很难,现在经济太差,没有需求就没有工作岗位,居民收入不下降已经很不错,但房价是有可能缓慢下降的

2、发展房地产。
过去十几年就是这么干的,但现在房价太高,已经到了伤害经济的底部,已经不能继续走拉抬房价发展经济的老路。

3、让股市走出慢牛。
目前看也相对可行,上层也一直在强调要通过资本市场服务实体经济,这也是我一向看好A股走牛的重要原因。
 
4、发展高科技和人民币国际化。
 
讲通俗一点,就是:

经济内循环其实就是要过苦日子的另一个代名词。也可以简单理解为好好干活,但不要想着能挣很多钱。在未来很长一段时间里面,物价会相对比较便宜。

 
https://zhuanlan.zhihu.com/p/165347415
 
【Go语言核心36讲:第12节 使用函数的正确姿势(1)】
 
在 Go 语言中,函数可是一等的(first-class)公民,函数类型也是一等的数据类型(函数类型属于引用类型,它的零值为nil)。
这意味着函数不但可以用于封装代码、分割功能、解耦逻辑,还可以化身为普通的值,在其他函数间传递、赋予变量、做类型判断和转换等。“函数是一等的公民”是函数式编程(functional programming)的重要特征。Go 语言在语言层面支持了函数式编程。

package main

import "fmt"

type Printer func(contents string) (n int, err error)

func printToStd(contents string) (bytesNum int, err error) {
return fmt.Println(contents)
}

func main() {
var p Printer
p = printToStd
p("something")
}函数的签名其实就是函数的参数列表和结果列表的统称,它定义了可用来鉴别不同函数的那些特征,同时也定义了我们与函数交互的方式。

各个参数和结果的名称不能算作函数签名的一部分,对于结果声明,名字也可以没有。且函数的名称也不算函数签名的一部分,只是个标识符而已。

高阶函数
 

1. 接受其他的函数作为参数传入;
2. 把其他的函数作为结果返回。

只要满足了其中任意一个特点,我们就可以说这个函数是一个高阶函数。
 
卫述语句
 
卫述语句是指被用来检查关键的先决条件的合法性,并在检查未通过的情况下立即终止当前代码块执行的语句。在 Go 语言中,if 语句常被作为卫述语句。
if op == nil {
return 0, errors.New("invalid operation")
} 查看全部
【早读:《深入理解计算机系统》】

第二章 信息的表示和处理

寻址和字节顺序

在几乎所有机器上,多字节对象被存储为连续的字节序列,对象的地址为最小的地址。

排列表示一个对象的字节有两个通用的规则:


小端法:在内存中按照从最低有效字节到最高有效字节的顺序存储对象;
大端法:在内存中按照从最高有效字节到最低有效字节的顺序存储对象;一旦选择了特定的操作系统,那么字节顺序也就固定下来。Android和IOS只能够运行于小端模式下。


两种方式没有谁好谁坏之分,对于那种字节排序的选择都是任意的。
大小端的说法来自于Jonathan Swift的《格利弗游记》一书,其中交战的两个派别无法就打开一个半熟的鸡蛋应该从哪一端打开达成一致意见。
不同的端模式下,会有以下影响:
1、通过网络在不同端模式的机器间传递数据时,发送和接收时,需要转换网络标准;
2、在检查机器级程序时,对数据的解读方式;
3、在编写规避正常的类型系统的程序时。
​#include <stdio.h>

typedef unsigned char *byte_pointer;
//typedef char *byte_pointer;

void show_bytes(byte_pointer start, size_t len) {
size_t i;
for (i = 0; i < len; i++)
printf("%p\t0x%.2x\n", &start, start);
printf("\n");
}

void show_int(int x) {
show_bytes((byte_pointer) &x, sizeof(int));
}

void show_float(float x) {
show_bytes((byte_pointer) &x, sizeof(float));
}

void show_pointer(void *x) {
show_bytes((byte_pointer) &x, sizeof(void *));
}

​在这段程序中,“byte_pointer start”告诉编译器,应该把这个指针看成指向一个字节序列,而不是指向一个原始数据类型的对象。然后,这个指针会被看成是对象使用的最低字节地址。
这种强制类型转换不会改变真实的指针,它们只是告诉编译器以新的数据类型来看待被指向的数据。
使用ASCII码作为字符码的任何系统上都是将得到相同的结果,与字节顺序和字节大小规则无关。因而,文本数据比二进制数据具有更强的平台独立性。
 
【HTML页面里怎么实现代码包含?】
https://ask.zkbhj.com/?/question/387
 
【Yii2框架中如何区分不同的场景指定赋值字段和检验规则】
 
场景(scenario)

分析上面问题,会发现关键点是批量赋值(massive assignment)和数据校验(validate)两个方法。如果对不同的场景指定赋值字段和检验规则,问题就迎刃而解。

Yii中的scenario有 安全属性 和 活跃属性 两个概念。安全属性用在批量赋值的load方法,只有安全属性才能被赋值;活跃属性用在规则校验的validate方法,在活跃属性集中并且定义了校验规则的属性才会被校验。活跃属性和安全属性的关系是,安全属性是活跃属性的子集。

\yii\base\Model类定义了默认场景:SCENARIO_DEFAULT(值为default)。默认场景下,出现在rules方法中的属性既是活跃属性,又是安全属性(这句话基本正确,看后续解释)。为不同场景指定活跃属性、安全属性以及校验器,可以通过覆盖senarios或rules两个方法实现(几乎每个Model类都会重写rules方法,senarios用得少)。

rules

先看rules方法。默认的属性加校验器定义方式,让每个属性既是安全属性,也是活跃属性。如果想让某个属性不是安全属性(不能通过load批量赋值),在属性名前加感叹号!即可。例如student中的user_id字段:
public function rules()
{
return [
["!user_od", "required"],
["!user_id", "integer"],
["!user_od", "unique"],
// other rules
];
}
user_id是活跃属性,在写入数据库时会被校验。但它不是安全属性,不能通过load方法进行赋值,解决了安全隐患。

再看rules方法按场景区分校验器规则的做法:定义校验器时on属性指定规则在哪些场景下生效,except属性则排除一些场景(如果不指定on和except,规则对所有场景生效)。例如:
public function rules()
{
return [
["password", "string", "length" => [8, 16], "on" => ["signup"]], // 仅在signup场景时才被验证
["status", "integer", "except" => ["signup"], // 除了signup场景,其他情况都校验
// other rules
];
}
在原来基础上新增感叹号和on/except属性,非常简便的就定义了非安全属性以及分场景指定校验规则。

scenarios

另外一种更清晰定义安全属性和活跃属性的做法是重写scenarios方法。scenarios方法返回一个数组,数组的键是场景名称,值是活跃属性集合(包饭安全属性)。例如student表的可能实现如下:
public function scenarios()
{
return [
self::SCENARIO_DEFAULT => ["!user_id", "grade", "class", xxxx],
"update" => ["grade", "class", xxxx],
];
}
默认情形下(学生报名),年级、班级这些信息是安全属性,但user_id不是,只能在程序内部赋值,并在插入数据时被校验;在修改信息时,user_id不是活跃属性,既不能被批量赋值,也不需要校验(事实上它不应该改变)。

scenarios方法只能定义活跃属性和安全属性,无法定义校验规则,需要和rules配合使用。
https://www.cnblogs.com/yangxunwu1992/p/6669380.html

 
【关于未来几年国内经济形势的分析总结】】
 
疫情发生以来,国内外经济形势发生了重大变化。国际局势也从全球化走向了逆全球化的道路,美国通过各种手段(贸易战、“中国病毒”论、打压华为、打压Tik Tok、关闭领事馆、干涉中国内政等)不断打压中国,各大企业也在不断将企业撤出中国。
 
最近最热门的经济词汇就是经济内循环,意思是说,以后要以国内市场为主,国内生产出来的东西,主要在自己国内消化掉,重新转化为生产力。也就是走内需拉动经济增长的路子。这是在疫情发生以及国内外形式发生如此变化之后的无奈之举。
 
我们过去拉动经济的三驾马车是外贸,基建和房地产,内需一向很薄弱,这几年内需份额有所提高,但还不足以成为拉动经济增长的主要动力。
 
最主要体现在居民收入不足杠杆过高中产被绑在房地产的战车上面等。
 
从微观层面看,中国消费结构呈现两边高中间低的M字型结构(健康的结构应该是相反的,两边低中间高,中产成为消费的主力)。所以中国目前的情况就是有钱人并不会受到高房价的影响而降低消费,反而还因此提高了消费能力,还在消费升级。然后相对经济收入低的人群消费能力本就低,地摊经济很火就说明这个问题。中产,由于购房等压力,从中端消费跌落到低端消费。
 
所以,国内要实现以经济内循环为主,国际循环为辅的国内国际双循环的新发展格局,有以下几种办法:
1、提高居民购买力
主要就是降房价和提高居民收入,提高居民收入很难,现在经济太差,没有需求就没有工作岗位,居民收入不下降已经很不错,但房价是有可能缓慢下降的

2、发展房地产。
过去十几年就是这么干的,但现在房价太高,已经到了伤害经济的底部,已经不能继续走拉抬房价发展经济的老路。

3、让股市走出慢牛。
目前看也相对可行,上层也一直在强调要通过资本市场服务实体经济,这也是我一向看好A股走牛的重要原因。
 
4、发展高科技和人民币国际化。
 
讲通俗一点,就是:


经济内循环其实就是要过苦日子的另一个代名词。也可以简单理解为好好干活,但不要想着能挣很多钱。在未来很长一段时间里面,物价会相对比较便宜。


 
https://zhuanlan.zhihu.com/p/165347415
 
【Go语言核心36讲:第12节 使用函数的正确姿势(1)】
 
在 Go 语言中,函数可是一等的(first-class)公民,函数类型也是一等的数据类型(函数类型属于引用类型,它的零值为nil)。
这意味着函数不但可以用于封装代码、分割功能、解耦逻辑,还可以化身为普通的值,在其他函数间传递、赋予变量、做类型判断和转换等。“函数是一等的公民”是函数式编程(functional programming)的重要特征。Go 语言在语言层面支持了函数式编程。

package main

import "fmt"

type Printer func(contents string) (n int, err error)

func printToStd(contents string) (bytesNum int, err error) {
return fmt.Println(contents)
}

func main() {
var p Printer
p = printToStd
p("something")
}
函数的签名其实就是函数的参数列表和结果列表的统称,它定义了可用来鉴别不同函数的那些特征,同时也定义了我们与函数交互的方式。


各个参数和结果的名称不能算作函数签名的一部分,对于结果声明,名字也可以没有。且函数的名称也不算函数签名的一部分,只是个标识符而已。


高阶函数
 


1. 接受其他的函数作为参数传入;
2. 把其他的函数作为结果返回。


只要满足了其中任意一个特点,我们就可以说这个函数是一个高阶函数。
 
卫述语句
 
卫述语句是指被用来检查关键的先决条件的合法性,并在检查未通过的情况下立即终止当前代码块执行的语句。在 Go 语言中,if 语句常被作为卫述语句。
if op == nil { 
return 0, errors.New("invalid operation")
}