您现在的位置:首页
--> idea's blog
常规的单机软件升级, 一般认为是一个原子操作, 也就是说, 软件会在"瞬间"完成升级, 即使不能在"瞬间"完成升级, 也要中断服务, 等升级完成后再提供服务.
对于需要中断服务的情况, 在分布式系统中是不能接受的. 同时, 分布式系统的升级永远不可能在"瞬间"完成. 因此, 分布式系统升级会面临一个长时间的中间态, 新旧版本的软件同时运行, 这就涉及到兼容性问题.
广义的可靠通信不限于计算机网络通信, 只要两个物体具有发送和接收能力, 或者两个物体之间有发送和接收动作, 均属于通信范畴. 例如人于人的声音对话, 身体语言等等. 可靠通信至少包括三项要求:
不丢包
不重复
完整性(原子性)
为了达到这三项要求, 对应有三条定理:
定理一(丢包定理): 确认和重传是解决丢包的问题唯一正确方法
定理二(去重定理): 排队(串行化)是解决去重问题的唯一正确方法
定理三(原子定理): 单点标记或者自校验是实现完整性(原子性)的唯一正确方法
有些同学可能对排队理论有怀疑, 表示搞一个全局位图(标记集合)也能解决去重问题. 如果深究, 判断标记和修改标记是独立的两步操作, 这两步操作就遇到去重问题, 也即, 对标记集合的操作本身也需要排队. 当然, CAS 是一种解决方案, 但 CAS 的实现内部本质也是排队.
有一些文章, 包括 Raft 协议的论文, 已经从反例的角度解释了为什么不允许 Leader 直接 commit 前任的日志, 而是必须追加本任期的一条日志, 以达到隐式地 commit 前任的日志. 我想从 Raft 的几项原则的角度, 在逻辑上解释这个问题。
在做 iOS 上的 XML+CSS UI 布局框架 CocoaUI 的过程中, 我体会到了 Apple 技术的强大之处, Apple 的底层框架和库提供了强大的功能和友好的 API, 我在开发 GUI 框架(上层 UI 框架)时用到的许多技术功能点都是信手拈来.
最近面了多个软件工程师,别看工作经验好几年,看起来好像能“干活”,但是竟然冒泡排序都不会写!这样的行业状况,一旦经济危机爆发,程序员群体估计要仆街。技术当然是成功的关键,但是经济状况出问题的话,行业的价值重估肯定让很多人痛苦不堪。
使用 Mac 系统的终端 ssh Linux 时, 总是提示
-bash: warning: setlocale: LC_CTYPE: cannot change locale (UTF-8): No such file or directory
即使在 Linux 上面修改了 locale 也没用. 原来, 这是 Mac 自己搞的鬼, 它会擅作主张地在你登录远程终端时设置 locale 为 UTF-8, 和服务器设置无关. 所以, 要解决只能修改 Mac 自己的配置文件.
$request_uri:这个变量就是HTTP头部的 path + query_string, 例如 /my/act?a=1。
$uri:这个变量对应到服务器上的一个文件(资源), 所以, 可能不等于 $uri, 因为可能被 rewrite 过. 例如浏览器请求 /my/act?a=1, 对应的资源(URI, $uri) 是 /dir/file.php, 当然, query_string 不属于 uri 的一部分。
由此可见, $request_uri 这个变量的名字是有歧义的, URI 并不包含 query_string, 但这个变量却包含。
什么? Google, 流氓软件? Google 不是 Don't Be Evil 吗? 它怎么会和流氓联系在一起? 没错, 说一套做一套.
对于 Web 服务器返回的 HTTP chunked 数据, 我们可能希望在每一个 chunk 返回时得到回调, 而不是所有的响应返回后再回调.
Objective-C 和其它所谓的 Unicode 友好型编程语言, 大多对内存不友好, 这些语言一提到"二进制", 好像就当机了一样.
所以, 我认为 PHP 确实是最好的编程语言, 对于 PHP 来说, 字符串就是二进制, 二进制就是字符串, 不管你什么字符集. 这并不是说 PHP 支持 Unicode, 事实上, PHP 对 Unicode 的支持是最友好最高级的. 例如, 拿到一段内存, 你想把它当作为 UTF-8 或者 UTF-16, 随你意, 只要你认为它是什么, 它就是什么, 然后, PHP 提供了对应的函数来处理.
回到题目, 在 Objective-C 里, 要将一段二进制数据(也就是一段内存)进行 urlencode(URL 编码), 应该怎么做? 很不幸, CFURLCreateStringByAddingPercentEscapes() 函数只处理字符串. 没错, 又是字符串! 这就是不把字符串当二进制的坏处!
CSS 的完整英文名称是: Cascading Style Sheets, 级联样式表. 除了可以定义丰富的样式, 以及进行界面控件布局外, CSS 最重要的特性便是名字中的"级联(Cascading)"一词. 级联代表了父子关联, 天生便是和数据结构中的"树"相关的.
我创建的 CocoaUI iOS UI 框架, 是一个使用 CSS 进行 iOS 上流式布局的开发框架, 极大地方便了 iOS 应用的界面开发, 轻松适配多种屏幕. 因为 CocoaUI 使用 CSS 来进行界面布局和定义界面样式, 所以需要对 CSS 的样式规则进行匹配, 将某一条 CSS 样式作用到某一个 UIView(IView) 上面.
基类中为了方便原则, 一般会加载所有可能用到的属性到 Context 中, 但这会导致性能问题, 所以需要 lazyload 机制. 例如, 某些属性只有在子类中被用到时, 才会真正地去查询数据库, 如果子类中不使用这些属性, 则不会发生数据库请求。
低级程序员认为自己与高级程序员的区别, 主要是高级程序员任何功能都能编码实现, 编码速度快, 代码无 bug. 正如一惯的那样, 低级程序员之所以低级, 正是因为他们勉强能看到(或者根本看不到)事物的表象而看不到本质. 所以, 低级程序员总结出的一切东西, 你都可以大胆的忽略.
所以, 我们来听听高级程序认为自己与低级程序员的区别是什么. 高级程序员之所以高级, 在于他们认识到代码 bug 是不可避免的, 有千万种理由可以导致 bug, 但他们可以在设计和逻辑上保证(追求)滴水不漏, 并用逻辑的百分之百准确性还减少代码 bug. 没错, 严谨的逻辑能力是高级程序员区别于低级程序员的最主要原因.
业务场景:
* server A 经常需要使用rsync将文件同步至 server B
* rsyncd 的配置稍显复杂,不想在 server B 上配置rsyncd
* 出于安全性的考虑,不能完全开放 server A 至 server B 的ssh权限
很多C/C++程序虽然在做网络编程, 但大多用别人封装好的库, 对底层不甚了解, 感觉 IO 操作不是很简单吗? 我敢说, 大多数人进行 IO 的姿势都不对, 所谓的 IO, 主要是 read()/write() 两个函数.
iPhone 手机的成功, iOS 操作系统功不可没. 而 iOS 操作系统的成功, 与早期 iPhone 单一的屏幕分辨率也有极大的关系. 不客气地说, 正因为早期 iPhone 手机只有一个分辨率, iOS 操作系统和其上面的 App 才不需要关心所谓的"响应式布局", "流式布局", "自动布局"这些技术, 它们只使用绝对定位的布局 - 每一个控件的大小和位置都是定死的, 几乎不变. 这样, iOS 应用开发者把精力放在了界面外观和交互体验, 最终促成了 iPhone/iOS 的成功.
不过, 从 iPad 的出现, 到 iPhone 5 发布, 以及后面的 iPhone 6/6+, iPhone/iOS 手机的屏幕分辨率开始多样化了, 这时, 界面布局便不能死守着绝对定位布局了.
为了解决这个问题, 苹果的方案是"Auto Resizing"和"Auto Layout", 特别是后
最简单的流式布局模型, 其实就是: 靠左, 靠右, 或者堆叠. 根据这个简单的理论, 可以用两个栈(Stack)数据结构, 一个表示靠左边的控件列表, 另一个表示靠右边的控件列表, 即可实现流式布局模型.
SSDB 的网络协议非常简单, 而且是业务无关的, 所以你可以把 SSDB 的网络协议应用于几乎所有类型的应用! 只要遵循 SSDB 的网络协议, 你就可以使用 ssdb-cli 命令行工具来连接, 与服务器交互, 或者方便调试. 你甚至可以使用 nc 命令来和任何一个支持 SSDB 网络协议的服务器交互.
SSDB 的主从同步策略非常简单, 就是把主(Master)上的所有写操作(Binlogs), 在从(Slave)上再执行一遍. MySQL 的主从同步也是一样. 而多主可以理解为互为主从.把 Master 上的所有操作(Binlogs)在 Slave 上执行一遍, 说来很简单, 但还是会遇到一些难题, 例如 Binlogs 不可能无限地永久保留. SSDB 只保留最新的 1000 万次写操作. 对于熟悉 MySQL 的同学可能也知道这样的例子: 在有 Binlogs 之前, 数据库内已经有了一部分数据. 也就是说, 这部分数据是无法通过 Binlog 来获得的.为此, 要有一个基础数据的拷贝(Copy)过程. 对于 MySQL 来说, 必须由 DBA 手动拷贝. 而对于 SSDB 来说, 这是自动的.
JavaScript 的闭包是一个其主动发展的特性, 也是一个被动发展的特性. 也就是说, 一方面, JS 有了闭包能更好解决一些问题. 另一方面, JS 为了解决某些问题, 而不得不使用闭包勉强来解决问题.
前者这里不讨论, 如果 JS 闭包能更好的解决问题, 当然使用闭包更好.
我讨论的是后者, 是因为 JS 本身的限制, 而不得不磕磕绊绊地用闭包来解决的问题, 例如"变量只初始化一次"这样的需求.
近3天十大热文
- [53] IOS安全–浅谈关于IOS加固的几种方法
- [52] 如何拿下简短的域名
- [52] Oracle MTS模式下 进程地址与会话信
- [50] android 开发入门
- [50] 图书馆的世界纪录
- [48] 【社会化设计】自我(self)部分――欢迎区
- [45] 读书笔记-壹百度:百度十年千倍的29条法则
- [45] Go Reflect 性能
- [42] 视觉调整-设计师 vs. 逻辑
- [40] 界面设计速成
赞助商广告