Blog

sub:React

Content #

对unmounted_component执行setState 已经卸载的组件上执行setState会出错,这里给出的三种可能发生的情形。

Hooks #

sub:useEffect sub:useRef sub:useMemo

Hooks的来历 Hooks与Class在逻辑复用上的对比 只能在函数组件的顶级作用域使用 Hooks的两条使用规则 useCallback缓存回调函数 useContext定义全局状态 实现useSingleton 封装通用逻辑useAsync 监听浏览器状态useScroll 博客文章列表过滤

Redux #

Redux的三个基本概念 react-redux的配置 使用Redux的计数器

对unmounted_component执行setState

什么情况下,React可能会对unmounted component执行setState? #

  1. 异步请求数据尚未结束时,组件已经卸载了。
  2. 卸载时没有清除清除listener。
  3. 卸载时没有清除interval。

Viewpoint #

From #

方位判断与双耳效应

方位判断与双耳效应 #

我们可以感知到声音是从不同的方向传来的。我们不妨先来看看这所谓的“方向感”是怎么产生的。

我们可以通过图 1 看到人耳的耳廓在接收不同方向的音源时,会让声波以不同的路径传导至内耳。这样,不同方向的声波传输到内耳的时候,音色就会由于耳廓的形状而产生各向异性。除此之外,由于我们有两个耳朵,所以音源在不同方向时声波到达耳朵的时间也会不同,这一点我们可以结合图 2 来理解一下。

其实很简单,如果音源在你的左侧,那么左耳会先接收到声波;相反如果音源在右侧,右耳会先收到声音。同时由于人的头部也会对声音的传播产生影响,如果音源在左侧,那么声波需要越过头部这个“障碍”才能传递到右耳,那么相对于左耳,音色和能量可能都会有所衰减。这其实就是空间音频里常说的“双耳效应”,即依靠双耳间的音量差、时间差和音色差来判别声音方位的效应。

Viewpoint #

From #

12|空间音频入门:如何实现“声临其境”?

GRUB是如何启动的

GRUB是如何启动的 #

BIOS 只会加载硬盘上的第 1 个扇区。不过这个扇区仅有 512 字节,这 512 字节中还有 64 字节的分区表加 2 字节的启动标志,很显然,剩下 446 字节的空间,是装不下 GRUB 这种大型通用引导器的。

于是,GRUB 的加载分成了多个步骤,同时 GRUB 也分成了多个文件,其中有两个重要的文件 boot.img 和 core.img,如下所示:

其中,boot.img 被 GRUB 的安装程序写入到硬盘的 MBR 中,同时在 boot.img 文件中的一个位置写入 core.img 文件占用的第一个扇区的扇区号。

而 core.img 文件是由 GRUB 安装程序根据安装时环境信息,用其它 GRUB 的模块文件动态生成。如下图所示:

如果是从硬盘启动的话,core.img 中的第一个扇区的内容就是 diskboot.img 文件。diskboot.img 文件的作用是,读取 core.img 中剩余的部分到内存中。

由于这时 diskboot.img 文件还不识别文件系统,所以我们将 core.img 文件的全部位置,都用文件块列表的方式保存到 diskboot.img 文件中。这样就能确保 diskboot.img 文件找到 core.img 文件的剩余内容,最后将控制权交给 kernel.img 文件。

因为这时 core.img 文件中嵌入了足够多的功能模块,所以可以保证 GRUB 识别出硬盘分区上文件系统,能够访问 /boot/grub 目录,并且可以加载相关的配置文件和功能模块,来实现相关的功能,例如加载启动菜单、加载目标操作系统等。

...

用cProfile进行性能分析

用cProfile进行性能分析 #

比如我想计算斐波拉契数列,运用递归思想,我们很容易就能写出下面这样的代码:

def fib(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    else:
        return fib(n-1) + fib(n-2)
def fib_seq(n):
    res = []
    if n > 0:
        res.extend(fib_seq(n-1))
    res.append(fib(n))
    return res
fib_seq(30)

接下来,我想要测试一下这段代码总的效率以及各个部分的效率。那么,我就只需在开头导入 cProfile 这个模块,并且在最后运行 cProfile.run() 就可以了:

import cProfile
# def fib(n)
# def fib_seq(n):
cProfile.run('fib_seq(30)')

或者更简单一些,直接在运行脚本的命令中,加入选项“-m cProfile”也很方便:

python3 -m cProfile xxx.py

运行完毕后,我们可以看到下面这个输出界面: 这里有一些参数你可能比较陌生,我来简单介绍一下:

  1. ncalls,是指相应代码 / 函数被调用的次数;
  2. tottime,是指对应代码 / 函数总共执行所需要的时间(注意,并不包括它调用的其他代码 / 函数的执行时间);
  3. tottime percall,就是上述两者相除的结果,也就是tottime / ncalls;
  4. cumtime,则是指对应代码 / 函数总共执行所需要的时间,这里包括了它调用的其他代码 / 函数的执行时间;
  5. cumtime percall,则是 cumtime 和 ncalls 相除的平均结果。

了解这些参数后,再来看这张图。我们可以清晰地看到,这段程序执行效率的瓶颈,在于第二行的函数 fib(),它被调用了 700 多万次。

...

toc:Python

变量 #

变量的赋值 通过函数修改变量值的两种方法 函数的参数传递 不可变对象的赋值 列表的赋值 和None比较时候永远使用is 函数定义和函数调用中的starred-argument

#

Python类装饰器 Python装饰器保持函数元数据

类型模型的三条原则 #

内存管理 #

编程技巧 #

应用 #

工具 #

Concurrent #

练习题 #

利用Python生成器解决判断子序列问题

Cookbook #

用iter方法逐行读取文件 统计文件中单词出现的频率信息(setdefault) 统计文件中单词出现的频率信息(defaultdict)

pdb的用法

pdb的用法 #

要启动 pdb 调试,我们只需要在程序中,加入“import pdb”和“pdb.set_trace()”这两行代码就行了,比如下面这个简单的例子:

a = 1
b = 2
import pdb
pdb.set_trace()
c = 3
print(a + b + c)

当我们运行这个程序时时,它的输出界面是下面这样的,表示程序已经运行到了“pdb.set_trace()”这行,并且暂停了下来,等待用户输入。

> /Users/jingxiao/test.py(5)<module>()
-> c = 3

Viewpoint #

From #

31 | pdb & cProfile:调试和性能分析的法宝

行为反应的领域特殊性

Content #

什么是行为反应的“领域特殊性”?这种无法自动把知识从一种情况转化为另一种情况,或者从理论转化为实际的状态,是人类本性中令人困扰的特性。让我们称它为行为反应的“领域特殊性”。领域特殊性的意思是,我们的行为反应、思维模式和直觉取决于事物的背景,进化心理学家称之为事物或事件的“领域”。教室是一种领域,生活也是。我们对一则信息的反应不是根据它的逻辑特性,而是根据它的环境,以及它在我们的社会情绪系统中的位置。在教室中以某种角度理解的逻辑问题在日常生活中可能受到不同的对待。实际上,它们在日常生活中确实受到了不同对待。

Viewpoint #

From #