这个计划起因是我经常需要打印,但是学校的打印店难得跑,还收钱五毛一张,我想打印机才多少钱,就像自己买一个;初步了解,发现还挺便宜,一两百块钱;细致了解了一下,发现这些一两百的挺坑,打印机需要耗材,这些打印机本身不贵,但是耗材就相当于本身一半的价钱了,耗材贵,打印的张数还少,算下来一张打印出来还挺贵。要想打印的便宜,还得买贵的打印机,打印机越贵,耗材越便宜,算下来每张成本也就低。于是一个计划就诞生出来了,我自己买一台打印机,预算大概五百左右,放在宿舍;我自己用肯定不会很频繁,没人会没事整天打印把,于是我就可以共享出去,给整栋楼的人打印,方便他们,然后定价要低于学校打印或者持平,这个赚取的钱要用来抵消掉成本(打印机的钱)和维护费用(墨水,纸张,机器维修等),等到可以持续运行之后,我就可以优惠提供给宿舍楼内人打,比如在此交过打印钱的同学可以免费打,在回本之后的同学可以以成本价钱打印。这一项实验,局部的社会主义行动,我称之为普瑞特计划(打印机的英文为printer)。
那么首先是资本的积累,我需要花钱买打印机,这个钱从哪儿来?我计划暑假去找兼职,赚到的大概六百元左右,足够打印机和购买耗材使用。
然后是定价的问题,我如果低于学校打印店,那么肯定有很多人到我这儿打,我不一定有这么多的时间呆在宿舍,然后频繁的打也会加快打印机损坏,我回本的时间也许会加快;假如我按学校价格来,肯定有一部分人回来我这儿,人不会很多,我能应付过来,可能回本的速度会比前面慢一点,这样就不会出现都往我这儿跑的情况,我这儿还近,方便,我和学校打印机店双赢。所以,现在把价格定为和学校打印店持平。
还有权力的问题,我作为发起人,可以享受打印机的使用权,比如我可以决定帮谁免费打,这样我可以帮到室友和同学,同时打印机的所有权也是我的,我可以任意处置这个机器;我原本准备等机器回本以后就优惠给同学们打印,此时运行只需要分摊维护费用就行了;后面感觉不对,因为此时的优惠实际上是前面交过钱的人垫付的,对他们不公平,所以我决定一直不改变定价,改为盈利分红的模式,分给支付过打印费用的人。就是一旦没有这么多人来打印,我就亏本,损失的费用大概是成本减去机器折旧的钱的差价,一旦回本,我就以分红的方式,分给其他支付了费用的人,并且按比例。在这个里面,我承担了初步的风险,所以我认为我拥有使用权没问题,权力和责任对等;一旦回本之后,此时的打印机就按照股权制进行分红,这个时候,我就不能免费帮人打了,所有人都收钱,所有使用机器的人都相当于股东,使用的人越多,相当于平摊的成本越低。
最后是处置问题,我不可能一直在学校,两年之后就毕业了,到时候这个机器是怎么处置,是折旧卖出去还是怎么的,如何处理;如果有人继承,必须按照我的模式运行下去,如果折旧,那么折旧后这个钱也要分红。
]]>前几天参加了黄河下乡活动,调查了黄河榆林段的环境保护情况,去了很多地方,甚至去了总书记调研过的高西沟;
陕西这边属于黄土高原,风沙大,气候比较干燥,个人感觉一年中就七八月份集中降雨,冬天下雪,平常很少见到下雨;这点我感受很深,带到学校的伞都没用几次。
那么在这边做环保,可想而知,难度挺大,我沿着山上去的时候,都看见好多松树干死了;这边种的应该都是耐旱的作物,苹果李子什么的;不过这边虽然缺水,但种出来的水果可甜了,路上就去农家的桃院玩了,现摘的桃子,我选的几个都是又大又红,还挺甜,熟透了的感觉,再不摘估计就烂地里了。
这几天,我也在想一个问题,做环保的意义在哪,我以前不大关注环保,怎么把环保容纳进我自己对世界的认知体系中?平常,一般的环保都是说,企业污染问题,乱排乱放污染环境,还有要节能;这里的环保可以理解为国家强制规定成眠的重新的资源再分配,因为这里的环境被看过公共利益,谁污染了,谁就应该治理;环境污染问题有点特殊,比如在上游排污,下游受到影响,下游的环保机构去调查,很可能查不到源头,或者源头很多无法定责;这些污染都被环境吸收了,很难被各自的量化出来。最后若是政府出来兜底治理环境,实际上是企业排污不治理,不付责任,最后由纳税人,每个公民承担;这里企业不治理省下的钱,实际上是从公民手里薅来的,因为公共资源实际上是受损害的;所以出台环保政策,实际上是要强制限制企业转嫁成本,获取不正当利益,进而更公平。
高西沟的环境保护不同,因为这里原本是环境恶劣的,黄土高原,通过好几辈人的努力,才成为先在的样子。“穷则思变”,矛盾运行到了一定状态,就会引起变革;高西沟人决心改善环境,实际上是从当地的长远发展上考虑的,生态环境改善可以促进生产,比如治理水土流失,水土留住了,就能种植作物;生态环境的改善也发展了旅游业,成为了名片,也增加了当地村民的收入。高西沟的环保,实际上是从生态中获得发展,是做大蛋糕。
为什么以前不注重环保,现在注重环保,这应该和现在的生产水平,发展状况,矛盾的运行有关;以前,发展是主要的矛盾,环境还一般;当环境被污染了一定程度,发展到了一定阶段,自然就开始注意环境问题了。所以,环境问题的凸显,实际上是发展与人理念的冲突,也可以说是现实与精神的外在体现。
下面写一下暑假重点要做的事儿;暑假从今天算起,还有一个月的时间,在这一个月里,我要完成以下内容:
实验和综述大致框架
练字
学习计算机专业课
看书(哲学史,csapp)
做兼职
最近发生了很多事儿,看着感觉好长时间没有更新博客了,最近的日期还是5月29号;最近也不知道在干啥,一下子就过来了,前面在看csapp的寄存器那一章,前面两部分,数据和指令,语句的汇编内容已经看完了,就差最后一部分面向过程那一节了,包括运行时栈区,数组指针等内容;本来这一部分也起了点头,后面不知道什么原因,又转向了王爽的汇编语言那本书,想先把这个本书看完,再回头看csapp;汇编也算是看了两章了,由于对汇编有些了解,重复的内容就跳过了,看的就不那么仔细;再加上考了个四级,平常又休息玩游戏,中间还花时间,想给宿舍区装一个自动给开锁的门锁,去找了方案,并且设计了板子,还没完成,一晃就到现在了;
就感觉平常时间过的好快,看书速度不快,几页书下来,几个小时就过去的了,平常还要去实验室,做实验;所以就很需要对事件精细划分,本来任务就多,就不能把时间浪费掉,玩过去了;
下面就计划一下后面的任务,每天依然是练字一篇,大概二十分钟,游戏就是csgo和元神,这两也慢慢玩的少了,以后少玩,多看看书;第二个任务就是计算机的相关知识学习,这个每天至少花两三个小时看吧,要写笔记,整理博客,加在一起可能就是一上午,或者一下午的时间;第三个任务就是英语,一天花个一个小时左右吧,时间放在早上或者晚上,以后需要看英文文献,所以这也是个必要的能力;第四个任务就是电化学,实验啊,论文啥的,加在一起,可能就是一个上午或下午的时间;平常的安排就这些,大概就放在早上,上午,下午,晚上这个四个时间段。
另外,最近还有个临时的任务,就是做一个宿舍门锁,这个可能总共要花两天的时间,包括接线调试程序,买硬件啥的,这个就优先处理吧,后面写成博客,记录一下。
]]>最近,喜欢上了韩磊的等待,尝试写一下注释;平常也要多做这样的工作,锻炼做精神分析的能力
1 | 我为什么还在等待 |
我为什么还在等待,说是等待,就预设了两个对象,其中一个是对象,是我,我是主体,另一个对象是什么,不知道,但是他至少存在,是能被摄取的,可能是实体,可能是抽象的…除了对象,等待还预设了,时间和空间,等多久,在哪儿等。问为什么还在等待,要不就是在问等待的原因,要不就是问为什么还在等,还要继续等吗?
我不知道为何仍这样痴情,这样痴情,显然也是对上面那个对象所说的,要不然说一个人痴情毫无意义,痴情与他;仍,表示状态,说明以前也对他痴情,一直到现在,未改变;不知道为何,说明不知道原因;这一句同样,可能有两个问题,一个强调仍,为什么没改变,另一个强调痴情,为什么痴情。
明知辉煌,过后是暗淡,仍期待着把一切从头来过。明知辉煌,过后是暗淡,辉煌怎么理解?暗淡怎么理解?说辉煌,暗淡,这两都是形容词,是什么辉煌,什么暗淡,这里并没有说主体,前两预设了两对象,要不就是说,是我辉煌,我暗淡,要不就是我等的那个对象,辉煌,暗淡。其次,作者还把辉煌和暗淡对立了起来,他用过后,假如某个对象,一直处在辉煌状态,经过一个阶段后,还是辉煌状态,那他就不必引入一个新符号,暗淡,来表示这两阶段的区别,可见,暗淡其实是不同于辉煌的那个阶段的。
明知是要和后面的仍联系在一起的,明知什么,仍什么。明知后面就表明,明知的是个现状,现实或经验规律等客观的,仍后接表示主观的,意志的精神的。仍期待着把一切从头来过,期待,就表明这只是一种想法,有点偏积极的,主动去接触,去拥抱,把一切从头来过,是说,明知那个对象会从辉煌,走向暗淡,仍然想主动再来一次。为什么想从头来过,到底是想再体验一下这一过程,还是说,从头来过就能改变这一现状。如果说作者是认为辉煌就是好的,暗淡就是不好的,那么显然,他是想从头来过,改变这一状况,是不服的,对现状不满的;如果作者认为,辉煌和暗淡平等,这是一个过程,无非谁好谁劣,那么他就无所谓改变,他从头来过,只是重新体验了这一过程。
前面说的不知道为什么等待,不知道痴情,其实他都知道,答案就在底下写清楚了,痴情于再来一次,等待,就是下面的期待,一个意思。
我们既然曾经拥有,我的爱就不想停顿。曾经说明以前有,现在不曾有,失去了,我的爱就不想停顿,这个就说明原因,就不想停顿,因为以前有过,有过啥不知道,有过辉煌?有过暗淡?我的爱这里可以说是精神,主体性,不想停留,不想停留在失去拥有的状态下;在功利主义的意识形态下,只可能说拥有辉煌,如果按这么说,那么失去的就是辉煌,现在是暗淡状态,实际上是要从暗淡走向辉煌;在非功利主义看来,就是无所谓辉煌,暗淡,只是不满于现状,要从一种现况中走到另一种现状。从这里看,作者根本就没把停不停留说明白,你到底是想停留还是不想停留,不同的人看到的不一样。
每个梦里都有你的梦,共同期待一个永恒的春天,春天。每个梦里都有你的梦,都是在说,每个人,包括你,组成的共同体,都有这个梦,永恒的春天,春天;春天给人的感觉是温暖的,适宜的,昆明四季如春;但对另一些人,春天花粉,过敏,难受,感冒也来了。作者又加了个永恒的,永恒的春天,人都知道,那有永恒的春天,没有这样的气候,哪怕是四季如春,也是有区别的,这里用的暗喻,用春天的温暖比喻,他所等待,所期待的,所想停留的。期待永恒的春天,在一些人看来,可能是温暖的,在另一些人看来,其实言过其实,没那么好。
看完整首歌,他也没说明,他的态度是暧昧的,所等待的到底是什么,不同的力量,在其中看到的是不一样的,这就导致不同人看到这,都能有共鸣,都有话说,和其传唱度高是有必然联系的。
]]>python模板
登录
1 | import json |
发送邮件
1 | import smtplib |
问题
1 | TypeError: login() missing 1 required positional argument: 'self' |
最近写代码的时候,一直报这个错,源代码类似下
1 | class Login: |
原因是调用函数需要实例化
改为
1 | Login().login() |
python的类调用与java有出入
]]>程序的流程控制,包括条件循环和分支结构,如if,for,while,switch语句,本文从汇编的角度,来理解这些结构
例如有两个值运算,有可能会溢出,有可能会产生进位,有可能为负,运算后,这些信息都通过条件码的形式保存下来。
lead
指令只进行地址运算,不会修改条件码
一元,二元,移位操作都会修改寄存器,并且设置条件码
有两类指令只设置条件码,不修改其他寄存器: CMP
和 TEST
指令
CMP
对操作数之间运算比较,基于S2-S1
1 | CMP S1,S2 |
TEST
对操作数进行测试,基于S2&S1
1 | TEST S1,S2 |
例如 testq %rax,%rax
可以检查%rax是正数负数还是零
每条指令都对应四种类型 b,w,l,q
对应 字节,字,双字,四字
上面是设置条件码的一些指令,下面是一种根据条件吗,设置的指令SET(读取条件码)
SET
指令会根据条件码设置值,有三种使用方法
1 | comp: |
set指令
jump指令又可以分为直接跳转,间接跳转,有条件跳转
jmp .L1
jmp *(%rax)
跳转指令的编码方式常见的采用pc相对寻址(基址+偏移量)来编码,csapp中有个例子
1 | 1movq %rdi, %rax |
.o
反汇编
1 | 0:48 89 f8mov %rdi , %rax |
条件结构可以用条件控制和条件跳转来实现
1 | //C语言中的if-else |
翻译为goto版本
1 | t = test; |
&&在c中存在短路现象,即t1&&t2,若前面为假,第二个条件直接不检查,下面从汇编的角度理解下(csappT3.16)
源码
1 | void cond(long a,long *p) |
gcc下汇编代码
a in %rdi ,p in %rsi
1 | cond: |
可以看到,若第一个为假,会直接跳转到 .L1
段,跳过检查第二个条件的代码
条件传送比起条件控制,更符合现代处理器的性能特性
分支预测的处罚
假设预测错误的概率是 p,如果没有预测错误,执行代码的时间是 TOK,而预测错误的处罚是 TMP。 那么,作为 p 的一个函数,执行代码的平均时间是 Tavg(p)=(1-p) TOK+p(TOK+TMP)。 如果已知 TOK和 Tran(当 p=0.5 时的平均时间),代入等式,我们有 Tran=Tavg(0.5)=TOK+0.5TMP, 所以有 TMP=2(Tran-TOK)。因此,已知 TOK=8 和 Tran=17.5,我们有 TMP=19。
条件传送指令
条件控制的代码
1 | if (!test-expr) |
条件传送的代码
1 | v=then-expr; |
条件传送相当于不进行预测了,把分支的表达式都算出来,最后当满足条件的时候再进行赋值操作,这种对简单的表达式才有效,而且有时候可能会失效,不能采用这种方法,例如如下代码,如采用条件传送的话,假设指针为空,会异常
1 | long cread(long *xp){ |
c中的循环,包括while,do-while,for循环
1 | do |
直到型循环,至少执行一次,翻译为goto
1 | loop: |
1 | while(test-expr) |
跳转到中间, 它执行一个无条件跳转跳到循环结尾处的测试,以此来执行初始的测试
1 | goto test; |
guarded-do,首先用条件分支,如果初始条件不成立就跳过循环,把代码变换为 do-while 循环
1 | t=test-expr; |
goto代码
1 | t=test-expr; |
1 | for(init-expr;test-expr;update-expr){ |
for可以翻译成while代码
1 | init-expr; |
中间策略
1 | init-expr; |
guarded-do
1 | init-expr; |
switch语句通过使用跳转表(jump table)这种数据结构,可以根据一个索引值进行多重分支
跳转表,是一个指针数组,数组元素都是指向代码段的指针,通过 &&
符号声明
switch.c
1 |
|
gcc下运行结果
1 | 1 |
采用指针数组的方法对比
1 |
|
switch语句关键步骤是通过跳转表访问代码位置。
跳转表对重复的情况就是用同样的代码标号,对跳出程序的情况使用默认标号
csappT3.30
下面的 C 函数省略了 switch 语句的主体。在 C 代码中,情况标号是不连续的,而有些情况有多个标号。
1 | void switch2(long x, long *dest) { |
汇编
1 |
|
为跳转表生成以下代码:
1 | .L4 |
A. switch 语句内情况标号的值分别是多少?
-1、0、1、2、4、5 和 7
B. C 代码中哪些情况有多个标号?
.L5
的情况为 0 和 7,.L7
的情况标号为 2 和 4。
本节内容来源于深入理解计算机系统(csapp)一书第三章(精通细节是理解更深和更基本概念的先决条件)
Inter从8位->32位->64位
期间晶体管大致沿着十八个月翻一翻的速度增成,这就是摩尔定理;这个增长速度是计算机革命的驱动力
机器编码中最重要的是指令集体系结构(Instruction Set Architecture, ISA)和虚拟地址
指令集定义了数据类型及格式,指令格式,寻址方式和可访问地址空间的大小等等,相当于定义了cpu的状态
指令
常见通用寄存器比如%rax,%rbx,这两都是64位的;
一个程序就是一个有限的顺序指令,执行程序就是依次取指执行的过程
虚拟地址则将不同进程的虚拟地址和不同内存的物理地址映射起来
csapp里面用的是AT&T格式的指令,S->D,前面是源,后面是目的
指令又分为操作和操作数
操作数又分为源操作数和目的操作数,源操作数就是不随指令变化的操作数,目的操作数就是随着指令变化的操作数,前者可以看作变量,后者就是处理过后的量,成了因变量,所以叫目的操作数
操作数按类型分又可以分为:立即数$,寄存器%edx,存储器(%edx)
寻址方式
M[]表示在内存中,R[]表示在寄存器中,Imm立即数
比例变址寻址:M[Imm+R[rb]+R[ri]·S]
其他寻址方式类似比例变址
变址寻址:M[Imm+R[rb]+R[ri]]
基址偏移量寻址:M[Imm+R[rb]]
间接寻址:M[R[rb]]
间接寻址就是指针的用法
绝对寻址:M[Imm]
寄存器寻址:R[rb]
操作规定了执行什么操作,并会规定执行的数据类型
数据类型
四字q | 双字q | 字w | 字节b |
---|---|---|---|
quattuor | double | word | byte |
64位 | 32位 | 16位 | 一个字节是八位,8bit |
mov指令
mov用来传值,例如
1 | movq $0x0, %edx |
这条指令会把立即数0,传到寄存器%edx中,传送数据类型为4字,64位数据
以传送类型分,因此mov有四种,为 movb
,movw
,movl
,movq
由于x86-64惯例,movl会把目的操作数的高位置0
mov的扩展指令
MOVABSQ
,传送绝对四字
MOVZ
零扩展,会给目的操作数的剩余空位补0
MOVS
符号扩展,会给目的操作数的剩余空位补符号位
数据传送实例
1 | long ex(){ |
指令
1 | //xp in %rdi y in %rsi |
movq (%rdi),%rax
先根据寄存器%rdi内的地址,去内存中找到xp的值,直接把值赋给寄存器%rax
movq %rsi,(%rdi)
此时%rsi的值是y,把%rsi直接赋给%rdi所指向的值,此时内存中的xp值被修改成了y
ret
返回寄存器%rax的值,他的值此时是xp,所以返回xp
压栈出栈指令
栈是一种数据结构,特点是先进后出,进栈出栈都是在栈顶上操作
对应指令 pop
出栈,push
压栈
指向栈顶的指针%rsp(%esp)extend stack point,前面是64位,后面是32位
指向栈底的指针%rbp(%ebp)extend base point
所以,压栈和出栈都相当于两条指令
1 | pushq S |
假设栈顶的地址是 0x10
R[%rsp]-8->R[%rsp]
给寄存器-8,记录新地址 0x8
S->M[R[%rsp]]
把S的值赋到%rsp记录的新地址(0x8)下
M[R[%rsp]]->D
把%rsp寄存器的值当作地址,找到对应地址下的值,此时即栈顶元素。赋给D
R[%rsp]+8->R[%rsp]
%rsp自加8
可以看出,出栈其实没有删除掉出栈的元素,只是把出栈的那个值传到了别处,然后栈指针加8;不过,上一个元素虽然没被删除,但是可以被新增的元素覆盖掉
算数逻辑指令
一元指令就是一个操作数,比如自加1,二元就是两个操作数,其目的操作数又是源,参与运算,又是目的,存储值
加载有效地址
1 | leaq S, D //&s->D |
它的第一个操作数看上去是一个存储器引用,但该指令并不是从指定的位置读取数据,而是将有效地址写入到目的操作数,类似于 C 语言的取地址操作符“&”
移位运算
1 | SAl k,D//D<<k->D |
SAL 和 SHL 都是左移指令,效果是一样的,移动几位,右边补上几位0;右移指令不同,算术右移 SAR 是补上符号位,即右边的第一位;逻辑右移 SHR 是补上 0
异或运算
1 | XORq S,D //s^D->D |
讨论下面两条指令的区别
1 | xorq %rdx, %rdx |
这两条指令都相当于给寄存器置为0,前者是计算为0,后者是传了个立即数0;但是,编为机器代码后,前者只有3字节,后者有7字节
为什么会这样,于是在gcc下验证
编写text.c汇编代码(为了方便对比,见下)
编译不链接
1 | gcc -c text.c>text.s |
执行完后 ls
查看会生成 text.o
文件
反汇编并保存到 1.txt
中
1 | objdump -d text.o>1.txt |
查看 code 1.txt
text.s
1 | xorw %dx, %dx |
反汇编
1 | text.o: file format elf64-x86-64 |
可以看到,确实如书上所说,前3字节是操作,后4字节是操作数
]]>安装wsl,安装完需要设置用户名和密码
安装windows Termiral
win10商店下载略
cmd进入wt(wox下命令无法使用,改win+r运行正常)
cmd bash
连接,或者直接ubantu进入
1 | cd /etc/apt/ |
更新root密码
1 | sudo passwd root |
更改wt启动路径
1 | { |
修改 startingDirectory
vim删除全部
1 | :.,$d |
wsl下ubantu运行路径
1 | \\wsl$ |
今天,下午去蹭了次课;这件事的起因就是开学的时候看了一次课,相当于开学第一课的那种,然后发现一个老师比较好看,然后去查了一下,查到了教授的课表;当时就只是一个想法而已;后面由于疫情又改线上上课,就耽搁了。
直到昨天,做完一天实验,感觉终于有了点空,于是决定,去实现当时的这个想法;然后就现场查,去蹭课了;由于是史纲,跟我一个班的没几个同学听,只有我坐了第一排。
写下这件事的原因其实是我感觉这件事挺有意思,因为我很好奇这件事到底要向我揭示什么,他要表达什么;写下来,梳理一下,加深对自己的认识;
先说过去,为什么会去?也许是因为觉得老师好看,也许是觉得老师讲的好,也许是其他因素,不管这个因素是啥,总之,这些诱因是与我观念之中的某些结构有了共鸣,然后,才有了这个行为;前面说的这种”结构”,其本质是社会生活关系的整体性的构建出来的,一种享乐。文化构建出了一套爱欲,然后渗透到了我身上,什么样是美的?什么样是优秀的?我需要反思的是,不能被这样一套爱欲经济学俘获,这样的爱欲对现实的人妖魔化,甚至是一种异化;对具体的人必须要整体性的把握。
需要警惕 笔记主义
的自恋,靠吸引别人的二阶享乐
平常记笔记用markdown比较多,当写一些数学公式时候就特别不方便,虽然markdown可以支持网页编码,但是如果要转word的话就比较麻烦,考虑到以后需要写论文等等工作,于是准备来系统学习下latex
Latex来源于Τ~Ε~Χ的排版系统,后由莱斯利·兰伯特(Leslie Lamport)在20世纪80年代初期开发,取其名,叫Latex
LaTeX需要编写代码,通过编译得到所需的pdf文件
进入官网下载软件。可以在线安装,也可以下载对应 .iso
文件本地安装,
我这里是本地安装,选择源头,下载iso
download
->generic mirror.ctan.org url
->TEX Live->
->Images
->iso
然后安装,我准备用vscode作为编辑器
是否安装成功可以用 tex -v
查看
需要下载 LaTwx Workshop
插件,并配置环境(略)
时间原因,先放一个大致模板,后面来完善
1 | \documentclass[12pt,a4paper,oneside]{ctexart} |
编译之后就能查看正常的 pdf
格式了
今天在使用电化学工作站的时候,需要做大量重复的设置并保存文件,发现及其繁琐,等测试完又得重新点一下。于是想实现自动化控制的,改用脚本去做。希望各位苦于配置参数的同学能解放双手。
刚开始是想用大漠插件去实现的,做起来比较复杂,然后发现实验室的机器还在用十年前的配置,这都2202年了,这个机器还用的是翼龙二双核处理器,严重怀疑考进去的脚本能不能运行;
后面去网上找了找解决办法,发现不用自己写,实验室的电化学工作站的机型是CHI660D,本身自带宏命令,多次实验,只需要提前配置好参数和命令就好了,每次运行完,只需要换另一组测试的电极,然后重新修改一下保存路径就行了
宏的编写格式如下
1 | folder:/*存储文件的路径*/ |
使用时,需要修改 folder
和 save
,tsave
下的路径,folder
表示在一个目录下,save
表示存储的文件名,依然可以在前面加路径,save存储的是一个bin文件,tsave表示存储为txt格式的文件
tech 表示需要做的实验名,比如cv表示伏安曲线 ,IMP表示交流阻抗(我们都是叫的EIS,但是不同机器命名不同,具体可以参考帮助文档或者自己手动测一个实验,看看最后输出的图底下写的是什么名称)
注意
小结
写这个命令其实很简单,但难的在于查找对应的参数名,而由于一些特殊原因,这学校的机器里压根就没有文档查,我只能去网上查找;各个属性有时候并不严格对应,比如扫描段数叫segment,但实际这个参数设置为cl,就因为这个,我到处找文档,测试命令
另附上一些查过的链接以及参数
链接
知乎CHI660系列电化学测试软件,有没有小程序让学生能像色谱一样设置参数后批量自动测试保存?
这个老哥更狠,直接用python写了自动生成宏命令的脚本,他的output.txt就是输出的宏命令,可以参考下。github上的python脚本CHI660_Macro
]]>随便写写
今天写markdown时候,发现typora开始收费了,而且是强制跟新的那种,不跟新不能用的那种
这让我一个穷苦学生怎么办呀,只能卸载,另谋高就;在找编辑器的时候发现有人说vscode就挺好用的,一试,嗯果然不错
1 | vscode yyds!!! |
就是快捷键还要熟悉一下
过去不是已经过去的事件,时间,过去是已经被排除的,顽固的剩余下的力量,是个剩余;
未来不是将要发生的事情,未来是变革性的,挑战性的,降临性的力量;
现在是个中介,中介联系着过去和未来;
]]>学习链接的过程,有助于构造大型程序,有助于理解虚拟内存,分页等概念,有助于理解语言的作用域,本章内容来自深入理解计算机操作系统。(这一章很多内容都需要参考编译原理,因此花了很多时间整理)
链接是将各种代码数据片段合并为一个单一文件的过程;链接存在的意义,就是为了将一个程序分开编译,编写时,只需修改小的模块,再通过连接器链接就行。链接可以在程序编译时,加载时,运行时执行。
首先,编辑代码,形成一个代码文件,经过预处理阶段;预处理阶段,主要是对文本进行替换,包括头文件的引入,宏定义的替换;处理完成后,在进行编译,这部分涉及编译原理的相关内容,组要做了下列内容
经过编译后,在有汇编器转成汇编代码,此时代码以指令的形式表示,最后一步链接,链接完成后,就是obj目标文件,此时是机器代码01表示,可以直接运行
最终程序被加载到内存中运行
内存模型
例如有两个片段mian.c
和sum.c
mian.c
1 | int sum(int x,int y); |
sum.c
1 | int sum(int x,int y) |
首先,编译器会将两个c程序预处理,比如引入头文件等,宏定义等
预处理器(cpp)
1 | main.c->mian.isum.c->sum.i |
再将中间.i
文件转成ASCII汇编语言文件
编译器(cc1)
1 | main.i->mian.ssum.i->sum.s |
再将汇编文件转成可重定位目标文件
汇编器(as)
1 | main.s->mian.osum.s->sum.o |
最后由连接器(ld),将两个目标文件以及必要系统文件组合起来,生成一个可执行文件
1 | mian.o,sum.o->prog |
最后,系统执行prog
时,由loader函数将程序加载到内存
这部分参考了深入理解计算机系统0F:链接ELF头部](https://www.bilibili.com/video/BV1MX4y1576E)
以最简单的helloworld为例,在编译后,编译器也不知道printf的具体实现代码的位置,此时的代码是非标准型代码,要转换成标准std代码;printf
此时在程序p1.o
外部,当程序运行到external printf
处时,可以先给真正的printf
代码留个空位置,通过ELF的机制,使链接器能找到所定义的代码(Executable可执行Linkable可链接Formate格式)
ELF功能
链接过程
ELF头对应的含义
1 | ELF头含义 |
SHT的范围[offset,num*size]
有了SHT后,编译器就可以根据SHT的各种信息去索引对应的代码段
符号解析
详细见龙书
将符号引用和符号定义关联起来,就是将变量(符号定义)与真实的数据地址(符号引用)映射起来,首先给个地址,再加个偏移量,就确定了一个数据
符号表格式
1 | typedef struct{ |
bind高四位,type低四位;
binding | 备注 | type | 备注 |
---|---|---|---|
weak | __attribute__((weak))修饰 | notype | 未定义的类型 |
local | static修饰 | function | 函数 |
global | extern修饰 | object | 数据 |
符号由汇编器构造,编译器会将符号输出到.s文件
在编译期时,编译器会进行符号映射,把符号和地址关联上,并根据类型给出对应偏移;链接器会根据binding维护不同文件之间的变量关系。
在编译期,会有三个伪节,ABS不可重定位的符号,UNDEF未定义的符号,COMMON未初始化的全局变量,是个零时性的(tentative)节。当链接器完成后,符号表中的value就是个绝对的运行地址了,同时也没有这些伪节了,因为此时程序已经确定了。
有个程序如下
1 | extern void func(); |
当程序到func()时候,会发现是个外部引用,无法处理,这时,在以(I1,I2···In)的URM程序,会指向In+1,此时,就转化成了标准程序,In+1可称为占位项或重定位项
实现重定位功能的就是目标文件
每一个目标文件就是个字节序列,目标文件又分为可重定位目标文件
,可执行目标文件
,共享的目标文件
可重定位目标文件:可以和其他目标文件合并,生成一个可执行目标文件
可执行目标文件:可以直接放到内存中执行的文件
共享的目标文件:可以在加载时或者程序运行时,动态的加载到内存中链接
重定位可以分成两步
通俗来说就是合并表;首先,各个symblol表会定义不同符号,然后编译器根据所有符号表的各个符号定义,按照解析的三个原则,确定一个唯一的符号表map_symbol,然后合并section时,各个节先去符号表中找对应的符号,然后构建对应的节。
通俗来说就是修改上面生成表的地址,改为正确的运行地址
重定位只有两个段需要引用,.text
函数和.data
数据,如果在.text
节引用就是.rel.text
,如果在.data
节引用就是.rel.data
重定位条目结构
1 | typedef struct |
info是个64位的值,高32位表示重定位类型,低32位表示引用符号。重定位最主要的连个类型就是相对地址引用和绝对地址引用
深入理解计算机操作系统(P480)给了一组重定位算法
1 | foreach section s { |
其中
R_X86_64_PC32
:相对地址引用
R_X86_64_32
:绝对地址引用
ADDR(s)
:每个节
ADDR(r.symbol)
:节运行时地址
相对地址引用
计算引用的运行时地址
1 | refaddr = ADDR(s) + r.offset |
更新引用
1 | *refptr = (unsigned) (ADDR(r.symbol) + r.addend - refaddr) |
绝对地址引用
链接器从偏移量 0xa 开始绝对引用
1 | ADDR(r.symbol) = ADDR(array) = 0xFFFFFF |
更新引用
1 | *refptr = (unsigned) (ADDR(r.symbol) + r.addend) |
PHT维护了表实现了片的内存关系,使可执行文件连续的片可以很容易的被映射到内存上
1 | off目标文件偏移 |
对于静态链接,如果有n个EOF程序文件,它们的源码中都引用了malloc 的定义,那么malloc的.text 与.data就会被复制n次。这对于磁盘上的程序文件而言还算可以接受,因为我们总是假设磁盘有足够大的储存空间。但是内存是更加稀缺的资源,如果这n个程序都在内存上运行,采用静态链接的话,那么内存上就有存在 malloc的n份拷贝,这无疑是对资源的浪费。
那么如果一个程序块如果被多次引用,那么就可以只在内存中存储一份,然后以共享的方式给各个块去使用,这就是共享库的意义。共享库以动态链接的方式被程序引用。
为实现动态链接,使用了位置无关代码(Position-Independent Code,PIC)的技术。PIC的实现依赖于一个简单的事实:EOF文件的Segment是按照它们在磁盘文件中的结构,被复制到运行时内存中的。因此,在.text,.rodata,.data构成的连续虚拟内存中,对任意两个符号(函数或变量)S1与S2,它们在磁盘上的地址相差是个定值;GOT本身就是对.text的一个偏移,这样只要在运行时确定动态库Mmap的地址就完成了动态链接过程
GOT解决了对共享库中全局变量的引用,对函数动态链接就是用了函数连接表(Procedure Linkage Table, PLT),GOT和PLT共同配合实现
指令跳转到 plt 表
plt 表判断其对应的 got 表项是否已经被重定位
如果重定位完成,plt 代码跳转到目标地址执行
如果未重定位,调用动态链接器为当前的引用进行重定位,重定位完成之后再跳转。
]]>前天开始上了开学来的第一节课,第一节课老师总是要做点收心工作的,谈到了后面的规划,比如要不要读博;本来,挺长时间没有想的一个事儿了,现在好像又有了新的想法;我去读博是可能的,但是这个过程应该会比我想象的难的多。
从目的上说,我确实是想做出一些东西出来,读博做科研确实可以满足;从时间上来说,我还有时间和精力去准备考试,现在研一下,一天除去上课,和实验室的时间,一天可以抽两个小时出来准备,到了研二研三,就直接没课了,那个时候可能大部分时间就在实验室了,从现在的经验看,做实验会有大量时间去等实验结果,所以也还是会有部分时间的;目的明确了,也有时间分出来,剩下的就是计划和执行了,需要有自制力去完成。
我准备毕业了考回计算机学硕,然后再读博。那么就需要好好准备,考研有四门,政治,英语,数学和专业课;政治可以到时候再看,英语和数学就可以从现在开始复习了;英语每天要背单词,尽量多看,每天一个小时左右吧;数学和专业课,也都需要看;那就每一门都分一个小时来;除此之外,还有现在的导师的任务需要完成。
]]>今天用npm装了好几次electron装不上,改用yarn装好了
安装步骤
在windows上需要去官网上下载,覆盖旧的node版本
查看是否安装好,可用node -v
查看版本
查看npm版本npm -v
npm install yarn -g
安装完后查看yarn版本
yarn -v
更换淘宝源
yarn config set registry https://registry.npm.taobao.org/
yarn global add electron
]]>npm安装慢或许这也是一种解决方法链接
今天学习了一下如何用python-docx库处理word文档
vscode,python,vscode的python插件
安装python-docx库
1 | pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple python-docx |
安装好后需要,导入vscode
1 | pip install python-docx |
本次需要引入大量参考文献,已经有了所有文献的文字信息,需要修改对应格式
例子
1 | [1] Dehghani F, Omidi F, Heravizadeh O, et al. Occupational health risk assessment of volatile organic compounds emitted from the coke production unit of a steel plant[J]. International journal of occupational safety and ergonomics: JOSE. 2020, 26(2):227-232. |
要求,需要把所有 []
,改成上标
分析的时候可以利用word的查找功能,补充word的查找通配符
1 | [^#]匹配单个数字 |
ctrl+shift+‘+’ 上标
当我开始写的时候,发现,word的替换功能已经给实现好了,不用写了,这次算是初步使用了一下,水了一篇。
补充
word的替换 ctrl+h
快捷键
查找 \[[0-9]{3}\]
,查找【】内三位数字 \[*\]
,【】内任意字符(使用通配符)
今天这张我不知道取什么名字好,算是写一下新学期计划吧。
今天是开学第一天,刚解除疫情隔离;外面出太阳了,但依然只两三度,所以还是要穿袄子;学校有个湖,水都冻上了,估计过几天也都化掉了;一切都显现着冬天快要过去,春天就要来了;天气变化了,可惜,口罩还是得依然带,好像这疫情弄不完一样。
新学期开始了,有的同学都说着,谁谁谁又准备好了一篇论文,准备发表,弄的室友都紧张起来了;我呢,就感觉一般般,论文关系着我毕业,也是很重要的,要说紧张吧,也不至于,毕竟时间还长,我的目标就是顺利毕业,尽量做到最好了;要说更远的科研,我不觉得我有那个志向,追求普遍性,也并不只有科研一条路;除了学业上没啥进展,爱好方面也没啥进步;我想写一点有内容的博客出来,现在看看,也离这个目标比较远,现在写的好像都在记流水帐;以前想做的无人机,也没动静了,就只在嘴上一说,计划会做,后面啥也没动。
我记得胡适以前写日记也是,昨天打牌,今天说不能打牌了,明天继续打牌,我跟大师不同的是,我喜欢打游戏,他是打牌;对于游戏我想,需要分析他的发生学机制,游戏为什么他会吸引人?如何让人上瘾?
我以原神为例,设计者提供了一个虚拟的世界,提瓦特大陆,在这个世界里,又有不同元素的国家,每个国家都有对应的特色,这些种种,都有现实生活的影子,比如璃月,就有浓郁的中国风,他的音乐,建筑,风景,好像都在不断叙述一个命题,这就是真实世界的样子;于是,玩家在游玩的时候,一定程度上就会短路,对于操控的角色,玩家就会理所当然的带入自己,认为角色就是自己,角色做出的操作就是自己做出的,这个维度上,玩家和角色就是一体的,玩家会和角色一起共呼吸共命运;在设计者创建的虚拟世界中,玩家在操作的时候,会误以为,自己就在真实世界中;其实这就是设计者所构建出来的,虚假的真实,即沉迷;但是,再高明的设计者,也受限于各种因素,不可能完全把现实世界照搬进去,于是,在这里,玩家又与角色产生了割裂,玩家沉浸在游戏中,即使在某一刻他觉得的,手上操作的角色就是自己,但之后会有更多事实提醒他,这只是他玩的一款游戏;这之中就有了一种矛盾,玩家既沉迷游戏,但又清楚的知道,自己不过玩的是一种游戏;在这种对立中,玩家就好像体验到了一种虚假的自由,我沉迷进去,受到这个虚拟世界的支配,但我又是跳脱这个世界的纯在,我是独立的,我有自由意志,能去操作角色的行为;在玩原神时候,尽管他的剧情,对话花样百出,但是,玩家依然能察觉到,他是被设计出来的,是一种机械的,僵死的机制,是不自由的,低阶的;于此相对的玩家在其中,却是自由的,可以去任何地方,做任何选择(这些看似是多选项,但依然是被设计者设计出来的,比如某些剧情杀),玩家可以尽情的嘲笑这个机制,这个怪物走路这么傻,被玩家秒杀,以此来凸显自己的高级,自己的自由;综上,我觉得游戏吸引人的原因之一,可能是来自于设计者的提供了一种虚假的自由,这个和现实就有了对比,毕竟现实不能为所欲为。
吸引的地方解决了,上瘾是因为啥呢?还是以原神为例,游戏中是等级制,高级一定比低级的参数高,能更好的再生产(击杀怪物获得奖励),而角色实力的提升是和体力挂钩的,一天的所产的体力是一定的,所以一天的提升是有限的(氪金除外),游戏中有两种货币,一种是魔拉,相当于金钱,一种是原石,用来抽取强力的角色,除了货币之外,还有地图上各种资源,这些都可以看作基本的生产资料,角色决定了基础参数,要提高这些参数再生产的话,就提高自己的生产力,这就需要海量的资源,拿到这些资源的方式就是做各种任务,跑图收集,可以看作生产中的劳动,玩家通过劳动,提高自己生产力;此外,还有一种方式,就是氪金,买大量的原石去抽奖,抽取更高的属性的人物(这些人物一般都有高强度的伤害倍率,或则好看的外表),这种方式,可以立刻提高人物的基础属性,更快速的刷怪刷本,更快的成长;并且,游戏内有个机制,就是不同人物之间的属性配合,可以打出更高的伤害,这个机制更加促进了氪金程度(因为,强力的五星人物只能通过原石抽卡获得,而一天通过任务领取的原石数量一定);以上,应该讲清楚原神这个游戏的盈利逻辑了,游戏提供了一个虚拟的空间,这个空间设计了一种虚假的自由,吸引玩家进场;然后,逻辑和现实一样,如果玩家想通过劳动以提高生产力,那么氪金可以更快的完成个任务(部分玩家并不热衷提高人物数值,对游戏任务爱做不做,风景党,所以氪金对他们无所谓)。既然逻辑和现实差不多,那么为什么玩家宁愿呆在游戏里上瘾,我觉得可能是虚拟和现实的差异导致的;在游戏里面,会有各种不同的任务几乎做不完,即使做完每天还会刷新,而且,任务都是即使性的,不需要花费多大力气就能完成,立即反馈,马上享乐;现实不同,人类所有伟大的成就都是靠艰辛的努力实现的;以此相比,即时享乐看上去那么诱人,所以,这可能是上瘾的一种解释。
这个问题我还会思考,游戏也仅以分析的原神为本,其他的不一定满足;玩游戏一方面可以愉悦身心,方便人更好的进行生产,一方面又确实让人沉迷,倒置浪费了时间;所以,玩游戏可以玩,但要抵制上瘾;上面分析了一大堆,我想,既然知道了游戏是骗自己的,那我为什么不去骗他,我让游戏自己玩,去那儿空转;原神这个游戏,不联机的话就是个单机游戏,我决定写个脚本让他自己玩,每日任务自己完成,也不用我来耗费时间了,也不影响别人。
后面,无人机方面,也要开始准备了,光说喜欢不行动就不是真的喜欢,所以后面要准备赚点钱买设备了,至少需要一块电烙铁和万用表,目前最需要的是行动。学业方面也要跟进,尽量多学一点知识。
]]>1 | //创建数组,下标0开始 |
遍历数组
1 | //for循环遍历略,js提供了for-each,IE8以上使用 |
js的对象声明
1 | var obj =new Object(); |
要添加对象属性的时候直接赋值就行,对象的属性也可以是个函数,即方法
1 | obj.name=""; |
调用对象
1 | obj.name; |
删除对象属性
1 | delete obj.name; |
更常见的操作是以[]
来操作
1 | var a=1; |
检查obj是否有某属性
1 | a in obj; |
js的对象是地址传递,对象存储在堆空间种;其他数据类型是值传递,存储在栈中
计较两个基本数据类型的时候比较的是值,引用对象是比较地址
tyorof
可以显示数据类型
枚举对象for in 语句
1 | for(var n in obj){ |
回收对象(设为空即可,浏览器会自动回收垃圾)
1 | obj=null; |
在js中有三种对象,原生对象(js自带),宿主对象(浏览器环境),自定义对象(自建)
Document Obiect Model文档对象模型,JS通过DOM来对HTML文档进行操作
节点
DocumentType:doctype标签(比如<!DOCTYPE html>
)。
Element:网页的各种HTML标签(比如<body>、<a>
等)。
Attribute:网页元素的属性(比如class="right"
)。
Text:标签之间或标签包含的文本。
Comment:注释。
DocumentFragment:文档的片段。
方法 | 说明 |
---|---|
document.getElementById() | 通过id获取元素 |
document.getElementsByTagName() | 通过标签名获取元素 |
document.getElementsByClassName() | 通过class获取元素 |
document.getElementsByName() | 通过name获取元素 |
document.querySelector() | 通过选择器获取元素,只获取第1个 |
document.querySelectorAll() | 通过选择器获取元素,获取所有 |
document.createElement() | 创建元素节点 |
document.createTextNode() | 创建文本节点 |
document.write() | 输出内容 |
document.writeln() | 输出内容并换行 |
详见DOM模型
函数声明
1 | function a (){} |
break
跳出当前循环
return
结束当前函数并返回值
内部函数
1 | (function a (){})() |
表示第一个括号内的函数是个整体,然后他本身作为一个函数名立即调用
构造函数
1 | function Person(name,age){ |
this函数的上下文,谁调用this指向谁,在构造函数中,指向实例
call函数和apply函数可以改变this作为实例对象
call(obj,a)
方法可以传递实参
apply(obj,[])
方法需要将实参封装到数组中传递
1 | //使用instanceof检查某个对象是不构造函数的实例 |
参数列表,所有传递的实参都会在arguments
中保存
准备趁假期系统学一下前端相关知识,h5和css3以后再介绍
html是超文本标记语言,就是用来记录文本的标记,由一个个标签组成<></>
,css层叠样式表,主要对HTML进行样式设置,javascript用来处理网页的交互
一般网页由一下部分组成
1 | <!DOCTYPE html> |
常用标签
标签 | 意义 |
---|---|
<h> | 标题 |
<q> | 引用 |
<p> | 段落 |
<br> | 换行 |
<strong> | 强调 |
列表
1 | <!-- 有序列表 --> |
链接
1 | <a href="https://www.baidu.com" target="_self"> |
a标签的target
,指定还是新建页面打开
图片
1 | <img src=".png" alt="蒂姆·伯纳斯·李爵士,万维网的发明人"> |
音频
1 | <audio src=".mp3" controls autoplay loop></audio> |
controls
允许控制autoplay
自动播放loop
循环播放视频
1 | <video controls> |
表格
1 | <table> |
1 | 2 | 3 |
表单form
用于提交数据,action
表示位置s
1 | <form action="" method="post"> |
下拉列表
1 | <select name=""> |
有一些标签IE兼容性不好,等以后真的工作需要再来整理了
对于简单的样式可以直接写到行内
1 | <p style=""></p> |
也可以写到块里
1 | <style> |
一般网页的样式都有单独样式,外部引入就好
1 | <link rel="stylesheet" href="./style.css"> |
css的基本语法是先声明要设置的标签,然后在内部设置元素
元素设置采用键值对的方式,一个元素对应一个值,;
结尾
1 | /*选取所有元素设置*/ |
元素选择器,如p{}
h1{}
div{}
类选择器(类名通常是自定的),.classname{}
ID选择器,#idname{}
属性选择器
1 | /*开头*/ |
交集选择器,选中含多个条件的元素.a.b{}
并集选择器,同时选中多个元素a,b{}
由于页面经常嵌套标签,所有又是要找后代元素
子元素选择,父元素 > 子元素{}
后代元素选择,祖先 后代{}
还有一些伪类参数,以:
表示
:first-child
第一个子元素
:last-child
最后一个子元素
:nth-child()
选中第n个子元素
:not()
将符合条件的元素从选择器中去除
css盒子模型
对应属性查阅手册
鞋盒就是有内容,内边距,边框,外边距,类似鞋盒一样
通过设置不同<div>
标签来控制不同的板块
盒子模型有两种布局:定位和浮动
定位布局可以用相对的方式,也可用绝对的方式
相对位置position::relative
绝对位置position::absolute
浮动布局 float
none
默认值,元素不浮动left
元素向左浮动right
元素向右浮动less是一种css的预处理器,有助于复用代码
声明变量
1 | @a:1; |
混合(以.开头,()内跟参数,变量值是默认值,可以在调用时候动态输入,类似函数,减少重复代码)
1 | .a(@w:10px, @h:10px){ |
如果每个部分都需要初始化,也可以写类似c++的构造函数,通过匹配模式实现
1 | .a(@_, @h){ |
@
表示匹配,_
表示所有的
同样的,通过匹配模式也变相的实现了重载
在匹配模式种,
表示连接,and
相当于&&,not
表示出了之外
继承
1 | .a{ |
js见Autojs签到
]]>写好脚本之后并不知道执行好没有,就想有个反馈的机制;原先计划看能不能发到微信上,先给小程序的接口发数据,然后让小程序通知微信;后来了解到,推送消息需要企业微信,比较麻烦,只好另寻他法;想了想,本来是本地的数据,为啥还要引入服务器呢,直接在本地写再查看不就行了。
检测是否打卡只要检测对应坐标是否变绿就行了
1 | //z是匹配颜色,xy对应坐标 |
然后就文件操作,读和写
1 | var path="/路径名" |