原文

想要理解 yield 先要理解 generators 在此之前要理解 iterables

iterables

当创建一个 list 的时候,可以一个一个的读取数据。这种一个一个读取项目元素称作 iteration

>>> mylist = [1, 2, 3]
>>> for i in mylist:
... print(i)
1
2
3

这里 mylist 是 iterable 当使用 list comprehension 时,创建了一个 list 也是 iterable

>>> mylist = [x*x for x in range(3)]
>>> for i in mylist:
... print(i)
0
1
4

所有可以使用 for ... in ... 的都是 iterable; listsstrings
这些 iterables 用着很顺手,但是他们都是存在内存当中的,有时可能并不希望这样,尤其是数据量大的时候

Generators

是 iterators 但是只能迭代一次。Generators 并不在内存存储数据,而是实时生成数据

>>> mygenerator = (x*x for x in range(3))
>>> for i in mygenerator:
... print(i)
0
1
4

使用 () 代替 [] 但是,mygenerator 不能迭代第二次。

yield

是一个关键字,使用上类似 return 函数会返回一个 generator

>>> def createGenerator():
... mylist = range(3)
... for i in mylist:
... yield i*i
...
>>> mygenerator = createGenerator() # create a generator
>>> print(mygenerator) # mygenerator is an object!
<generator object createGenerator at 0xb7555c34>
>>> for i in mygenerator:
... print(i)
0
1
4

当你调用函数的时候,里面的代码并没有执行,只是返回一个 generator 对象。
然后在使用 for 的时候代码会一次执行

opendatatools

pip install opendatatools
pip install html5lib

pip install pyecharts
pip install echarts-countries-pypkg
pip install echarts-china-provinces-pypkg
pip install echarts-china-cities-pypkg

Scrapy

pip install scrapy

  1. 生成项目
    scrapy startproject quotes

  2. 生成spider
    scrapy genspider quotes quotes.toscrape.com

  3. pipeline输出
    settings.py 里面设置
    ITEM_PIPELINES = {
    ‘quotes.pipelines.TextPipeline’: 400,
    ‘quotes.pipelines.MongoPipeline’: 300,
    }
    后面的400,300是序号,数值越小,优先级越高

  4. mongodb 参数在settings里面设置
    pip install pymongo

Scrapy运行流程大概如下:

首先,引擎从调度器中取出一个链接(URL)用于接下来的抓取
引擎把URL封装成一个请求(Request)传给下载器,下载器把资源下载下来,并封装成应答包(Response)
然后,爬虫解析Response
若是解析出实体(Item),则交给实体管道进行进一步的处理。
若是解析出的是链接(URL),则把URL交给Scheduler等待抓取

Obey robots.txt rules

输出中文
但是对于现在版本的可以直接在setting文件中设置:FEED_EXPORT_ENCODING = ‘utf-8’

useragent
. useragent 模仿百度(“Baiduspider…”),2. IP每爬半个小时就换一个IP代理。
随机1-3秒爬一次,爬10次休息10秒,每天只在8-12,18-20点爬,隔几天还休息一下
图像识别(关键词 PIL,tesseract),再对验证码进行了二值化,分词,模式训练之后,识别了小黎的验证码
择了内置浏览器引擎的爬虫(关键词:PhantomJS,Selenium),在浏览器引擎中js 加密脚本算出了正确的结果,又一次拿到了对方的数据。

Twisted

Twisted是用Python实现的基于事件驱动的网络引擎框架。

引用

从架构设计上来说,区块链可以简单的分为三个层次,协议层、扩展层和应用层。其中,协议层又可以分为存储层和网络层,它们相互独立但又不可分割。
6437caef.png

由linux基金会主导的超级账本(HyperLeger),版本库的名字叫Fabric
官方网站:https://www.hyperledger.org/
源码库:https://github.com/hyperledger

知识图谱

aa5371fd.png

Key pool

钱包预先生成 100 个密钥,保存在 key pool。新建地址的时候,使用这里面的未使用密钥创建。
主要用途是减少备份次数,同时防止硬盘损坏时,碰巧使用了新建的地址,导致备份时没有备份到。
旧版默认生成 100 个密钥,可以通过 -keekpool 参数来设置。新版扩充到了 1000 个。

Dapp

参考
by Vitalik Buterin

Dapp(decentralized application) 应用的后端代码运行在去中心化的 peer-to-peer 网络中。
和运行在中心化服务的 app 相比,一个 Dapp 有前端代码和界面,可以调用后端代码,而且前端可以部署在去中心化的存储中例如 Swarm or IPFS
如果 App = frontend + server,那么 Ethereum 的合约是运行在 Ethereum 的全球 p2p 网络中的
那么 DApp = frontend + contracts

Contracts: 去中心化的逻辑处理,运行在 Ethereum Virtual Machine (EVM)
Swarm: 去中心化的存储,作为记账协议而设计的,不依赖于物理存储系统,可以是 IPFS, BitTorrent 或将来发明的存储技术
Whisper: 去中心化的消息处理

下面是使用区块链 + 智能合约 + swarm + whisper
f54277b3.png

666392f1.png

分叉 soft fork

软分叉是把之前的有效区块,认为是无效的,旧节点认为新区块是有效的,新节点区块保持向后兼容性,当新规则启用时作为临时分叉,未升级节点也可以接受已升级节点的区块,同时分叉的新链只接受已升级节点的区块。
一旦启用软分叉之后,就取决于已升级节点能否尽快取得绝对性的大多数份额,否则软分叉将会失败,旧链没有任何影响。
旧版本在新版本拒绝区块时会发现有新版本需要升级,然后完成升级过程。
当大多数矿工完成升级后正式启用新规则,称作 miner-activated softfork (MASF)
当大多数节点协同一致支持新规则,不需要矿工支持时,称作 user-activated softfork (UASF)

硬分叉是一种快速,高优先级,不向后兼容的改变,定义为当实现时产生永久的改变。
新链和旧链是相互平行的,各自应用不同的规则,两条链之间不能互相转移资产
随之而来的是两份资产的问题,用户分别在两条链上同时拥有相同的资产,比如在硬分叉前,旧链中有100个币,那么分叉后,在旧链和新链将同时有100个币,
当然两个链中币的价值也是不同的,因为无法相互转移。

0b1c1105.png
阅读全文 »

什么是共识机制

区块链可以看作一本记录所有交易的分布式公开帐簿,区块链网络中的每个参与者都把它看作一本所有权的权威记录。
公开账本历史数据不可篡改,只允许往后添加,每个节点都具有相同的权限,那么就带来一个问题:
公开账本每个新区块由谁来负责写入?
因为所有节点都一样,如果所有节点同时一起写入账本数据,那么肯定数据会不一致。
因此需要一种机制来保证区块链中的每一区块只能由一个节点来负责写入,
如何选出写入账本数据的节点,这就是共识机制。让平等的参与者按照某种秩序达成一致意见。

所谓的共识就是在人人平等的社会里需要大家共同形成一个共识,产生一个操作者、临时决策者,代表大家来进行中心化的操作,大家按照这个共识来维持去中心化的网络世界。

主流的共识算法有哪些

在分布式网络中如何保证数据一致性。

说到一致性问题,就不得不提大名鼎鼎的拜占庭将军问题。是 Leslie Lamport 1982 年提出用来解释一致性问题的一个虚构模型。拜占庭是古代东罗马帝国的首都,由于地域宽广,守卫边境的多个将军(系统中的多个节点)需要通过信使来传递消息,达成某些一致的决定。但由于将军中可能存在叛徒(系统中节点出错),这些叛徒将努力向不同的将军发送不同的消息,试图会干扰一致性的达成。

结论:
Leslie Lamport 证明,当叛变者不超过1/3时,存在有效的算法,不论叛变者如何折腾,忠诚的将军们总能达成一致的结果。如果叛变者过多,则无法保证一定能达到一致性。

阅读全文 »

JVM加载class文件的原理机制

Java中的所有类,都需要由类加载器装载到JVM中才能运行。
Java的类加载器有三个,对应Java的三种类:负责加载系统类,扩展类,应用类。

  1. 装载:查找和导入class文件;
  2. 连接:
    (1)检查:检查载入的class文件数据的正确性;
    (2)准备:为类的静态变量分配存储空间;
    (3)解析:将符号引用转换成直接引用(这一步是可选的)
  3. 初始化:初始化静态变量,静态代码块。
    这样的过程在程序调用类的静态成员的时候开始执行,所以静态方法main()才会成为一般程序的入口方法。类的构造器也会引发该动作。

多线程相关

如何在Java中实现线程?

  1. 继承 java.lang.Thread 类
  2. 实现 java.lang.Runnable 接口

用什么方式创建线程比较好,用Runnable还是Thread?

Java不支持类的多重继承,但允许你调用多个接口。

Thread 类中的start() 和 run() 方法有什么区别?

start()方法被用来启动新创建的线程,而且start()内部调用了run()方法,这和直接调用run()方法的效果不一样。
当你调用run()方法的时候,只会是在原来的线程中调用,没有新的线程启动,start()方法才会启动新线程。

Java中什么是竞态条件? 举个例子说明。

多线程对一些资源的竞争的时候就会产生竞态条件,如果首先要执行的程序竞争失败排到后面执行了,那么整个程序就会出现一些不确定的bugs。
一个例子就是无序处理

Java中如何停止一个线程?

你可以用volatile 布尔变量来退出run()方法的循环或者是取消任务来中断线程。

一个线程运行时发生异常会怎样?

简单的说,如果异常没有被捕获该线程将会停止执行。

如何在两个线程间共享数据?

你可以通过共享对象来实现这个目的,或者是使用像阻塞队列这样并发的数据结构。
阻塞队列 (BlockingQueue)是Java util.concurrent包下重要的数据结构,BlockingQueue提供了线程安全的队列访问方式:当阻塞队列进行插入数据时,如果队列已满,线程将会阻塞等待直到队列非满;从阻塞队列取数据时,如果队列已空,线程将会阻塞等待直到队列非空。并发包下很多高级同步类的实现都是基于BlockingQueue实现的。

Java并发编程的过程中遇到了什么挑战,Java内存模型

你必须知道如何处理死锁,竞态条件,内存冲突和线程安全等并发问题

java 请求url加时间戳有什么用

1,防止缓存。

Kotlin 使用关键字 class 来定义类
类的修饰包括类名,类头部(指定类型参数和主构造函数等),花括号包裹的类体。
类头和体是可选的,没有体的时候,花括号可以忽略

class Invoice {
}

// 这个有什么用处呢?
class Empty

构造函数

一个类可以有一个主构造函数和 1-n 个二级构造函数,
主构造函数是类头的一部分,在类名的后面,有可选的类型参数

class Person constructor(firstName: String) {
}

如果主构造函数没有任何注解和可见修饰符 constructor 关键字可以省略

class Person(firstName: String) {
}

主构造函数不能包含任何代码,初始化代码可以放在 使用 init 关键字声明的 initializer blocks
在实例初始化的时候,按照在类体出现的顺序执行

class InitOrderDemo(name: String) {
val firstProperty = "First property: $name".also(::println)

init {
println("First initializer block that prints ${name}")
}

val secondProperty = "Second property: ${name.length}".also(::println)

init {
println("Second initializer block that prints ${name.length}")
}
}

常用的简洁的声明方式

class Person(val firstName: String, val lastName: String, var age: Int) {
// ...
}

二级构造函数

使用关键字 constructor 定义

class Person {
constructor(parent: Person) {
parent.children.add(this)
}
}

这是一本把常见的心理陷阱总结在一起的书籍。有一些已经耳熟能详了,有很多并不知道。
这不是一个适合集中时间阅读的书,适合每天看几页,然后思考积累,重要的是要深有体悟才能领会到。

3e263941.png

摘录几条对我感触较深的已备查看。

篡改历史现象

简单地说就是人们在不同的时间会做出不同的选择,却认为自己的选择是始终如一的。
我们的大脑在这里做了自适应,解决方法也很简单,对自己的选择存档备查。

激励排挤效应

这个挺有趣,也比较容易理解。
在一个人不是为了金钱而努力做事的时候,奖励金钱反而会降低做事的意愿。
金钱降低了做事本身的意义

内省错觉

越是深信不疑的事情,越要多一些怀疑。

当有人和我们的观点不同时,我们会有三个反应。

  1. 无知假设:其他人一定是缺少必要的信息
  2. 白痴假设:其他人有相关的信息,但是脑子不好使,所以得不出正确的结论
  3. 恶意假设:其他人有相关的信息,也能理解这里面的意思,但故意得出相反的结论,他这么做是带有恶意的。

竞争偏见

请对比你有才华的人予以支持,短时间内你会使自己的地位陷入危机,但你绝对是可以从中获益的,因为无论如何总会有人在某一时间超过你。
等他们超过你时,你会更容易赢得他们的好感,更方便向他们学习。

非我发明症候群

我们会陶醉在自己的想法中,认为自己的是最好的。
为了能够再次清醒,请适时地保持一定距离,回过头去审视自己的那些想法:在过去10年里有哪些想法是真的很超群???

导入项目时,提示登录用户不是该小程序的开发者

这时候,找到“project.config.json”文件,我们需要修改项目中的“project.config.json”文件。
打开“project.config.json” 文件,将“appid”设置为自己的appid,然后保存并关闭文件,再次导入项目即可。

状态码 含义
200 ok - 成功返回状态,对应,GET,PUT,PATCH,DELETE.
201 created - 成功创建。
304 not modified - HTTP缓存有效。
400 bad request - 请求格式错误。
401 unauthorized - 未授权。
403 forbidden - 鉴权成功,但是该用户没有权限。
404 resource not found - 请求的资源不存在
405 method not allowed - 该http方法不被允许。
410 gone - 这个url对应的资源现在不可用。
415 unsupported media type - 请求类型错误。
422 unprocessable entity - 校验错误时用。
429 too many request - 请求过多。