Becomin' Charles

算法 | LNMP | Flutter | Mac

Becomin' Charles

如果你正在斯坦福、Coursera或者可汗学院学习在线课程,那么这种开始方式,已经很好了。

你可能还需要尽可能多地去学习数学(包括统计),因为数学是机器学习的基础。

我非常推荐的一本书是Programming Collective Intelligence。这本书的数学很浅,只需要基本理解Python就可以通读此书而没有什么障碍。如果你已经在学习大学级别的机器学习课程,你可能会觉得这本书对你来说太过基础了一点。

Programming Collective Intelligence: Building Smart Web 2.0 Applications: Toby Segaran

对于一些更高级的话题,你可以试试如下的书,基本按照需要数学知识的多少来排序:

Amazon.com: Risk Assessment and Decision Analysis with Bayesian Networks (9781439809105): Norman Fenton, Martin Neil: Books

Artificial Intelligence: A Modern Approach (3rd Edition): Stuart Russell, Peter Norvig: 9780136042594: Amazon.com: Books

Learning Bayesian Networks: Richard E. Neapolitan: 9780130125347: Amazon.com: BooksEdit

Quoar原帖

Updated:

另一个回帖的人,认为学习Machine Learning没那么简单,并提出该学科是一个高度交叉学科,想要深入,需要准备好很多先修课程的知识,包括但是不限于:

  1. 微积分。最好所有的知识都具备,极限(Limits),differentiation,integration。
  2. 线性代数。甚至要理解最简单的回归模型,都需要它的知识。通常是机器学习课程最先教的东西。
  3. 统计学。超级重要。机器学习其实是一族统计分析的方法,所以它是在统计学的根基上发展起来的。对所有的统计分析方法,有一个很好的掌握,是绝对必须的。
  4. 计算机科学基本知识。具体说,算法,包括数值算法(从牛顿法,到蒙特卡洛模拟技术)。这与机器学习在很多地方是重合的,而且经常被用于机器学习的一些基础算法。
  5. 编程。机器学习是一个应用学科,你需要掌握一门编程语言来运行算法。Python学习简单,在机器学习专家中,应用广泛。

想要把丢掉的东西捡起来,还是很辛苦啊,今天我就发现,我连char* 和 char []的区别都不知道。

1
2
3
4
5
6
7
8
9
10
11

#include

int main(int argc, char* argv[]) {
char* buf1 = "this is a test";
char buf2[] = "this is a test";
printf("size of buf1: %d\n", sizeof(buf1));
printf("size of buf2: %d\n", sizeof(buf2));
return 0;
}

结果是:

1
2
3
4
5

$ > ./main
size of buf1: 4
size of buf2: 15

购买了Linode的同学,一般都会在Linode上安装部署各类技术解决方案,解决程序员的信息查找和咨询访问问题。这类方案里,本人首推使用shadowsocks,简单、轻量、稳定易用。但是在某些特殊的场合,非VPN不能解决问题。在各式各类的VPN方案里,我首推L2TP over IPSec,协议加密,内容加密,给未来还是要留个出路的,不然都被扫出来封掉,那太悲催了,我不忍细想。

如果安装的的Debian系统,那么整个部署流程会很方便愉快,但是最近这个问题,困扰我将近半年之久了,就是这个突然不工作了,多方查找才知道,是openswan版本存在bug,导致不兼容,致使L2TP over IPSec的方案无法尽功。有问题的版本如下:

1
2
3
4
5
6
7
8
9
10

# aptitude show openswan
Package: openswan
State: installed
Automatically installed: no
Version: 1:2.6.37-3+deb7u1
Priority: optional
Section: net
Maintainer: Rene Mayrhofer

想要恢复正常也比较简单,降级即可:

1
2
3

# apt-get install openswan=1:2.6.37-3

将openswan的版本降级后,重启IPSec,一切恢复了正常,世界清净了!

如果购买Linode,可以考虑使用我的referral code,算是对我的支持,谢谢:f268347f24b5221e45c9a1048cb8b8db0f0c241a

在Mac上,管理命令行软件包,使用Homebrew,它的原理主要就是将软件安装在一个固定的目录,然后将二进制文件的路径,加入到系统的PATH中,
这样,系统就可以正确识别到命令。PATH的顺序会影响到系统搜索命令的顺序。

brew使用的/usr/local/bin默认已经在Mac系统的PATH里了,但是在最后面。通过 echo $PATH命令可以查看。

但是对于想要使用新版本的人来说,这就不方便了。所以,就要想办法调整PATH的顺序。

sudo vi /etc/paths

就可以在里面调整PATH的搜索顺序了,这个我特意去Linux系统里看了一下,不是这样的,看来是Mac系统特有的。
一般在Linux系统里调整PATH顺序都是在 .bash_profile或者 .bashrc里面,执行

export PATH=/usr/local/bin:$PATH

如果数据库只有一份,那就是数据存储的单点,对于要求可靠性的服务来说,就存在一个单点故障的可能性,这个时候,我们就要通过复制镜像,来解决单点故障。复制还有一个额外的好处,就是可以根据主从,做读写分离,这样,就不会在写入的时候,因为锁表,而降低MySQL的并发性能,所以MySQL复制是MySQL中非常基础的一种操作。

怎么配置

配置Master

首先,要做的是确定一个Master,对于充当Master的MySQL Server来说,需要一些特定的配置才能实现,一个是开启binlog,另一个是要设置server-id。

[mysqld] log_bin = mysql-bin server-id = 1

配置Slave

配置Slave,对于Slave来说,要配置的就是一个唯一的server-id。这个id不能跟Master相同,而且,多个Slave也不能相同。配置完毕后重启。

[mysqld] server-id = 2

创建User

在Master创建一个user,专门用于进行复制用途的。因为在Slave上,user和password会被用明文存储,所以,这个user的权限要尽可能的小,一定要不同于超级用户。

create user repl@'your.domain' identified by 'password'; grant replication slave on *.* to repl@'your.domain';

注意,这里第2句,grant语句,必须是赋权限给*.*的,因为replication slave权限是一个global privileges,所以,必须这样,如果想要限制权限在一个比较小的范围,不想复制所有的db的话,可以在my.cnf增加配置项replicate-do-db和binlog-do-db来限定数据库的范围。

获取Master的位置

在Master的数据库上,知行flush tables with read lock;语句,然后知行show master status;这时候,就可以看到当前的binlog文件名和当前知行的sql语句位置。将文件名和执行的位置都记录下来。

这时候,如果Master的数据库的内容非空的话,应该做的事情,就是使用mysqldump来导出数据。空数据库的话,就没必要做什么事情了。

建立连接

在上文空数据库的情况下,是很简单的,stop slave,直接在slave上使用change master to语句,将各项参数设置完毕后,就可以执行start slave了。

如果Master原来有数据,应该把刚才生成的dump文件,传送到slave上,然后首先stop slave,然后导入dump的数据,然后执行change master to语句,将刚刚dump前记录的bin文件和位置都设置正确,然后才能start slave,其实也不麻烦。

状态检查

在比较理想的世界里,到这里,我们的工作就结束了,但是,世界是不理想的,因为各种原因,这种replication的联系,经常会中断的。所以要时不时检查这个联系。

在Master上可以执行show master status看到的东西和上面看到的是一样的。

在Slave上可以执行show slave status,可以看到很多的信息和错误提示。一般情况下是没错的,一旦发生错误了,就应该从这里获取相应的信息来解决问题。

http://quercus.caucho.com/

昨天晚上,仅仅是出于好奇的搜了一下,竟然真的有这种项目的存在,在JVM之上,实现了一个PHP。人类已经不能阻挡Java的节奏了啊。

关于这个,要在以前的我一定会嗤之以鼻,这算什么东西呢,不伦不类的。但是现在的话,也不得不静下心来想想,为什么。

PHP的门槛低,这个主要体现在,第一,程序员多,因为PHP的成功,为全世界培养了海量的程序员,不敢说多靠谱,至少数量多的,那么对于某些企业来说,招聘PHP程序员会比Java容易一些;第二,部署容易,PHP之所以流行,这也是至关重要的一个原因,只要拷贝文件即可;第三,成熟的应用很多,现在Web产品里,面向个人的应用里,很多都是PHP开发的,如果想直接运营这么个产品,直接拿过来,是很理智的。

Java技术成熟,Java的技术太过悠久了,积累了无数的可以使用的类库,还有就是中间件。做这么一个东西,也是一个合理的想法吧,博采众家之长嘛,至少可以融汇Java和PHP的优点。

提高性能,PHP是解释执行的,但是Java是编译执行的,至少是存储成中间码再执行。两者结合的话,PHP可以从解释执行,进化到字节码执行。号称Drupal可以这个平台上,性能提高4X。并非没有可能,如果再左以连接池啊等等东西的话。

当然了,银弹是没有的,但是我觉得这还是一个很好的尝试!而且我看2014年竟然还发布版本了,至少这个还是保持活跃的。知道一下这个东西也好,或许哪天会用到。

这是一个交互案例,很多时候,我们可能就是需要一种交互来完成一个操作,但是我们就是没法想出来很好的解决方案,这种的案例,我遇到不胜枚举,但是每次,我都没有把这种奇葩交互给记录下来,今次,我就想到了要记录下来这个事情,以便今后查倒的时候,可以有据可凭。

为什么

不知道多少人,看了我的标题,能理解出来我要做的是个什么交互?其实场景是这样的,我写了一个 WordPress 的插件,功能是显示博客的文章归档,名字叫 Better Extended Live Archive,这个插件目前能提供三个 tab,每个 tab 一种归档的纬度,来展示用户博客的文章列表,比如按照时间纬度,按照分类纬度,按照 tag 的纬度。

从上图中,我们可以看到,有三个 tab,分别是 By Category,By Date,By Tag,这三个 tab 的显示与否,是可以在后台配置的,同时,这三个 tab 的显示顺序,也是可以可以配置的。所以本文的问题就来了,怎么样让用户决定显示与否以后,再决定其显示顺序?

我想出来的方案

其实,要实现这个根本不难,你肯定会这么说对不?左边一个列表框,右边一个列表框,然后右边代表“待选”,左边代表“选中”,然后加一个上下按钮,来调整顺序,这其实就是用标准的 HTML 组件拼装这个交互的例子了,但是,如果我写插件的时候那么去实现,工作量要大好多,第一个,我要用 PHP 去渲染两个列表框,这就很麻烦了,第二,我要再页面上写一堆 js,来实现左右移动的,上下调序的交互,太累。

而实际上,从本质上,一个列表框,就能包含这两重含义了,第一,multiselect,可以让列表框多选,就可以表达选中这层含义;第二,列表本身是有顺序的,就可以表达顺序,那么为什么一个控件能表达的东西,我却要花那么大力气去实现呢?

所以,第一版的时候,我就真的放了一个列表框在那里,可以多选,选中一项点保存后,就会优先显示被选中的,将没被选中的 tab 接到列表的末尾。提交的时候呢,因为只提交选中的项,所以,被提交的顺序,是列表显示的顺序。只有一个单一列表的时候,这个列表通过这么个简单处理,就可以完成我说的两重任务。先显示选中项,这就表示,通过选中某个并保存,可以调整列表显示顺序。也即,通过若干次选中,并保存后,我可以用一个单选框,模拟出任何我要的选中状态和顺序。

最终采纳的方案

通过论证和实验后,我真的把这样一个版本给提交发布了。因为我认为它在功能上是完备的,完全可以表达我想要表达的逻辑了,当然了,使用这样的东西,还是需要技巧和逻辑的基础的。充其量,这是一个 60 分的功能,能用,但是难理解,难用而已。不是坏的。

当然了,如你想见,你不能总是交给一个用户仅仅能用的东西。在第二个版本中,我就改进了这个设计。它需要的不仅仅是完备,而且要好用。就好像图灵机很就牛逼了,那又怎么样,我还是需要 iPad。作为读者,如果我不做个动画,估计你们光从文字描述都看不懂我在说什么,不过没关系,你只要知道我最终采用那个方案就行了。

我通过搜索“select and sort”这样的关键词,竟然真的找到了解决方案,而且同样不需要我花多大的力气。主要是有人在 StackOverflow 上问了这个问题,最佳答案里,竟然也给出了让我相当满意的答卷

是一个叫 jQueryUI Multiselect 的插件,很赞!第一,我仍然只需要一个列表框就行了,因为我分析过了,一个列表框显然可以表达两重意思,只是交互不友好而已;第二,交互通过 js 完全补全了,而且是渐进式增强式的,就是说,没有这个 js,或者 js 不起作用,就退化到我原来的方案,其作用了,就变得很好用。Perfect!

总结

作者能想出来这个插件,并按照这样的方式去构建,简直让我拍案叫绝。真是英雄所见略同,但是我比他懒!

我自己想了想,貌似只有很傻的办法呢:

  1. 创建一个新的空数组,插好要的数据,然后把原来的数组接在后面,用foreach可以,但是弱爆了,不如用+。
1
2
3
4

1, 'b' => 2);
$new = array('c' => 3) + $original;

  1. 先将原数组 array_reverse 一下,然后用 array_push,然后再 array_reverse,不错,不如第一个效率高。

你们想想看啊?

OAuth1.0Core

现在已经是OAuth2.0的时代了,整个中国互联网圈子,基本都在使用OAuth2.0了,但是我们可以看到,Twitter,这个曾经引领 了互联网开放平台的先驱,依然固执得坚持着使用OAuth1.0,而且现如今都在使用OAuth2.0的这些中国互联网平台们,也都经历过 OAuth1.0的历史阶段。了解历史才能展望未来,就让我们来看一下什么是OAuth1.0吧~

阅读全文 »