Gen_random_num_in_rust

Rust标准库中并没有随机数生成器,想要实现此类功能,你需要自行设计(纯Rust或FFI到C),或者使用第三方包。 一个常见的解决方案是使用rand包,该项目基于Apache-2.0 和 MIT协议开源,且拥有完备的文档: ...

February 29, 2024 · 2 min · 351 words · IAKSH

something_about_thread_safety

0x00 | 基本意义 当某个功能在多线程环境中被调用时,能够正确地处理多线程之间的共用变量,使程序能够按照预期正确执行。 如果一个功能(比如函数)在执行过程中需要修改一些公共变量,而且其功能是连续的,这一次的功能会受到上一次执行后对公用变量的修改的影响。 也就是说这个功能是受调用顺序影响的。 那么这个功能就不是线程安全的。 因为在多线程环境下,无法确定线程间调用功能的顺序。各个线程将会相互干扰。 0x01 | 锁 常见的就是mutex,互斥锁。 这是一种十分暴力的解决方案,简单易用,但是容易让程序退化回单线程。 0x02 | 原子操作 就目前而言,原子操作已经上升为CPU的一套指令集了。 原子操作通过硬件电路实现了一套基本没有开销的线程安全实现方案。 C++标准库中提供了相关API

February 29, 2024 · 1 min · 19 words · IAKSH

something_about_dependency_injection

在复用代码时,尽量使用has-a(组合),而非is-a(public继承)。 一来has-a不会将基类的所有api保留在子类,避免了“鸵鸟非鸟”的问题。 二是子类能在逻辑上与实际的基类解耦。子类依赖接口,而不是实际的基类。 依赖注入(dependency inject,DI) 之前已经提过了,”子类“应当依赖一个固定的接口,而不是某一个指定的类。这样,子类的设计着力点就从依赖的具体类的设计转回了子类本身。 然而这样会带来一个额外的问题:接口是否应该定义如何初始化该类?综合而言,答案是否定的。但如果接口没有规定如何初始化,那么子类又应该如何初始化一个未知初始化方式的成员类实例呢? 答案是DI。让子类所依赖的这个类在子类的外部构造,在这之后使用子类的setter将其绑定到子类中。 至于这个被依赖的类具体如何在子类外部被构造,我目前的想法是做一个工厂模式。当然,还是得看实际情况,如果并不需要太过泛化,直接调用构造函数就好。 DI实际上将一个类的依赖顺序倒置了: 在不使用DI,直接在类中镶嵌其所依赖的类时,整个构造是从顶部开始的,由顶部逐渐向其所依赖的底部进行。这个过程是自动化的,而且几乎是固定死了的。它为我们带来便利的同时,向我们隐瞒了实际上的依赖顺序。 而DI将这个过程倒置了,在构造顶部的类之前,我们需要从最底部的依赖开始,手动的构建整个依赖体系。 从维基上抄的一部分关于DI的内容 注:编程语言层次下,“接收方”为对象和 class,“依赖”为变量。在提供服务的角度下,“接收方”为客户端,“依赖”为服务。 0x00 | 四个基本概念 服务:任何提供了某种功能的类 客户:使用服务的类 接口:客户不应该知道服务实现的细节,只需要知道服务的名称和API 注入器:负责把服务引入给客户,叫法有很多:Injector / Assembler / Container / Provider / Factory 依赖注入把对象构建和对象注入分开,因此创建对象的 new 关键字也可以消失了。 0x01 | 实现方式 建钩子注入(构造注入?):依赖由客户对象的构造函数传入 Setter注入:客户对象只能暴露一个能接收依赖的setter方法。 接口注入:依赖的接口提供一个注入器方法,该方法会把依赖注入到任意一个传给它的客户。客户实现一个setter接口,可设置依赖。 0x02 | 我的理解 DI实际上就是尝试使客户类的设计关注点回归到类本身,而非其所依赖的类。 认识到了一个新的词 ”关注点分离“。

February 29, 2024 · 1 min · 45 words · IAKSH

something_about_msc_51

0x00 | 历史 MCS-51架构是Intel搞的东西,就和今天的所谓”架构“一样,实际上是一组指令集和一些硬件标准,用在了自家的Intel 8051,Intel 8751等等芯片上。 不止MCS-51,Intel还搞出过MCS-48,MCS-96。 基于MCS-51架构的Intel 8051设计简单,使用方便,价格低廉,功耗(在当时)较低,受到一众吹捧,美国各高校也开始将其列入计算机课程。当然也少不了来自世界各地的效仿者。 0x01 | 现状 Intel 已经不再设计和生产单片机了,但是在这之前 Intel 疯狂售卖MCS-51架构的授权。一些拿到这一授权的公司就开始生产并修改自己的兼容MCS-51架构下程序的单片机,比如中国台湾的STC宏晶,ATMEL。 虽然社会上对MCS-51架构单片机的需求早已不复从前,MCS-51架构在各高校中还是有一些市场的。时至今日,STC和ATMEL等当年的一些MCS-51授权厂也依然在生产基于或兼容MCS-51架构的单片机。 目前全球最大,且可能是唯一在MCS-51架构上梭哈的就是STC宏晶,对于国内大学生而言其最广为人知的产品应该是STC89C52RC。 值得一提的是,STC公司不仅坚持传统的MCS-51单片机,还在此基础上研发出了32位的MCS-51指令集兼容内核。 0x02 | 硬件资源 由于各授权厂普遍存在修改MCS-51架构的情况,所以目前能买到的”51单片机“硬件资源只会比 Intel 的MCS-51架构下的更多。 而对于使用MCS-51架构的Intel 8051,其片上拥有: 8位总线 4KB内部储存,最大可扩充到64KB 128Bytes运行内存,最大可扩充到64KB 4组IO口(P0,P1,P2,P3) 2组16位计时器(T0,T1) 5个中断源(INT0,INT1,T0,T1,RXD,TXD) 1组全双工串口 对于使用MCS-51架构的Intel 8052,其片上拥有: 8位总线 8KB储存,最大可扩充到64KB 256Bytes运行内存,最大可扩充到64KB 4组IO口(P0,P1,P2,P3) 3组16位计时器(T0,T1,T2) 6个中断源(INT0,INT1,T0,T1,T2,RXD,TXD) 1组全双工串口 0x03 | 软件生态 由于MCS-51架构曾经的辉煌,以及其目前在各个高校中的地位,时至今日依然有不少MCS-51内核单片机的开发工具和其他软件依然在保持维护。 对于编译器,有: SDCC:一个开源的C语言编译器,可编译出运行在MCS-51架构单片机和其他一些小型设备上的程序。该编译器同时提供了相关的头文件和程序打包工具。 MDK Keil C51:一套闭源的商业软件,是MDK Keil集成开发环境的一部分,提供了对MCS-51架构单片机的C语言编译器和仿真软件。 有关MCS-51的各种外设代码在互联网上很容易找到,不过其中大部分是使用的是 MDK Keil C51。

February 29, 2024 · 1 min · 57 words · IAKSH

something_about_sdcc

0x00 | Keil C51和SDCC Keil C51: 闭源的商业软件 自带(绑定)IDE IDE提供了仿真环境 生成的程序体积较小,汇编质量较高 网络资料较多 只要能接受那个IDE,门槛较低 SDCC: 免费的开源软件 更接近标准C语言 生成的程序体积较大,汇编质量一般 不止能给8051写程序 网络资料较少 有一点点的门槛(需要自己配置环境和工作流 0x01 | 从Keil C51迁移到SDCC sdcc 更加接近标准C编译器,对于不属于标准C语言的特性,sdcc 在其标识符前加上两个下划线进行标识。 sdcc中没有sbit和bit这样的数据类型(但实际上有__sbit)。在Keil C51中常见的一些定义语句在SDCC中需要使用宏实现。 sbit SDA = P1 ^ 5; sbit CLK_ST = P1 ^ 6; 在 sdcc 中: #define SDA P1_5 #define CLK_ST P1_6 // 也可以使用__sbit,不过可能不是你想的那样 __sbit __at (0x90) P1_0 ; 另外,Keil C51中的interrupt关键字也被改为了__interrupt,在Keil C51中可以这样定义一个中断函数: void my_interrupt_func() interrupt 4 { // ... } 而在 sdcc 中需要这样:...

February 29, 2024 · 1 min · 103 words · IAKSH