Nodejs开发的时候遇到的一个异步问题
我的项目需要将多个excel文件生成
然后打包,在发现有excel文件缺失后
我排查确定打包文件的函数没有问题
把目光锁定在文件名的生成上后发现
我总是认为timestmp用来做文件名可以保证文件名不会重复
但其实在异步操作中
由于多个线程是并发执行的
他们某一时刻的timestmp可能是相同的
这就会导致excel文件名生成可能是相同的
从而覆盖之前生成的excel文件
导致excel文件的缺失
后面使用md5对里面的唯一值_id加密后用来拼接文件名
可以正常生成excel文件了
发现确实有timestmp相同的情况出现
计算机网络应用层
应用层常见的网络应用体系结构
C/S模式 (Client/Sever)
P2P模式 (Peer to Peer)
混合模式
C/S模式和P2P模式的运作过程在C/S模式中,
Sever需要一直运行
Client则是按需连接
Sever需要有一个固定的IP和固定的Port(端口号)才能方便Client的连接
常见的在Web服务中,需要一台服务器守候在80端口,在客户端(浏览器)使用域名解析到服务器IP,然后访问其80端口进行数据交换
在P2P模式中,
任何一个Peer除了作为客户端外还都可以作为服务器
在某个Peer请求某个资源时可以向多个用户同时请求资源,可以有不错的速度
对于一个会话来说是有客户端和服务器之分的
常见的如迅雷(好像是只要不给),在准备下载某个资源时,会先与其他用户进行通信,查看其他用户是否有自己需要的内容,如果有会从其他用户那进行下载,从而提高下载的速度
C/S模式和P2P模式的特点C/S模式在用户量增加到一定数量的时候会性能会出现断崖式的下降
而P2P模式在用户量增加时性能会均匀增加(因为增加用户的同时也就在增加服务器)
应用层和传输层进行传输前需要确定的 ...
主存储器的基本结构和原理
主存储器的构成在一般的主存储器中主要由以下部分构成
MDR(memory data register)内存数据寄存器
MAR(memory address register)内存地址存储器
存储体
存储体由存储单元构成而存储单元又由一个个存储元构成
存储元的构成和数据读写的实现原理存储元的构成一般存储元由以下两个元件构成
MOS管
电容
其中
MOS管在接受5V及以上的电压时,会接通线路,否则保持短路状态
电容在两级有电压差时会存储电荷
他们在电路图中的结构如下图所示
存储元的写入和读取如果此时需要进行数据的写入
首先对MOS管提供5V电压让MOS管保持通路状态
在MOS管的第三个(从左往右)引脚给出高电平
此时电容左端为接地0V,右端为高电平
因此电容会存储电荷,在存储完成电荷并稳定后停止对MOS管提供5V电压
此时电容左端和右端皆为接地状态,电荷不会发生移动
存储电荷状态下的电容代表二进制数据1
如果需要进行数据的读出
首先对MOS管提供5V电压让MOS管保持通路状态
分为两种情况
第一种情况下电容中有电荷存储
此时由于MOS管已经接通
电容会释放电荷
产生 ...
管程
管程的作用让写代码的不用再去考虑互斥问题(互斥问题由编译器自行解决),可以更好地投入到其他的逻辑思考当中
管程的代码实现 管程的代码实现有点面向对象的意思,下面以生产者(Producer)消费者(Consumer)问题展开
生产者和消费者问题中有以下数据
count 当前在缓冲区中的资源的数量
MAX_NUMBER 缓冲区的最大容量
其中的count是一个共享数据会被多个进程争夺使用权,但我们使用了管程技术所以现在不需要担心多个进程对该变量的争抢问题
除了数据以外我们还需要定义对数据的操作(行为),在生产者消费者问题中我们会有以下操作
insert 表示生产者将一个产品放入缓冲区
remove 表示消费者将一个产品从缓冲区中取出
管程虽然帮助我们解决了互斥的问题,但同步的问题依旧需要我们自己写代码解决
管程为我们提供了两个方法用于解决同步问题
wait() 调用该方法后进程进入阻塞队列
signal() 调用该方法后会从阻塞队列中弹出一个进程执行
在编写insert方法以及remove方法时我们需要注意以下几点
比如在执行insert方法的count++ 语句之前我们应该 ...
七种未定式计算
泰勒公式
f(x_0+h)=f(x_0)+hf'(x_0)+\frac{h^2}{2}f''(x_0)+o(h^2)在PDE(Partial Difference Equation)偏微分方程中我们会利用泰勒展开式对某一点进行展开
在上面的式子中
$x-x_0=h$
所以上面的式子还可以写成
f(x)=f(x_0)+hf'(x_0)+\frac{h^2}{2}f''(x_0)+o(h^2)特别地在我们令$x_0=0$时,我们就可以得到特定函数的展开式
f(x)=f(0)+hf'(0)+\frac{h^2}{2}f''(0)+o(h^2)例如对于$\tan x$
我们先写出其多次求导的式子
\tan'x = (\frac{\sin x}{\cos x})'=\frac{\sin^2x+\cos^2x}{\cos^2x}=\frac{1}{\cos^2x}=\sec^2x\\
tan''x = (\frac{1}{\cos^2x})'=\frac{-2\cos x (-\sin x)}{\cos^4x}=\frac{2\sin x}{\cos ^3x}=2\tan x\sec x\\ ...
二叉树的遍历
先中后序遍历先中后的含义
先中后代表了根节点的访问次序
一定会先遍历左结点再遍历右结点
假设对于一个结点(N) 他的左结点(L) 他的右节点(R)按照先中后序进行遍历的遍历顺序如下
遍历方法
遍历结果
先序遍历
NLR
中序遍历
LNR
后续遍历
LRN
遍历时的注意点对于某个结点来说一定要将此结点按照指定的遍历顺序遍历完全
例如如果按照中序遍历准备开始遍历某个结点时,就要依照遍历顺序先遍历左结点
并且在遍历左结点时,也要按照遍历顺序进行遍历,对当前左结点的左结点进行中序遍历
只有当某个结点的左节点为空时,才能按照指定的遍历顺序选择当前遍历中的下一个应该遍历的结点 在当前例子中应该选择根节点进行遍历
在当前遍历的所有左中右结点都遍历过一遍后才向上继续遍历
在执行时应该具有递归思维
遍历的例子
按照先序遍历(中左右)
从结点1开始先遍历到结点1 输出1
接着开始遍历结点2
对于以结点2为根节点的遍历先遍历到结点2 输出2
接着开始遍历结点4
对于以结点4为根节点的遍历先遍历到结点4 输出4
由于结点4没有左右结点 所以紧接着的遍历都为空
由于左 ...
二叉树的存储结构
二叉树的顺序存储结构体定义1234typedef struct { ElemType value; int isEmpty;} Node;
静态声明1Node[] tree;
不忽略结点顺序的顺序二叉树的结点关系为了保持数组索引和结点编号的一致性
在声明完成数组后一般第一个元素不会被使用即tree[0]被放弃使用,树的第一个结点会从tree[1]开始存储
这样如果需要访问树的第$i$个结点只需要访问tree[i]即可,不需要写成$i-1$,增加代码的可读性
对于一个存储在数组tree[MAXSIZE]的完全二叉树
当有一编号为$i$的结点,可以得出结点关系为
$2i$ 为其左结点的编号
$2i+1$ 为其右结点的编号
$\lfloor \frac{i}{2} \rfloor$ 为其父节点的编号 $\lfloor \rfloor$ 为向下取整符号 (假设现在考虑编号为3的结点 那么$\frac{3}{2}=1.5$ 此时如果向上取整得到2 显然2是其兄弟结点而不是父节点 因此应该向下取整)
使用顺序二叉树的使用场景在使用顺序表进行存储时,如果碰到了非完 ...
二叉树的相关性质
二叉树性质结点的总个数=总度数+1
在图中我们可以看出
对于任意一个结点
这个结点的度=这个结点的连线数量=这个结点的下一层结点数量
在经过我们处理之后可以发现根节点是没有对应的这就是1的来源
度为0的结点个数为度为2的结点个数+1设非空二叉树中
度为0的结点个数$n_0$
度为1的节点个数$n_1$
度为2的节点个数$n_2$
当二叉树的总结点个数为$n$时,可以由
结点的总个数=度为0的结点个数+度为1的节点个数+度为2的节点个数
结点的总个数=总度数+1
得到以下两个式子
$n=n_0+n_1+n_2\cdots①$
$n=0\times n_0+1\times n_1+2\times n_2+1\cdots②$
将①-②得到
$0=n_0-n_2-1\Rightarrow n_0=n_2+1$
所以说
度为0的结点个数为度为2的结点个数+1
叶子结点个数比二分支结点个数多一个
二叉树的第$i$层至多有$2^{i-1}$个结点可以由以下逻辑数学归纳得到结论
对于二叉树的第一层显然最多只能有$1=2^0$个结点
第二层由于第一层最多只能有$1=2^0$个结点,而 ...
部署Arch-Linux-ARM到AndroidPad
前言需要增加Pad的可用性,偶然看到视频便跟着操作
参考链接proot容器+termux-x11+KDE Plasma 自动安装脚本 支持触屏 不掉帧_哔哩哔哩_bilibili
GitHub - kde-yyds/termux-x11-plasma-installer: a script to install proot+temux-x11+plasma in termux
小米平板5写代码超强体验!Termux-X11 + VSCode_哔哩哔哩_bilibili
https://ivonblog.com/posts/fix-termux-signal9-error/
安装Arch-Linux的具体步骤
处理”Signal 9”错误
安装”Termux”以及”Termux:X11”应用并授予权限
在Termux中执行代码
输入启动命令启动
处理”Signal 9”错误使用数据线连接Pad并打开Pad的USB调试功能
下载ADB调试工具解压后在命令行打开解压后目录
在命令行中输入以下命令连接设备
1adb devices
在查看到设备已经连接后继续输入
1adb shell
根据安 ...
启用验证安全地连接MongoDB
综述MongoDB默认在msi安装后处于非认证状态,此时我们不需要进行认证就可以连接并且使用MongoDB服务器,但出于安全性考虑,为MongoDB添加认证服务是必要的。在添加成功后使用非认证的方式连接MongoDB会被以”requires authentication”拒绝连接。而以用户名+密码的方式进行连接的用户可以正常连接使用。
有以下步骤
创建管理员用户
开启用户认证
设置允许从外网进行访问
防火墙开启服务器端口
测试连接
创建管理员用户确保MongoDB服务在后台正常运行,如果没有则尝试启动服务,启用失败就检查配置文件,默认win的配置文件存放在bin目录下的cfg文件
进入安装目录的bin目录下,打开终端
输入mongo
1mongo
使用admin数据库
1use admin
创建root权限用户
1db.createUser({user:"root",pwd:"xxxxxxxx",roles:["root"]})
如果返回Successfully added user …. 即创建成功 ...