0%

记一次删库到数据恢复

熟悉的朋友可能知道,进入架构组后,今年一直在为团队做各种开发辅助工具,其中包括一个服务器。

最近这个服务器也上线有三月多了,也不断收集了很多数据,包括用户的各种行为操作、API 调用数据等等。

在最近的一次升级中,我调整了源码的目录结构,脑子一抽删除了数据库。

阅读全文 »

由于骑手不能随时处在有 WIFI 的状态,流量变成了很敏感的问题,为了精确到每个 API 的流量,进行针对性的优化,开始在我们的 APM 中添加流量监控功能。

本文将记录自己做流量监控方面的总结。其中包括了非常多的踩坑经验,和现有一些方案的缺陷分析,对我来说是一个非常有意义的过程。

干货预警🤣请做好读大量代码的准备😂😂😂

阅读全文 »

Python——奇怪的扫码登录

最近在做 Sparrow(还在内测的一个敲好用 Mock 系统😁)的时候遇到了一个需求。Sparrow 服务器是使用 Django 2.0 编写的产品,所以本文所有的代码背景均为 Django 2.0 环境和 Python 3.6.3 语言,整体是 Vue + Django + SQLite。

Sparrow 的操作一般都是在网页上操作,而手机客户端往往是用来同步一些简单数据的。那么这里遇到一个和平常 APP 不同的使用场景。

一般来说,一个产品的操作大多是在手机上,那么 PC 客户端和网页版就可以通过已经登录的移动端 APP 扫码登录。

而现在的情况是,Sparrow 的使用大多在网页版,那么,我需要的就是,让移动 APP 用户在网页版已经登录的情况下免去输入用户名、密码的登录操作,让移动 APP 用户扫描网页二维码,完成移动 APP 的登录。

阅读全文 »

1. 资源文件引用的方式

在第一节,先来介绍一下 CocoaPods 两种资源文件引用的方式——resource_bundles & resources

1.1 resource_bundles

resource_bundles 允许定义当前 Pod 库的资源包的名称和文件。用 hash 的形式来声明,key 是 bundle 的名称,value 是需要包括的文件的通配 patterns。

We strongly recommend library developers to adopt resource bundles as there can be name collisions using the resources attribute.

CocoaPods 官方强烈推荐使用 resource_bundles,因为用 key-value 可以避免相同名称资源的名称冲突。

同时建议 bundle 的名称至少应该包括 Pod 库的名称,可以尽量减少同名冲突

Examples:

1
spec.ios.resource_bundle = { 'MapBox' => 'MapView/Map/Resources/*.png' }
1
2
3
4
spec.resource_bundles = {
'MapBox' => ['MapView/Map/Resources/*.png'],
'OtherResources' => ['MapView/Map/OtherResources/*.png']
}
阅读全文 »

2018 年 1 月 1 日 +

理解比特币(BitCoin)背后的区块链技术,这一篇文章就够了

Django权限机制的实现

使用元类

Understanding Responder Chain

iOS 电量测试实践

iOS 性能监控 SDK —— Wedjat(华狄特)开发过程的调研和整理

使用NSURLProtocol时要注意的一些问题

2018 年 6 月 1 日 +

图解 HTTPS:Charles 捕获 HTTPS 的原理

NSMutableArray原理揭露

探究NSMutableArray的实现原理

2018 年 11 月 1 日 +

北美软件工程师面试简单介绍

色彩第一课:自然人眼中的色彩

开篇

上一篇《iOS 混编 模块化/组件化 经验指北》中介绍到的 Lotusoot ,将在本篇中做一个更为详细的介绍。

最初 Lotusoot 简称为『混编路由』,但是随后反而曲解了它的功能,其真正的定位是『模块化工具和规范』。

Lotusoot 可以做到:

  1. 模块间、模块内服务调用
  2. Swift、OC、或者两者混编项目均可使用
  3. 短链注册、路由调用
  4. 脚本自动注册服务/路由表

注:这里的模块化,也就是大家说的『组件化』,不是在主工程用文件夹分模块,而是指将独立模块抽调成 CocoaPods 库、或者其他形式的库文件,成为一个独立工程。
下文中的模块就代表一个 CocoaPods 库

阅读全文 »

1. 开篇

本文的初衷,是为了给正在做混编或者模块化的同学们一个建议和参考。

因为来饿厂以后做的项目是全公司唯一一个 Swift/OC 混编的 iOS 项目,所以一路上踩坑无数,现在把一些踩坑的过程和经验总结起来,供大家参考。

相信在浏览本文后,一定会有所收获。

我来的时候项目已经开始 Swift 改造了,慢慢的把项目 Swift 化,新代码都是 Swift 的。

先公布七个月成果,下图是我们最终的项目结构:

对于我们混编的情况,在五个月前大家就展开了讨论。

给我们的选择有两种:

  1. 慢慢将 OC 代码替换成 Swift
  2. 尽快模块化,分离两种语言代码

一开始我们是从 选择1 开始做的,但是很快我们就发现,对于我们 74% 都是 OC 代码的项目来说,太痛了,太漫长了,而且期间迭代的过程中还在不断地迭代,不断的耦合。

所以在经过一番利害分析后我们迅速投入到了 选择2 中。一方面,模块化本身就是越来越臃肿的项目的最终归宿,一方面可以慢慢将两种语言剥离。

阅读全文 »

原文链接:A Simple Object Model
作者信息:Carl Friedrich Bolz


上一篇:《【500 Lines or Less】-【翻译练习】-【chapter 14】-【简单对象模型】-【第二部分】》
译者注:休息结束,我们继续

实例优化

虽然对象模型的在之前的几节中发生了很多行为变化,但在最后一节中,我们将在没有影响任何行为的情况下进行优化。这种优化被称为 maps,并在自编程语言的虚拟机中率先被使用。如今,它仍然是最重要的对象模型优化之一:它被用于 PyPy 和所有现代 JavaScript 虚拟机,如V8(其中优化被称为 hidden classes)。

目前的观察:在到目前为止实现的对象模型中,所有实例都使用完整的字典来存储它们的属性。字典是使用哈希映射来实现的,这消耗大量的内存。此外,同一个类的实例将会拥有同样的属性,比如,有一个类 Point,它所有的实例都包含同样的属性 xy

maps 优化利用了这一点。它有效地将每个实例的字典分成两部分。一部分存放所有实例共享的 keys。而实例只存储对共享映射的引用和列表中的属性值(比字典更消耗了更少的内存)。

做简单测试用例如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
def test_maps():
# white box test inspecting the implementation
Point = Class(name="Point", base_class=OBJECT, fields={}, metaclass=TYPE)
p1 = Instance(Point)
p1.write_attr("x", 1)
p1.write_attr("y", 2)
assert p1.storage == [1, 2]
assert p1.map.attrs == {"x": 0, "y": 1}

p2 = Instance(Point)
p2.write_attr("x", 5)
p2.write_attr("y", 6)
assert p1.map is p2.map
assert p2.storage == [5, 6]

p1.write_attr("x", -1)
p1.write_attr("y", -2)
assert p1.map is p2.map
assert p1.storage == [-1, -2]

p3 = Instance(Point)
p3.write_attr("x", 100)
p3.write_attr("z", -343)
assert p3.map is not p1.map
assert p3.map.attrs == {"x": 0, "z": 1}
阅读全文 »

原文链接:A Simple Object Model
作者信息:Carl Friedrich Bolz


上一篇:《【500 Lines or Less】-【翻译练习】-【chapter 14】-【简单对象模型】-【第一部分】》
译者注:休息结束,我们继续


方法调用

现在我们的模型还缺少方法调用的功能,本章我们将会实现一个简单的继承模型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
def test_callmethod_simple():
# Python code
class A(object):
def f(self):
return self.x + 1
obj = A()
obj.x = 1
assert obj.f() == 2

class B(A):
pass
obj = B()
obj.x = 1
assert obj.f() == 2 # works on subclass too

# Object model code
def f_A(self):
return self.read_attr("x") + 1
A = Class(name="A", base_class=OBJECT, fields={"f": f_A}, metaclass=TYPE)
obj = Instance(A)
obj.write_attr("x", 1)
assert obj.callmethod("f") == 2

B = Class(name="B", base_class=A, fields={}, metaclass=TYPE)
obj = Instance(B)
obj.write_attr("x", 2)
assert obj.callmethod("f") == 3
阅读全文 »

原文链接:A Simple Object Model
作者信息:Carl Friedrich Bolz

Carl Friedrich Bolz是伦敦国王大学的研究员,对动态语言的实现及优化兴趣浓厚。他是 PyPy/RPython 的核心贡献者之一,并为 Prolog, Racket, Smalltalk, PHP 和 Ruby 等语言贡献代码。

引子

面向对象开发是现今最主流的编程范式之一,面向对象的思想和变成范式也被大量的编程语言所支持。虽然不痛语言提供的面向对象编程机制表面上非常相似,但是细节上却大相径庭。大多数语言的共同点是拥有对象和继承机制。而『类』,并不是每一种语言都很好的支持它的种种特性。比如,比如对于 Self 或者 JavaScript 这样的原型程序设计的语言来说没有类的概念,而是对象间直接进行了继承。

了解不同语言的对象模型的不同之处是一件非常有趣的事。这能帮助你发现不同语言的异同之处。这将在我们学习新语言时,运用以往的编程语言经验,快速的学习。

本章将探索学实现一套简单的对象模型。我们将从一个简单的实例和它的类开始,并让它拥有一些方法可以用于访问。这是被 Simula 67 、Smalltalk 等早期 OO(面向对象) 语言所采用的经典面向对象范例。在本章中,这个模型将会被一步步进行扩展,前两个小节我们将展示不同语言的设计思路,最后一小节将讲解如何提高对象模型的性能。最终我们的模型并不是任何一门语言所采用的模型,不过,将认为是一个简化的 Python 对象模型。

本章中使用的代码范例都使用 Python 编写。代码可以运行在 Python 2.7 和 3.4。为了更好的理解对象模型的设计,本章也提供了相应的单元测试。测试代码可以通过 py.test 或者 nose 来运行。

用 Python 作为实现语言并不是最好的,通常一个 VM(或者语言解释器)是由底层语言比如 C 和 C++ 实现的,并在实现过程中对更偏向于扣每一个实现细节从而提高代码效率。而更简单的语言更让我们更容易关注实际的行为表现,而不是扣实现细节。

阅读全文 »

开端

Objective-C 中,有一段重复写到你不得不加入 snippets 的代码块。就是下面这段

1
2
3
4
5
6
7
__weak __typeof__(self) weakSelf = self;
[self.aButton touchUpInside:^{
__strong __typeof(weakSelf)strongSelf = weakSelf;
if (strongSelf) {
strongSelf.title = @"按钮被点击";
}
}];

一般,由于重复写的次数过多,就加到了 snippets 快捷代码块,以下是我的:

阅读全文 »

重要性

我们从重要性说起。

团队开发中要重视有洁癖的人,这种人往往对糟糕的工作流不断提出意见、对 Git 的使用方式提出要求。如果你的团队中这种人正在不断的被忽视,那么你的团队一定出现了管理混乱、代码质量不高等等等等问题。

统一的工作流程是至关重要的,不管对于哪一个行业的作业来说都一样。对于我们开发人员,工作流包含了开发时 Git 的使用规范、Repo 管理的规范、测试过程的规范、设计交互的管理规范等等。由于测试、交互等设计到更多的人员,本篇文章暂且不表,重点说 Git 的使用规范和 repo 管理的规范。

本篇文章将讲述我在工作中一直使用的 Work Flow,希望对大家有帮助。

阅读全文 »

你是否见过?

  1. 你是否见过测试人员或者自己在 CI 上 install 了一个版本,发现了 BUG 后,突然忘了自己下的是 CI 上的哪一个 commit 的包?
  2. 你是否见过下面这个东西:

blog_iOS——写一个快速定位问题的脚本-01

blog_iOS——写一个快速定位问题的脚本-02

阅读全文 »

randomart image 出现在哪里

通常我们在生成 SSH Key 的时候会用到 ssh-keygen 命令,在生成结束后,会输出类似如下的内容,这个 randomart image 是什么呢?

1
2
3
4
5
6
7
8
9
10
11
12
The key's randomart image is:
+--[ RSA 2048]----+
| o=. |
| o o++E |
| + . Ooo. |
| + O B.. |
| = *S. |
| o |
| |
| |
| |
+-----------------+
阅读全文 »

在写 『iOS(Objective-C) 内存管理&Block』 一文时,我并没有发现 NSObject 的代码已经被开源了,所以分析的主要是 GNUStep 的源码,对 Apple 的部分只是通过猜测。

实质上,NSObject 的实现内容已经开源在 objc4-706 中。于是我便开始学习 objc4 中的内容。

下面就和大家扒一扒 Apple 的 NSObject 内存管理的一些内容。

SideTable

找到 NSObject.mm,首先来一些非常重要的信息,以便后面的理解。

objc4-706 NSObject.mm SideTable:

1
2
3
4
5
6
7
8
struct SideTable {
// 保证原子操作的自旋锁
spinlock_t slock;
// 引用计数的 hash 表
RefcountMap refcnts;
// weak 引用全局 hash 表
weak_table_t weak_table;
};
阅读全文 »

第一篇 iOS 内存管理

1 似乎每个人在学习 iOS 过程中都考虑过的问题

  1. alloc retain release delloc 做了什么?
  2. autoreleasepool 是怎样实现的?
  3. __unsafe_unretained 是什么?
  4. Block 是怎样实现的
  5. 什么时候会引起循环引用,什么时候不会引起循环引用?

所以我将在本篇博文中详细的从 ARC 解释到 iOS 的内存管理,以及 Block 相关的原理、源码。

2 从 ARC 说起

说 iOS 的内存管理,就不得不从 ARC(Automatic Reference Counting / 自动引用计数) 说起, ARC 是 WWDC2011 和 iOS5 引入的变化。ARC 是 LLVM 3.0 编译器的特性,用来自动管理内存。

与 Java 中 GC 不同,ARC 是编译器特性,而不是基于运行时的,所以 ARC 其实是在编译阶段自动帮开发者插入了管理内存的代码,而不是实时监控与回收内存。

阅读全文 »

Why 我丢失了 Github 账号

从前天,经过了两天时间与 Github 客服对话,终于找回了我的 Github。

朋友在问我为什么登陆不了 Github 的时候表示不太理解。

原因很简单,因为我丢失了两步验证的 app,也丢失了 recovery code。

阅读全文 »

What has Happened?

上周,leader 拿着 iPhone 7 打开了网易新闻,问我:『你看,你这里的下拉刷新是短震动,我们的手机数周遥控电视的时候只有长震动,产品那边问能不能用短震动』。

然后博主就去查看了一下关于短震动的方式,整个过程可以描述为——『资料真少!』。

不过最后通过一下午的搜集,最终还是总结整理出来了这份文档,也补充了自己对 iPhone 6s 之后对 Taptic Engine 的了解。

阅读全文 »