Kaito's Blog

致力成为一枚silver bullet.

0%

11、门

通过串联或并联的开关组成继电器完成简单的逻辑任务,继电器的组合叫做逻辑门,逻辑门一般有两个或多个输入

继电器的优点是:可以被其他继电器控制,而不需要人工控制,意味着简单的逻辑门组合起来可以完成复杂的功能。

如何连接继电器,是逻辑门的关键:

  • 继电器串联:与门(AND)
  • 继电器并联:或门(OR)
  • 反向器:NOT
  • 只有1-1输出0:或与门(NAND)
  • 只有0-0输出1:或非门(NOR)
  • 延迟信号:缓冲器

利用4个门与2个反向器连接的电路叫做2-4译码器:2个输入,输出4种不同的信号。

同样的原理可以制造出3-8译码器或4-16译码器。

由缓冲器、反向器、四种基本逻辑门可以组成复杂电路。

12、二进制加法器

一对二进制数相加的结果,有2个数位:加法位、进位位,这2个数位计算是分别进行的。

  • 进位位逻辑:与门
  • 加法位逻辑:或门 + 与非门 = 异或门(XOR)

2个输入 –> 异或门 –> 结果 –> 与门 = 半加器

2个半加器 + 或门 = 全加器

  • 组成与门、或门、与非门(3 * 2 = 6个继电器)
  • 异或门 + 与门 = 半加器(8个继电器)
  • 2个半加器 + 或门 = 全加器(18个继电器)
  • 8个全加器= 8位二进制加法器(144个继电器)

全加器的计算原理就是计算机的加法原理,但这种进位方式叫行波进位(脉冲进位),更快的加法器使用前置进位提高运算速度。

现如今的计算机使用晶体管,耗能低、价格低、体积小,但如果搭建一个8位加法器依然需要144个晶体管,如果使用前置进位法,将用到更多的晶体管,但电路是体积非常小。

13、如何实现减法

十进制减法计算步骤:

  • 减数大于被减数:被减数 - 减数 = 减数位个9 - 减数 + 被减数 + 1 - 10^减数位数
  • 减数小于被减数:被减数 - 减数 = -(减数位个9 - (减数位个9 - 减数 + 被减数))

二进制减法计算步骤:

  • 减数大于被减数:被减数 - 减数 = 减数位个1 - 减数 + 被减数 + 1 - 2^减数位数
  • 减数小于被减数:被减数 - 减数 = -(减数位个1 - (减数位个1 - 减数 + 被减数))

8个异或门连接为求补器1个求补器+1个8位加法器+1个异或门形成可完成加法和减法的电路。

用2的补码来表示二进制中的负数,最高位代表符号位。

14、反馈与触发器

2开关+电池+磁铁可以完成一个循环电路,如果连上金属簧片可以形成一个蜂鸣器,也可以叫振荡器

振荡器可以在不需要人干涉的情况下,自发工作。

振荡器在0和1之间交替规律变化,又称为时钟

振荡器从某个初始状态开始,经过一段时间又回到初始状态的间隔,称为周期

周期的倒数就是振荡器的频率,也叫赫兹

2个或非门+2个开关+1个灯泡的电路,左边或非门的输出是右边或非门的输入,而右边或非门的输出是左边或非门的输入,这种连接方式称之为反馈

而当2个开关都断开时,电路有2个稳定态,这类电路统称为触发器触发器可以“记住”某些信息,这类电路叫做R-S(复位/置位)触发器,这类触发器的特点在于:可以记住哪个输入端最终状态为1

现在把2个输入分别叫做数据端和保持位,经过分析,保持位为0意味着输出不被数据端所影响,那么电路演变可以为:增加2个与门,变成3个输入:复位、保持位、置位,此时的电路和之前电路功能是相同的。

但是我们只想要2个输入,继续分析电路后得出:2个输入端同时为0是无意义的,而同时为1是非法的,因此只要将保持位设置为0,即可完成相同功能,电路演变为:复位和置位变为1个数据端+反向器代替,这样就有2个输入了:保持位+数据端。

此时的电路称为电平触发的D型触发器,即当保持位输入为某一特定电平,触发器保存数据端的输入。

通常情况下,保持位又叫做时钟,它可以在0和1之间规律来回变化,但此时的时钟仅用来指示什么时候保存数据。

至此,此电路就是电平触发的D型锁存器,也叫1位存储器,它可以锁存住1位数据并保持它,以便将来使用。

由2级R-S触发器连接的电路,时钟端既控制第一级R-S触发器,也控制着第二级,只有当时钟信号由0变为1时,数据端的输入才被保存下来,输出0到1或1到0,而下级触发器的频率正好是上级触发器频率的一半,这种电路叫分频器,就这样多个振荡器连接下去,就形成了计数器

至此,我们可以通过使用继电器形成的电路来加法、减法和计数了。

15、字节与十六进制

8位代表1个字节(byte),追溯历史原因,8位可以表示0-255共256种不同的事物,而最早的书面语言的基本字符都少于256个,所以使用8位表示1个字节是比较理想的手段,通用1个字节也可以表示RGB256种颜色值。

如果要表达的事物1个字节不够用,则可以扩展字节,采用2个字节甚至更多字节来表示,表示起来也很方便(扩展方便)。

把1个字节分为每4位为1组,进而演化出16进制,1个16进制位表示4位,表达起来也很方便。

阅读全文 »

由于最近正在看《编码:隐匿在计算机软硬件背后的语言》,整理并记下读书笔记。

1、至亲密友

2个人远距离交流,可以通过手电筒开和关进行通信,但想表达的文字太复杂,手电筒开关次数太多,难度非常大。

引出莫尔斯电码,使用点和划(短闪和长闪)通信。

结论:

  • 编码是用来在机器和人之间信息传递的方式,编码就是交流。

  • 编码无处不在,手电筒的闪烁,英语词汇,空气中的比划,手语,布莱叶盲文。

  • 计算机里存储和传递数字、声音、音乐、图片和电影,处理后呈现出信息与人类沟通。

2、编码与组合

莫尔斯码发送简单,但是接收后解析困难,解决方案:构建信息与编码的图表

结论:

  • 码字的数目 = 2^编码位数

  • 编码进行适合的组合,得出完整的信息表示。

3、布莱叶盲文与二进制码

布莱叶觉得最初的盲文编码过于复杂,不利于长文本阅读,随之改造盲文编码,使用2*3的矩阵,利用凸/平点表示一个字母信息。此标准沿用至今,改造后有了二级布莱叶盲文(使用很多缩写,一个2*3矩阵表示一个单词)

结论:使用6位二进制码表示出2^6=64种编码表示,并且根据上下文有双重身份。

4、手电筒的剖析

原子构成:中子、质子、电子。

一个原子的中电子数=质子数,如果电子从原子中脱离,就会产生电流

当质子与电子出现失衡,就会自我修复,从其他物体带走电子,例如地毯带走脚上的电子,自己感觉被静电电到了。

电路中的电子不断从一个原子移动到下一个原子,就形成了电流

电池内部经过化学反应,能够使多余的自由电子聚集到负极(阴极),正极(阳极)变得急需电子,化学能转为电能

电池为电路提供电能,反过来,电路为电池内化学反应提供条件,化学反应持续进行,化学物质被消耗完,电池没电。

导体:最外层电子容易逃逸。绝缘体:阻抗性很大(电阻)。

交代出:电流、电压、电阻、功率。

白炽灯发光原理:钨丝电阻非常小,电流经过后钨丝变热达到燃点,由于存在真空中,不会燃烧,所以发亮!

5、绕过拐角的通信

远距离如何通信?通过电源+导线的方式,实现远距离通信。

距离越远,需要的导线越长,成本高并且电阻大,需要强电压。

如果电压足够强,电池足够大,通信2方只需要一端接地,另一端使用一根导线即可,减少成本。

结论:使用导线可以构建出绕过拐角、视线之外的发报系统,不受距离限制,涉及问题:电流、电阻等。

阅读全文 »

最近公司线上服务器都换上了堡垒机登陆,这样每个开发人员都只分配堡垒机账号,然后运维人员划分对应的权限机器就好了,相比之前的跳板机登陆要有很多优点:

  • 只需给开发人员分配一个账号和密码,避免机器过多账号繁多的情况;
  • 运维人员分配机器权限便捷,只需给开发人员账号分配权限机器即可;
  • 相对跳板机来说更安全,堡垒机登陆到线上服务器后,可以记录每个用户的所有操作记录;

大概说下堡垒机的使用机制:

  • 开发人员使用自己的账号登陆堡垒机,输入账号和密码
  • 登陆成功后,堡垒机会列出该账户下有权限可操作的服务器列表,每个服务器对应一个数字
  • 开发人员输入对应的服务器数字或者选择搜索选项搜索服务器
  • 如果是直接选择了服务器,则会列出可用的账户,如果是搜索服务器,则需输入服务器IP
  • 然后堡垒机会列出可用的账号列表,每个账户对应一个数字
  • 输入账户对应的数字,选择使用哪个账户操作服务器,进入服务器,登陆完成

其实说白了,和很多客服电话原理差不多,列出来多个选项菜单供你选择,然后一步步选择,最终进入服务器。

也就是说我进入一台线上服务器,需要输入账号密码->选择/搜索服务器->选择操作账户->登陆成功这几个步骤。每次登陆服务器只是IP不同,但都需要频繁输入相同的数字进行选择,肯定受不了,最好的方式是,能不能通过一个脚本,根据命令行的提示信息,自动选择,最终进到服务器。当然,答案是可以的,这里就使用到了Expect工具。

简单介绍下Expect:

Expect是Unix系统中用来进行自动化控制和测试的软件工具,该工具利用Unix伪终端包装其子进程,允许任意程序通过终端接入进行自动化控制。

现在很多终端工具客户端都提供这些操作,例如SecureCRTXShell都是支持的,最终都是使用的Expect。

这些工具的使用就不介绍了,这里主要介绍一下不借助工具,在终端编写脚本来完成此功能,例如在Linux、Mac终端下进行登录操作。

阅读全文 »

阿米洛 侧刻 红轴

终于等到你,还好我没放弃! 机械键盘入坑太久,无法自拔。

先后体验过的机械键盘有茶轴、青轴、红轴。

第一把,樱桃cherry G80-3000茶轴,传说中的入门神器!无图,请自行脑补。

第二把,KBT race2青轴,话说玩机械键盘都不体验下青轴啪啪啪的声音,都不好意思行走机械键盘界。

KBT Race2 青轴

不得不说,外观真是漂亮,大小适中!服役了不到一年,手指酸痛受不了了。

后来在知乎上看到大神推荐只玩红轴,瞬间走火入魔,神经向往,最终,购入现在的红轴键盘!

阿米洛 侧刻 红轴

阿米洛 侧刻 红轴

阿米洛 侧刻 红轴

阅读全文 »

该来的总会来的,MacBook、iPad mini在手中已久,唯一差的就是iPhone了,最近被哥们刺激到后,一激动就入手了,这比预计来的要早一些。

Iphone 6s

iPhone6s上手已有小半个月,各项体验都还不错。由于从长久的安卓阵营转到iOS麾下,有些地方还有些不太适应,当然,大部分的体验还是很满意的,这篇文章就说一说其优点顺便吐槽下吧。

先交代下背景,之前用的是一台小米4,3G内存版,MIUI7开发版操作系统。

较常用的几点比较如下:

优点

流畅度

  • 6s不负众望,各应用间快速切换,应用内浏览极度流畅,不用强制关闭进程;
  • 米4稍逊,打开应用过多后,就需要打开任务管理器杀死后台进程,在一些视频App中会出现卡顿;

TouchID

  • 第一次使用指纹解锁功能,用户体验非常爽,而且比较了iPhone6,解锁速度上了新台阶,每次想看下时间却都不小心解锁了,想想这速度的提升;
  • 米4木有指纹解锁,所以导致我连数字、图案解锁都懒得设置,因为感觉使用手机的成本太高了;

快速返回

  • 6s在使用App时,需要返回上一级不必一定使用左上角的返回按键,手指在屏幕左侧向右滑动即可;
  • 米4因为有返回按键的存在,使用也还算可以,不过6s体验更佳;

3DTouch

  • 在电话、短信、浏览器、拍照等方法增加了快速使用的便利性,尤其是在浏览网页时,长按链接可不必打开就可预览网页内容;
  • 由于又多了一种维度的使用反馈,以后应该会在游戏App中产生更多的可能性;

LivePhoto

  • 6s在拍照时,自动拍摄前后各1.5秒的短视频,用来记录拍照时的情景,配合3DTouch使用真是富有情怀;
  • 拍摄LivePhoto照片还可以当做手机解锁壁纸,长按屏幕时可以出现动态壁纸的效果;
阅读全文 »

由于之前一直在做爬虫采集相关的开发,这个过程那肯定少不了跟「代理 IP」打交道,这篇文章就来记录一下,如何实现一个爬虫代理服务,本篇文章主要以讲解思路为主。

起因

做过爬虫的人应该都知道,抓的网站和数据多了,如果爬虫抓取速度过快,免不了触发网站的防爬机制。而这些网站应对爬虫的办法,几乎用的同一招就是封 IP 。

那么我们还想稳定、持续地抓取这些网站的数据,如何解决呢?一般解决方案有2个:

  • 使用同一个服务器 IP 抓取网站数据,但是放慢速度
  • 使用多个代理 IP 抓取数据

第一种方案牺牲的是时间和速度,但是一般情况下我们的时间是很宝贵的,理想情况下是,用最短的时间获取最多的数据。所以第二种方案是推荐的,那么从哪里可以找到这么多代理 IP 呢?

寻找代理

最直接地,使用搜索引擎去检索。

例如使用 Google、Bing、百度,输入关键字:免费代理 IP,前几页几乎都是提供代理 IP 的网站,逐个打开后观察可以发现,几乎都是一个列表页,这个列表页展示的代理 IP 少则几十个、多则几百个。

但是仔细观察你就会发现,每个网站提供的免费 IP 是有限的,而且拿来用之后你就会发现,有的也已经失效了。毕竟,人家更倾向于你购买他们的付费代理 IP。

身为狡猾的程序猿,当然不能因为这点困难就退缩了。仔细想一下,既然搜索引擎能搜到这么多提供代理的网站,每个网站提供几十或几百个代理 IP,假如有 10 家代理网站,那加在一起也有几百到几千个了。

那么很简单,你要做的事情就是,把这些提供代理 IP 的网站收集起来,写一个采集程序把这些免费代理 IP 抓过来就好了,想想是不是很简单?

测试代理

好了,通过刚才的思路,你可以编写一个采集代理 IP 的程序,然后就可以拿到成百上千的代理 IP 了。当然,收集的代理网站越多,采集到的代理 IP 也就越多,所以我们尽量多收集一些代理网站,越多越好。

等等,这么多代理 IP ,难道别人真的就免费送给你了吗?

当然不是,前面也提到过,这些代理中,有很大一部分已经是失效的了。那怎么办?如何知道哪些代理是有效,哪些是不可用的呢?

很简单,写一个 HTTP 程序,挂上这些代理,访问某一个稳定的网站,然后看是否能正常访问,如果可以正常访问,那么代理 IP 就是可用的,访问失败则说明代理 IP 已失效。

最简单地,我们可以使用 curl 命令就可以测试一个代理是否真的可用:

1
2
# 使用代理 48.139.133.93:3128 访问 网易首页
curl -x "48.139.133.93:3128" "http://www.163.com"

当然,这种方式只是为了演示方便,实际最好的方式是:编写一个多线程的代理测试程序,然后分别使用这些代理去访问某个网站,根据访问的结果,最终就可以输出一批可用的代理 IP。

阅读全文 »

可能是上天对我的眷顾吧,在一个偶然的机会有幸得到一台Mac,从此Mac探索之路一发不可收拾。

记得刚刚使用Mac时,完全小白一枚,但作为程序员应该发挥本职业必备的职业技能,从学习OSX系统、操作技巧到使用各种效率工具,这每一步都源于Blog、知乎、Google的学习。

一个偶然的机会,在学习Mac技巧时,看到一篇Blog,再然后关注了作者的微信公众号,然后到每天关注其推送的内容,然后就在今天,入手了作者的一本书——《MacTalk人生元编程》,在这里也向大家推荐一下。

MacTalk人生元编程

这本书汇集了:Mac技巧、编程、科技人文、人物、工具、职场等内容,不管你是正在使用的Mac用户,或是正在coding之路的程序猿君,都可读来看看。个人由于更加喜欢科技与人文一词,便以此为题名。

此刻我已成为Mac大军中的一员,Promini都已具备,唯一差的武器就是爱疯,预计今年会入手一台,便也无憾了。

尤为喜欢书序中的那句话:

泰山崩于前,我依然沐浴更衣焚香沏茶,诚心正意,手起键落:Hello World!

最近使用python的ORM框架peewee开发项目,遇到一个问题就是:在插入数据后,获取不到数据库生成的自增主键值,然后分析源码后得到解决方案,以此记录。

首先,定义model

class User(Model):

    id = IntegerField(primary_key=True)    
    username = CharField()

    class Meta:
        database = db
        db_table = "user"

其中主键id是整型自增类型。

根据peewee官方文档介绍,插入数据时使用如下:

user = User(username='admin')
user.save()

或

user = User.create(username='admin')

或

id = User.insert(username='admin).execute()

但是获取user.idid结果却为None

于是乎开始看peewee的源码,看到底发生了什么?

首先看Moelcreate方法:

@classmethod
def create(cls, **query):
    inst = cls(**query)
    inst.save(force_insert=True)    # 还是调用本类的save方法
    inst._prepare_instance()
    return inst

发现create方法还是调用本类中得save方法,那么好办了,来看save方法做了些什么?

阅读全文 »

每个开发人员必备的技能,就是如何使用搜索引擎来获取自己最需要的知识,这篇文章介绍使用搜索引擎的一些技巧,注:主要针对Google搜索,其他搜索引擎暂未尝试,部分可用,个人认为百度是用来卖萌的。

精准搜索

最简单地搜索,即输入搜索词,确认,等待返回结果,例如输入“北京什么地方好玩”,结果如下:
常规搜索

但是这个结果是搜索引擎智能帮你分词后的结果,其中一些是你认为不想看到的,那么精准搜索就派上用场了,很简单,在搜索词两边加上英文格式双引号即可,再看结果,是不是明朗很多:
精准搜索

排除搜索

好了,学习了刚才的技巧之后,突然觉得有些范围的内容完全不是自己想要的,例如不想看到关于与百度相关的内容,那么就可以这样用:关键词 -排除关键字,注意,横杠+排除关键字前必须有空格,否则无效。
排除搜索

阅读全文 »

解析页面肯定是写爬虫遇到的最常见的工作,但不要小看这个这个过程,有时它也会令你抓狂。这次写一下关于curl工具的使用,主要介绍一下平时很常用的几项。

curl是利用URL语法在命令行方式下工作的开源文件传输工具,使用这个工具,就能在命令行发起请求,获得响应,而且其命令简单且强大,非常适合用作写爬虫时,解析页面前的模拟工作。

基础

# 发起HTTP请求,并把返回的网页内容显示在屏幕
curl "http://www.example.com"

# 发起HTTP请求,并把返回的网页内容输出到文件
curl "http://www.example.com" > test.html

# 或者用命令-o参数也可达到同样的效果
curl -o test.html "http://www.example.com"

注意:URL地址带上双引号是比较好的习惯,防止URL中带有特殊符号,导致不能解析报错情况。

伪装头信息

有时curl直接访问页面,会得到与浏览器打开不同的结果,所以此时就要伪装头信息,来模拟浏览器的行为,这样返回的数据就跟浏览器看到的一样了。

# 使用-A参数定义User-Agent,模拟浏览器行为
curl -A "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36" "http://www.example.com"

# 使用-e参数定义Referer,表示从哪个页面跳过来的,解决防盗链问题
curl -e "http://www.example.com" "http://detail.example.com"

# 或者使用-H参数自定义头信息,也可定义User-Agent、Referer、Content-Type等信息
curl -H "my-header:xxxxx" "http://www.example.com"

代理访问

或者你用程序频繁访问某个网站,结果人家把你IP封禁了,这时就可以用代理来进行访问。

# 使用-x参数使用代理访问
curl -x "123.45.67.89:8102" "http://www.example.com"
阅读全文 »