我已与2020年3月份抵达加拿大温哥华,入职新公司

2019年底拿到job offer,开始办理相关事宜,具体时间点如下:

  • §2019年11月27日提交了各种信息给移民律师
  • §12月3日,体检,无犯罪记录公证
  • §12月10日,开始准备支持材料,拿到无犯罪记录公证书
  • §12月18日,LMIA获批
  • §12月20日,填写各种IMM表格
  • §12月21日,律师将工作许可申请提交给IRCC
  • §2020年1月4日,收到Biometric Instruction Letter
  • §1月6日,提交指纹和相片信息(Biometric)
  • §1月14日,收到Passport Request Letter
  • §1月15日,快递护照等材料给Visa Application Center
  • §1月20日,Visa Application Center签收
  • §1月22日,dispatched to the IRCC Office
  • §1月23日, under process at the IRCC Office
  • §2月1日,获得Work Permit Approval信件,信件告知,签证也已经签发
  • §2月19日,processed decision envelope has been dispatched t0 VAC
  • §2月21日,收到decision envelope,拿到W-1 Worker签证
  • §3月1日,CA 991 北京 – 温哥华,抓紧时间前往温哥华,害怕COVID-19在海外爆发,导致入职不利。

Hyperledger Frabric/EOS/Ethereum/Bitcoin对比

Fabric的知识源于 https://hyperledger-fabric.readthedocs.io/en/latest/whatis.html

Fabric是一个基于策略的有权限机制的通用区块链平台。一个或者多个组织可以设定策略(Network Configuration),搭建平台,并允许其他组织加入该平台,不同的组织之间可以在平台上形成一个一个个的Channel,每一个Channel对应了一个配置策略(Channel Configuration)以及保存于Channel上的账本(Ledger),每一个Channel的账本和智能合约(Smart contract, a.k.a chaincode)可以分布在多个Peer Node上,Fabric上的应用(Application)通过调用智能合约,产生交易(Transaction),交易在Peer Node上得到背书(endoresement),并最终提交到Ordering Service Node,打包成为区块(Block),区块分发到Peer Node上并被验证,验证后,有效的交易就会提交(Committed),Fabric的World State也得到了更新。

与EOS等相比,Fabric既不是POS(Proof of Stake)也不是POW(Proof of Work),而是一种基于策略的机制。最初,Fabric采用的是单机共识或者以及基于Kafka的CFT(Crash Fault Tolerance)机制,目前,Fabric已经增加了Raft的支持。

另外,由于Fabric有Channel的概念,而且不同的Channel之间有隔离机制,这就使得Fabric在不同的Channel之间的共识可以互不干扰,有了并发的基础,而对于EOS,以太坊(Ethereum)和比特币(Bitcoin)来说,每一次共识必须是全网的共识,这决定了Fabric天生就比EOS/以太坊/比特币等有性能优势。

从性能角度来看,实际而言,比特币性能最差(不考虑Off-chain和闪电网络等因素),以太坊次之,EOS又好一些,Fabric最好。实践中,EOS由于其独特的抵押机制,导致CPU和内存资源分配必须依赖于用户所能抵押的EOS数量,所以,尽管全网来说,EOS性能应该优于比特币和以太坊,但是,对于普通用户来说,往往由于自己能抵押的币很少,普通用户在EOS上可能迟迟得不到运行应用的时间,导致实际上无法执行操作。Fabric由于Channel的隔离因素,所以,对于大量不相关联的交易,完全可以互不干扰,分布在不同的Channel上,因此,Fabric可以实现水平扩展,而这时BTC/EOS/ETH都无法实现的。

对于Fabric来说,根据 https://arxiv.org/pdf/1805.11390.pdf

在一个拥有8个peer node,每个peer有E5 2.0GHz 32GB内存的Fabric网络下,以Kafka作为Ordering Service的前提下,TPS达到了140,这是在一个比较普通的配置下所达到的。

从系统特性角度来看,EOS/以太坊/比特币都在存储数据上有较大限制,链上不适合存储大量的数据。必须通过各种off-chain机制存储大数据,而Fabric原生支持私有数据(private data),再结合Channel隔离,Fabric本身就可以支持较大的数据直接存储在链上。

从智能合约开发角度来看,Fabric支持用go, java和nodejs来开发智能合约,因此,对于开发者来说更为友好,相比之下, EOS的智能合约C++,以太坊的智能合约语言为Solidity,Bitcoin本身支持一些简单的操作,不是完全不可以开发智能合约,然而限制很大。

说说面试官在面试中不可犯的错误以及求职者哪些方面属于重大缺陷

每一个人都会经历求职,入职,工作,在工作中作为面试官面试求职者这些过程。面试和被面试的过程,是一个面试官发现求职者亮点,并判断求职者是否合适,同时,求职者也会评估当前公司的一个双向过程。在这个过程中,无论面试官还是求职者,都有许多要注意要的点,在这些要点之中,本文将结合近期王垠在他的博客中提到的赵海平对他的面试过程,以及赵海平在知乎上的回应,讲讲面试官和求职者各自站在自己的角度,都有哪些不要犯的错误,同时求职者应该如何更好地评估自己。

首先,我认为,作为面试官,在面试的过程中还是最好避免任何的“玩笑”,并且注意用词,否则很容易造成负面的影响。毕竟,我们不知道一个玩笑会被怎样解读。

王垠在他的博客《再谈“P vs NP”问题》中的“解密”部分提到了他曾经去阿里的杭州总部面试,在一次交叉面试中,一位P10面试了他,这位P10“是 Facebook 的第一个华人员工,他的 FB 工牌上写着“The Greatest Computer Scientist””。根据这个信息,尽管王垠没有明确说出名字,我们不难推断出,面试官就是赵海平了。王垠还提到,赵海平问他“你回国之后的一年怎么没去工作?你是富二代吗!”正好,一位自称是赵海平的知乎用户在《如何评价阿里 P10 赵海平对王垠的面试?》的回答中,提到了

好吧,我确实很爱开玩笑,当时开了一个玩笑,简历上有一年的空挡没有工作,这个是个 red flag (警惕性信息),我必须要询问原因,我很友好的开了个玩笑“不需要挣钱的呀,富二代那种?;-) 现在想想的确不合适,希望王垠原谅!

https://www.zhihu.com/question/360622233/answer/944141354

这么来看,在面试过程中,赵海平的确提到了“富二代”这样的话语,他也的确认为这样的话不太合适。尽管赵海平本身可能并没有任何恶意,这样的话语确实可以解读为一种歧视,挑衅,不礼貌。我们也许不清楚他人有什么禁忌,对于同一个词语,表达方式是否有不同的解读,不同的感受,因此,面试官本身在用词用语方面其实要非常注意,或许,注意的程度甚至会让人感觉比清朝的文字狱还要厉害。

其次,我认为,对于求职者来说,更重要的在于如何评估自己在面试官,甚至说在目标公司心目中的地位。这部分,我认为赵海平在他的知乎回答中给出了许多有用的信息。

简历上有一年的空挡没有工作,这个是个 red flag (警惕性信息),我必须要询问原因

我们可以看到,求职者首先要注意,尽量不要让自己的简历有空档,更不要有很长时间的空档,如果空档只是两三个月,一般还不太要紧,如果空档很长时间的话,如1年,那么,公司对你就会有负面的看法了,赵海平作为阿里的P10,已经属于很高级别,他既然特别提到了,就说明一年的空档是一个很不好的因素,即red flag。尽管赵的中文用词是“警惕性信息”,笔者认为,赵想要表达的真实含义其实比“警惕”还是要高一个级别的。

至于博客的讨论是在简历工作讨论之后了,如果不是出于寻求亮点发掘能力,我是不会去看博客的

赵海平在他的知乎回答中提到“如果不是出于寻求亮点发掘能力”,这就非常有意思了,为什么寻求亮点要看博客了呢?这里可能有至少两种解读,一种就是,赵海平在王垠的简历上找不到亮点,所以期望在王垠的博客中找亮点,还有一种就是,赵海平觉得简历上有亮点,但是希望找更多亮点,让王垠级别定更高。我个人猜测,可能真实的解读是第一种解读,即赵海平的确在简历上没找到亮点。

那么,为什么简历上找不到亮点呢。我认为,一个最合理的解释就是,王垠的确在前面的几家公司都定级不够高,职业连贯度不够,导致很难在公司项目和公司职级上对自己进行背书。例如,谷歌的L6,这个级别大家都认可,脸书的E6,亚马逊的L7,如果你在这些公司有这样的级别,那么,公司就给你背书了,而且,通常能升到这个级别的人,本身也要经过各种考核,有着有不错的impact的项目,对于团队也有影响力,在业界看来,公司已经考核过了,那么,自然就默认有L6/E6/L7的人应该很不错。

第三,求职者避免自我感觉太好,特别是不要把公司和自己的位置颠倒了

当时阿里巴巴有一个项目组想请我加入他们。…… 我看他们好像很诚恳,最后终于决定跟他们聊一下。虽然我常常听说阿里的“996”现象和办公室政治,但这种高级别的职位,他们又求贤若渴的样子,心想就算最后不去,了解一下探探底也无妨。

解密(2019 年 12 月) 王垠的《再谈“P vs NP”问题

我发现,王垠在博客中提到是阿里的某个团队请他加入,而不是他主动求职的,在知乎的问题《如何评价阿里 P10 赵海平对王垠的面试?》中,不少回答也认为这是阿里求着王垠加入。然而,根据我个人多年的经验,这里的态度,邀请,其实性质上都是面试邀请,本质上只能表明求职者已经通过了简历筛选,并不意味着面试结果会如何。求职者切忌有一种对方既然求我去面试,说明我就是一个合格的人,入职时水到渠成的感觉。

最后总结,作为面试官,尽量避免开玩笑,用词用语一定要注意,避免触碰到各种禁忌。对于求职者,一定要准确估计自己在公司层面的定位,综合分析自己的优缺点,避免自我感觉太好。对于求职者来说,如果简历上有长时间的空档,并且职业生涯不太稳定,这都是一些很大的硬伤,在面试中难免遭受质疑,被质疑是正常的。即便如此,有硬伤也不意味着不能求职成功,只不过不能奢望很高级别的岗位,同时要做好常常失败的准备。

flutter应用在三星手机上运行时,屏幕左下角有游戏工具的浮动图标。flutter应用在三星android手机上被识别为游戏?

今日,我用flutter编写一个ios/android应用,并在三星note8上运行时,突然发现应用启动后,屏幕上显示的不是

Flutter Demo Home Page

而是

Welcome to Game Tools

我点击屏幕右下角的 < 后,屏幕倒是切换到flutter应用了,然而,屏幕左下角还是比其他应用多了一个图标。即 ||| 的左侧图标,在其他应用中不会出现,而且,点击该图标后,手机就会启动游戏工具(Game Tools)

我搜索Stackoverflow后,发现,React Native的应用也有类似情况

React Native app is recognized as a game on Samsung Note8

https://stackoverflow.com/questions/49287871/react-native-app-is-recognized-as-a-game-on-samsung-note8

I think there are few possibilities.
you (or one of your dependencies) have included the google play service API which inside of play service API has a module named games that samsung will automatically treat it as game.
You could find which of your dependency is loading google play service API and create a exclude like:
compile (project ('your.dependency')){ exclude group: 'com.google.android.gms', module:'play-services-game' }
Your application id (can see on build.gradle) is registered on samsung game database. You could check by going into playstore and search for your application id

不过,我检查了flutter的依赖(dependencies),并没有发现play-services-game。难道,真的是application id被三星识别为游戏的id了吗。

我检查了flutter默认的app id,该id为com.example.app,我将该值改为com.example.app,并重新编译运行应用。结果,我发现,当app id为com.example.app时,三星的游戏工具就会出现,而app id为com.example.app111时,三星的游戏工具就不会出现。

看来,com.example.app的确已经注册到三星的游戏数据库中( is registered on samsung game database. )了。还好,我们正常发布的应用不会使用com.example.app,所以,我们无需担心flutter编写的应用会触发三星的游戏工具(Game Tool)。

iOS 13的新Info.plist的key NSBluetoothAlwaysUsageDescription,相关应用需要及时升级

iOS 13在隐私方面有了新的变化,其中一个变化对于视频录制类应用会有较大影响。那就是Privacy – Bluetooth Always Usage Description(NSBluetoothAlwaysUsageDescription)。
如果视频类应用支持手持稳定器,如大疆Osmo Mobile,而目前手持稳定器与手机之间都是通过蓝牙连接的,那么,App的Info.plist中需要添加该Key,否则,App在尝试连接手持稳定器的时候,会crash。

Crash的错误信息如下
This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app’s Info.plist must contain an NSBluetoothAlwaysUsageDescription key with a string value explaining to the user how the app uses this data.

使用CoreMotion时遇到Main Thread Checker: UI API called on a background thread: -[UIApplication applicationState]

2019年8月1日更新:根据本人测试,在iOS 13 Developer Beta 5,iPhone XS Max上,本bug已经不再出现,App调用CoreMotion不会再出现Main Thread Checker: UI API called on a background thread: -[UIApplication applicationState] 错误。


我近期以ProMovie为原型,开发一款iPhone的录像app,在开发的过程中,考虑到用户可能会锁定屏幕旋转,所以,我使用了CoreMotion判断设备当前的orientation,以此确定拍摄的视频的orientation。然而,在实际调试中,我发现,每次在我的iPhone XS Max iOS 12.3.1上运行,Xcode都会检测到以下错误。该错误不会导致应用崩溃,但是一直存在。最终,我只能像忽略warning一样忽略它,然而,与warning不一样之处在于,我可以想办法解决warning,却没办法解决此问题。

Main Thread Checker: UI API called on a background thread: -[UIApplication applicationState]
PID: 11696, TID: 3583674, Thread name: com.apple.CoreMotion.MotionThread, Queue name: com.apple.root.default-qos.overcommit, QoS: 0
Backtrace:
4 libobjc.A.dylib 0x000000022fc476f4 + 56
5 CoreMotion 0x00000002363c1d9c CoreMotion + 294300
6 CoreMotion 0x00000002363c22cc CoreMotion + 295628
7 CoreMotion 0x00000002363c21dc CoreMotion + 295388
8 CoreMotion 0x00000002363f001c CoreMotion + 483356
9 CoreMotion 0x00000002363f0060 CoreMotion + 483424
10 CoreFoundation 0x00000002309d627c + 28
11 CoreFoundation 0x00000002309d5b64 + 276
12 CoreFoundation 0x00000002309d0e58 + 2276
13 CoreFoundation 0x00000002309d0254 CFRunLoopRunSpecific + 452
14 CoreFoundation 0x00000002309d0f88 CFRunLoopRun + 84
15 CoreMotion 0x00000002363ef9f4 CoreMotion + 481780
16 libclang_rt.asan_ios_dynamic.dylib 0x00000001053e1ef0 _ZN6__asan10AsanThread11ThreadStartEyPN11__sanitizer16atomic_uintptr_tE + 192
17 libsystem_pthread.dylib 0x000000023064e908 + 132
18 libsystem_pthread.dylib 0x000000023064e864 _pthread_start + 48
19 libsystem_pthread.dylib 0x0000000230656dcc thread_start + 4
2019-07-22 16:56:00.955489+0800 VideoCamera[11696:3583674] [reports] Main Thread Checker: UI API called on a background thread: -[UIApplication applicationState]
PID: 11696, TID: 3583674, Thread name: com.apple.CoreMotion.MotionThread, Queue name: com.apple.root.default-qos.overcommit, QoS: 0
Backtrace:
4 libobjc.A.dylib 0x000000022fc476f4 + 56
5 CoreMotion 0x00000002363c1d9c CoreMotion + 294300
6 CoreMotion 0x00000002363c22cc CoreMotion + 295628
7 CoreMotion 0x00000002363c21dc CoreMotion + 295388
8 CoreMotion 0x00000002363f001c CoreMotion + 483356
9 CoreMotion 0x00000002363f0060 CoreMotion + 483424
10 CoreFoundation 0x00000002309d627c + 28
11 CoreFoundation 0x00000002309d5b64 + 276
12 CoreFoundation 0x00000002309d0e58 + 2276
13 CoreFoundation 0x00000002309d0254 CFRunLoopRunSpecific + 452
14 CoreFoundation 0x00000002309d0f88 CFRunLoopRun + 84
15 CoreMotion 0x00000002363ef9f4 CoreMotion + 481780
16 libclang_rt.asan_ios_dynamic.dylib 0x00000001053e1ef0 _ZN6__asan10AsanThread11ThreadStartEyPN11__sanitizer16atomic_uintptr_tE + 192
17 libsystem_pthread.dylib 0x000000023064e908 + 132
18 libsystem_pthread.dylib 0x000000023064e864 _pthread_start + 48
19 libsystem_pthread.dylib 0x0000000230656dcc thread_start + 4

然而,令我感到困惑的是,Stack Trace给出的信息表明这应该是CoreMotion自己的问题。

我通过搜索,发现Stackoverflow上有相应的问题和回答
https://stackoverflow.com/questions/54607856/main-thread-checker-warning-with-coremotion-only-appearing-on-2018-model-iphone
根据该问答,2018款的iPhone都可以复现此问题。这样看来,这是一个iPhone的bug了。

我于是拿来了我的iPhone 6s进行测试,果然,在我的iPhone 6s iOS 12.3.1上,我的app并不会复现此问题。

然而,经过搜寻,我又发现了如下的bug report
https://openradar.appspot.com/46210367

有人报告,在使用UIInterpolatingMotionEffect时,也会出现UI API called on a background thread: -[UIApplication applicationState] Thread name: com.apple.CoreMotion.MotionThread 错误,且该错误仅在iPhone XS上出现,在iPhone X,6s和6s Plus上则不能复现此错误。因此,该report认为,bug与新的硬件相关,具体什么原因,未知。需要注意的是,该bug report提到的iOS版本为12.1,而截止到本文写作之时,iOS已经升级到了12.3.1,很快就要一年了,该bug仍然存在。

A new instance of CMMotionManager results in a Thread Checker warning
Originator: futuretap
Number: rdar://46210367 Date Originated: 22-Nov-2018 10:46 AM
Status: Duplicate/31658500/Closed Resolved:
Product: iOS + SDK Product Version: 12.1
Classification: Serious Bug Reproducible: Always

Summary:
This is a duplicate of radar #45003816. We encounter the same issue when using UIInterpolatingMotionEffect. The Main Thread Checker kicks in on an iPhone XS@12.1.
iPhone X@12.1.1, iPhone 6s@11.4.1, iPhone 6s Plus@11.4.1 all work fine so it seems to depend on the new hardware.

Creating a new instance of CMMotionManager always results in a Thread Checker exception

Main Thread Checker: UI API called on a background thread: -[UIApplication applicationState]
PID: 9123, TID: 1958556, Thread name: com.apple.CoreMotion.MotionThread, Queue name: com.apple.root.default-qos.overcommit, QoS: 0
Backtrace:
4 libobjc.A.dylib 0x00000002079d7894 + 56
5 CoreMotion 0x000000020e2387a4 CoreMotion + 305060
6 CoreMotion 0x000000020e238cd8 CoreMotion + 306392
7 CoreMotion 0x000000020e238be8 CoreMotion + 306152
8 CoreMotion 0x000000020e26a3cc CoreMotion + 508876
9 CoreMotion 0x000000020e26a42c CoreMotion + 508972
10 CoreFoundation 0x0000000208770888 + 28
11 CoreFoundation 0x000000020877016c + 276
12 CoreFoundation 0x000000020876af54 + 1016
13 CoreFoundation 0x000000020876a844 CFRunLoopRunSpecific + 452
14 CoreFoundation 0x000000020876b5a8 CFRunLoopRun + 84
15 CoreMotion 0x000000020e269d64 CoreMotion + 507236
16 libsystem_pthread.dylib 0x00000002083e5a04 + 132
17 libsystem_pthread.dylib 0x00000002083e5960 _pthread_start + 52
18 libsystem_pthread.dylib 0x00000002083eddf4 thread_start + 4
2018-10-04 12:09:35.737994+0200 test[9123:1958556] [reports] Main Thread Checker: UI API called on a background thread: -[UIApplication applicationState]
PID: 9123, TID: 1958556, Thread name: com.apple.CoreMotion.MotionThread, Queue name: com.apple.root.default-qos.overcommit, QoS: 0

Comments
Happening for me as well, lot of things getting impacted, and yeah only happens on XS, XS Max, and XR

By jchaudhry at May 6, 2019, 11:36 p.m. (reply…)
This issue still happens. Should I file yet another bug report with Apple?

By aruslan at April 2, 2019, 6:34 p.m. (reply…)
Any update on this issue, seems like this is massively impacting a lot of projects

By xuehao.hu at March 29, 2019, 6:11 a.m. (reply…)

Swift语言的随机数:运行效率和安全性(cryptographically good)

Apple推出Swift语言已经很多年了,如今,Swift语言已经进化到了5.1版本,很多细节也越来越完善了,不过,总的来说,Swift语言的overhead仍然较大,具体到随机数上,Swift内置的运行时生成随机数效率低,不适用于模拟,测试和游戏等对于cryptographically good要求不高的场景。

如果读者需要大量生成随机数的话,建议用arc4random或者arc4random_uniform,不要使用arc4random_buf或者Swift语言的random方法。对于测试,模拟和游戏等不需要cryptographically good/secure的情况,可以直接引入C语言类库的rand方法,运行效率更高。

Swift对于内置的Double, Int等类型提供了random方法,用以生成指定的开闭区间内的随机数。然而,经过实际测试,我发现,一方面,Swift语言本身的overhead很大,另一方面,Swift内置的SystemRandomNumberGenerator使用的是arc4random_buf,该方法比arc4random和arc4random_buf慢很多。所以,如果效率非常重要,那么,请不要使用Swift类库的随机数,应该在Swift中调用C/C++语言实现的随机数库。


       var i = 0;
        while(i<100000000){
 //1亿个随机数,每个随机数在闭区间[0,11]内取值,随机数独立同分布
            let _ = arc4random_uniform(11)
            i += 1;
        }
       var i = 0;
        while(i<100000000){
//1亿个随机数,每个随机数在闭区间[0,2^32-1]内取值,随机数独立同分布
            let _ = arc4random()
            i += 1;
        }
       var i = 0;
        while(i<100000000){
            var b:UInt32 = 0;
//1亿个随机数,每个随机数在闭区间[0,2^32-1]内取值
            arc4random_buf(&b, 4)
            i += 1;
        }
        var i = 0;
        while(i<100000000){
            var b:UInt32 = 0;
            b = UInt32.random(in: 0...10)
            i += 1;
        }

以下为一个特别简单的模n同余的Linear Congruent伪随机数生成器,实际测试发现,生成1亿个32位随机数的话,Debug模式下需要耗时29.31秒, Release模式下需要5.06秒。

struct LCG: RandomNumberGenerator {
    var seed:UInt64
    
    init() {
        self.seed = mach_absolute_time()
    }
    
    init(seed:UInt64) {
        self.seed = seed;
    }
    
    mutating func next() -> UInt64 {
        self.seed = 32479 &+ self.seed
        return self.seed
    }
    
}

var i = 0;
while(i<100000000){
    var b:UInt32 = 0;
    b = UInt32.random(in: 0...10, using: &lcg)
    i += 1;
}

经过实际测试,结果如下
1亿个随机数,

随机数生成方法 debug release
rand 11.21秒 0.52秒
arc4random 3.09秒 2.34秒
arc4random_uniform 3.41秒 2.67秒
arc4random_buf 19.69秒 18.79秒
UInt32.random 47.98秒 19.27秒
自定义LCG 29.31秒 5.06秒

UInt32.random实际上会使用Swift内置的SystemRandomNumberGenerator,实际上最终调用了arc4random_buf,然而,与直接调用arc4random_buf相比,UInt32.random在Debug模式下慢了近30秒,Release模式下则慢了16秒,因此,我们可以得出结论,即便是Release模式下,Swift的overhead还是很大的。因此,如果需要高效率生成很多随机数的话,不建议直接使用Swift的Double, Int的random方法。不过很特别的是,rand函数在Debug模式下竟然比arc4random慢很多,甚至和arc4random_buf差不多了,但是,在Release模式下,rand还是最快的,0.52秒就可以生成1亿个伪随机数。

接下来,我们来看看为什么arc4random_buf比arc4random和arc4random_uniform慢这么多。

经过查看苹果的具体实现 https://opensource.apple.com/source/Libc/Libc-1272.200.26/gen/FreeBSD/arc4random.c.auto.html

我们不难发现,arch4random方法的具体代码如下,其中CACHE_LENGTH的值为64

uint32_t
arc4random(void)
{
	int ret;
	os_unfair_lock_lock(&arc4_lock);
	arc4_init();
	if (arc4_count <= 0) {
	    arc4_stir();
	}
	if (cache_pos >= CACHE_LENGTH) {
		ret = ccdrbg_generate(&rng_info, rng_state, sizeof(rand_buffer), rand_buffer, 0, NULL);
		os_assert_zero(ret);
		cache_pos = 0;
	}
	uint32_t rand = rand_buffer[cache_pos];
	// Delete the current random number from buffer
	memset_s(rand_buffer+cache_pos, sizeof(rand_buffer[cache_pos]), 0, sizeof(rand_buffer[cache_pos]));
	arc4_count--;
	cache_pos++;
	os_unfair_lock_unlock(&arc4_lock);
	return rand;
}

而arc4random_uniform实际调用arc4random方法,并且通过多次循环避免modulo bias

/*
 * Calculate a uniformly distributed random number less than upper_bound
 * avoiding "modulo bias".
 *
 * Uniformity is achieved by trying successive ranges of bits from the random
 * value, each large enough to hold the desired upper bound, until a range
 * holding a value less than the bound is found.
 */
uint32_t
arc4random_uniform(uint32_t upper_bound)
{
	if (upper_bound < 2)
		return 0;

	// find smallest 2**n -1 >= upper_bound
	int zeros = __builtin_clz(upper_bound);
	int bits = CHAR_BIT * sizeof(uint32_t) - zeros;
	uint32_t mask = 0xFFFFFFFFU >> zeros;

	do {
		uint32_t value = arc4random();

		// If low 2**n-1 bits satisfy the requested condition, return result
		uint32_t result = value & mask;
		if (result < upper_bound) {
			return result;
		}

		// otherwise consume remaining bits of randomness looking for a satisfactory result.
		int bits_left = zeros;
		while (bits_left >= bits) {
			value >>= bits;
			result = value & mask;
			if (result < upper_bound) {
				return result;
			}
			bits_left -= bits;
		}
	} while (1);
}

也就是说,arc4random和arc4random_uniform由于rand_buffer[64]的存在,每生成64个32位随机数,才需要调用一次ccdrbg_generate,而arc4random_buf每一次调用,都需要调用一次ccdrbg_generate。所以,如果读者需要大量生成随机数的话,建议用arc4random或者arc4random_uniform,不要使用arc4random_buf或者Swift语言的random方法。

对于测试,模拟和游戏等不需要cryptographically good/secure的情况,可以直接引入C语言类库的rand方法,运行效率更高。

说说退休父母投靠在京独生子女落户北京的流程

本人落户在北京朝阳区,前往户口所在派出所咨询了父母投靠的详细细节,于2018年12月底正式向派出所提交材料,2019年5月14日拿到准迁证。准迁证的签发日期是2019年5月9日。

提交材料后,其实没别的事,就是一个“等”字。但是,提交材料以前,花了大量时间理解政策,收集材料。

需要准备的材料中,首先要准备的是我的档案部分,到存档部门直接索要就可以了,现在回想起来,当初我还是犯了一些错误。1. 没有事先准备一个文字的清单,导致第一次去的时候没有拿到查档证明,这个查档证明的内容就是XXX为我处存档人员,根据XX档案,父母为XXX,无兄弟姐妹。我为此不得不第二次去人才办理查档证明,多跑了一次。2. 自己的档案管理不及时,等到要办事用到档案了,才发现档案中缺少高中的毕业生登记表,最后不得不抽空回了老家到了当年上学的高中翻了好多档案,才最终找到。据说当年应该是高考后,到大学时就应该转移的。

在准备材料的过程中,问题最大的就是我父母在广西,父亲退休的时候广西已经不再对企业退休人员发放退休证了,而北京的文件仍然要求退休证,当初我也是感到很麻烦,也到本版进行了咨询。这里要说明的是,在广西的国家干部和事业单位退休人员,还是有退休证的,但是企业职工,不管你是高管还是工人,通通不发退休证,只发待遇资格证了。

最后,我采用的解决办法如下
1 复印了我父亲的“享受养老保险待遇资格证”
2 通过广西省一级的政府信息公开,要到了盖章的红头文件,该文件表
明广西确实不对2008年以后退休的企业职工发放退休证了。该文件为“广西壮族自治区劳动和社会保障厅关于全区统一使用享受基本养老保险待遇资格证的通知(桂劳社发[2008]3号)”

为了政府信息公开,我请人专门去南宁了一趟。之所以专门去南宁一趟,主要是之前我的父母和政府打交道的时候发现,大量政府人员认为“你们要这个文件有什么用,有资格证就行了”,当政府认为一个东西没有必要的时候,根本就不会给你办理,如果你不亲自出面,工作人员感受不到必要性。具体办理地点为 广西壮族自治区政务服务中心 南宁市青秀区怡宾路6号。请各位读者注意,在本案例中,该文件的发文单位为省级单位,所以要去自治区政府服务中心,而不是南宁市政府服务中心。

还有一个就是独生子女证,这个证件的主要问题就是子女姓名和我的姓名不一致,最后采取的办法是父母到了当地街道的计生办,去了数次,体现了自己的诚意,表明了重新办证的必要性和自己确实只有一个子女的事实,最后,街道计生办颁发了新证件。

以上就是我在办理父母投靠进京落户的时候遇到的一些难点和问题。其余的材料,在我看来,都是按照派出所的文件按部就班就好了,唯独以上几个问题是一开始很困扰我的。

最后说点题外话,由于这次父母投靠事情,我看到了自己和父母的大量原始档案,对于中国的历史问题有了更深刻的理解。

我终于明白身份证的生日和实际生日不一样是怎么回事了。新闻中说的档案中农历和公历生日混为一谈,生日填错的情形,真实发生在我父母的档案中,最后,这些问题都通过手写一份材料解决了。

第三调解室3月19日晚的节目给我们的警示

第三调解室昨晚(3月19日)的节目有很大的警示意义。这一期节目的家人还上过2018-12-21和2018-12-22两期节目,年夜饭后起风波(1)和(2)。

北京市丰台区石榴庄村的一位老父亲指望女儿养老,做主自己百年之后送一套房子给女儿,女儿觉得没有后顾之忧就卖了自家的房,没想到女儿先去世,老父亲反悔不愿意送房子了,现在女婿和外孙女即将无家可归。

某老父母有两个儿子一个女儿,女儿女婿别处有房,后来父母和儿子在农村拆迁得了好几套房,女儿由于有房就没有拆迁得房。父母指望女儿和女婿养老,所以2011年和儿子女儿一起签了一个协议,拆迁房子送一套给女儿女婿,以后女儿女婿负责养老送终,女儿觉得自己公公婆婆已经先走了,以后爸妈也指望自己养老,所以就把自己家里的房子卖了,想要以后带着老公和女儿与父母一起住。大姐曾经有一套唯一住房,2011年签了分家协议以后没多久,2012年就卖掉了自己的唯一住房,大姐的原来的房子是1990年亚运会拆迁的安置房。她的原话是,我就没有后顾之忧了,所以我就把自己的房子卖了。

2016年母亲去世,随后不久女儿因为脑溢血也去世了。老父亲觉得女儿死了,以后养老就不能指望女婿和外孙女了,所以想要推翻原来的养老协议,也不送房子了,现在女婿和外孙女即将无家可归。老父亲说,他们没房子,搬走后去哪里住,我管不着了。

最后结局,由于老母亲先死,女儿后亡,外孙女可以代位继承姥姥的资产,最后舅舅和姥爷给了外孙女100万作为遗产的对价。

想着这家人都是北京人,女儿当年觉得没有后顾之忧卖房的时候北京房价比现在低多了,女婿和外孙女就算有这100万,在北京也买不了什么房,女儿当年觉得自己没有后顾之忧的时候,她肯定没有没有想到自己的丈夫和女儿会面临这种惨痛的结局。

背景介绍
郑家八口人分了五套房,父母二人,二哥三口,小弟三口,大姐的户口不在娘家,所以没有得到拆迁安置房。
八口人分成了两户按照,父母和二哥分了两套两居室90, 75,一套三居室115,小弟分了两套两居室。

2011年12月12日一家人签了分家协议,小弟的一套75平米的房子给姐姐,父母百年以后,小弟的75平米房子首先过户给姐姐,最后,父母的115平米的三居室过户给小弟。
2013年拆迁房得到了,大姐认为这套房子就是自己的房子了。

[php-fpm slow log应用]wordpress的Captcha Booster插件导致我的个人blog因为最近有一段时间无法访问

我的blog最近有一段时间不能访问了,总是报504 Gateway Timeout。
具体原因如下。

我用php-fpm作为fastcgi server,nginx通过reverse proxy连接到php-fpm,然后php-fpm执行wordpress代码并将html数据返回给用户。

我的wordpress的编辑后台添加了Captcha Booster插件,这样登录界面就有captcha了。然而,没想到就是这个插件,导致了我的blog无法访问。

我通过启用了php-fpm的slow log,发现问题出在plugins/wp-captcha-booster/wp-captcha-booster.php:552

[14-Sep-2018 16:55:58.866159]  [pool www] pid 31454
script_filename = /usr/share/nginx/wordpress/wp-admin/index.php
[0x00007f5ea7fe2398] file_get_contents() /usr/share/nginx/wordpress/wp-content/plugins/wp-captcha-booster/wp-captcha-booster.php:552
[0x00007f5ea7fe21b8] get_ip_location_captcha_booster() /usr/share/nginx/wordpress/wp-content/plugins/wp-captcha-booster/wp-captcha-booster.php:576
[0x00007f5ea7fe2060] blocking_visitors_captcha_booster() /usr/share/nginx/wordpress/wp-content/plugins/wp-captcha-booster/wp-captcha-booster.php:901
[0x00007fffb287fcb0] user_functions_for_captcha_booster() unknown:0
[0x00007f5ea7fe1ef8] call_user_func_array() /usr/share/nginx/wordpress/wp-includes/class-wp-hook.php:286
[0x00007f5ea7fe1dd0] apply_filters() /usr/share/nginx/wordpress/wp-includes/class-wp-hook.php:310
[0x00007f5ea7fe1c70] do_action() /usr/share/nginx/wordpress/wp-includes/plugin.php:453
[0x00007f5ea7fe1ab8] do_action() /usr/share/nginx/wordpress/wp-settings.php:450
[0x00007f5ea7fe1990] +++ dump failed

在Captcha Booster的代码中

wordpress/wp-content/plugins/wp-captcha-booster/wp-captcha-booster.php 550到559行

                        $api_call  = TECH_BANKER_SERVICES_URL . '/api/getipaddress.php?ip_address=' . $ip_address;
                        if ( ! function_exists( 'curl_init' ) ) {
                                $json_data = @file_get_contents( $api_call );  // @codingStandardsIgnoreLine.
                        } else {
                                $ch = curl_init();  // @codingStandardsIgnoreLine.
                                curl_setopt( $ch, CURLOPT_URL, $api_call );  // @codingStandardsIgnoreLine.
                                curl_setopt( $ch, CURLOPT_HTTPHEADER, array( 'Accept: application/json' ) );  // @codingStandardsIgnoreLine.
                                curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, 5 );  // @codingStandardsIgnoreLine.
                                curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );  // @codingStandardsIgnoreLine.
                                curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );  // @codingStandardsIgnoreLine.

上述代码中TECH_BANKER_SERVICES_URL的常量的值为https://tech-banker-services.org

我发现,不知什么原因https://tech-banker-services.org已经不可用了,这导致这几行代码执行将不会成功。
而一开始我没有安装php-curl,这样,wordpress就会执行

$json_data = @file_get_contents( $api_call );  // @codingStandardsIgnoreLine.

所以这就导致wordpress会卡在这一行代码非常久,nginx也就无法及时获得数据,从而超时报504 Gateway Timeout了。

我现在临时的解决办法如下
首先安装php5-curl

> apt-get install php5-curl

接下来将

curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, 5 );

改为

curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, 1 );

这样子,wordpress执行的时候,只会被卡1秒了。