什么是人工智能

 人工智能Artificial Intelligence, AI)亦称机器智能,是指由人工制造出来的系统所表现出来的智能。 — wikipedia.org

 从 深蓝到 AlphaZero,人工智能的智力水平、普适性、学习能力 正在以爆炸式地速度快速发展;
 从 棋类到 医学,人工智能开始在各类应用领域,都在大展身手;
 从 CPU / GPU 到 TPU,人工智能的计算能力正向着无法穷举的极限不断逼近 …

 但是,我们并不浮躁,踏踏实实地点亮 AI 知识树的每个枝叶,才是我们每位富有科学精神的人所应该做的

关于本文

 我们将分为三块对 AI 进行诠释

 首先,将介绍人工智能的主流思想实用技巧,通过一些耳熟能详的有趣定理,我们可以对人工智能有些直观、初步的认识;随后,言归正传,我们将开始接触 AI 领域的几大理论支柱,由浅入深地学习 统计学微积分线性代数概率论 等知识体系;最后,落地到实践,我们需要紧跟人工智能的技术发展前沿,对重大的突破性项目进行了解、学习,以及运用。如此,对人工智能领域进行横向分层,可以很方便地找到我们学习的突破点

 不过,出于文章编排的考虑,可能部分编码就要放在其他博文中了,如有不便,还望见谅(Python、Prolog、R、Java)。本文持续更新中,若有不妥之处,还请不吝赐教哈 (^o^)/

主流思想

演绎法 & 溯因法 & 归纳法

(利用 Axure™ 绘制而成)

实用技巧

Occam 剃刀原理

 奥卡姆剃刀(Occam´s Razor),意为简约之法,是由 14 世纪逻辑学家、圣方济各会修士奥卡姆的威廉提出的一个解决问题的法则,即"切勿浪费较多资源,去做'用较少的资源,同样可以做好'的事情",相同思想见于郑板桥的删繁就简三秋树

阅读全文 »

开发人员用一种语言就能编写整个 Web 应用

 可以减少开发客户端和服务端时所需的语言切换(Clojure, ClojureScript 一样的道理)
 代码可以再客户端和服务端中共享(表单校验或游戏逻辑中使用同样的代码)

JSON 是目前非常流行的数据交换格式

 JSON 还是 JavaScript 原生的

有些 NoSQL 数据库中用的就是 JavaScript 语言

 MongoDB 的管理和查询语言都是 JavaScript
 CouchDB 的 Map/reduce 也是 JavaScript

JavaScript 是一门编译目标语言

 List of languages that compile to JS

Node 用的虚拟机(V8)会紧跟 ECMAScirpt 标准

 在 Node 中如果想用新的 JavaScript 语言特性,不用等到所有浏览器都支持

阅读全文 »

关于本文

 虽然接触 Java 已经 8 年之久,可惜学习之初的笔记文档没能很好地保存下来。本文是近几年工作学习中遇到的一些零散的知识点,包括了 基础概念、实用的编程技巧、代码可读性、设计模式、性能优化(工具 & 编码)、测试相关、JVM 相关、常用的工具和常见问题。本着好记性不如烂笔头的初衷,在不断地踩坑和爬坑的过程中,慢慢地记录成文。期待着本文能起到抛砖引玉的作用,以看到大家的真知灼见。

基础知识

注解

GuardedBy

 @GuardedBy 注解可以作用于某一个属性或者方法,约定在访问这些被注解标记的资源时,能被同步代码块保护着。简单的使用案例如下:

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
28
@GuardedBy("obj")
private ConcurrentMap<String, String> map = new ConcurrentHashMap<>();
private final Object obj = new Object();

public void put(String k, String v) {
synchronized (obj) {
map.put(k, v);
}
}

/**
* If you use `error prone` tool to check this, this annotation should be `@SuppressWarnings("GuardedBy")`
* {@see https://errorprone.info/bugpattern/GuardedBy}
* {@see https://github.com/apache/druid/pull/6868#discussion_r249639199}
*/
@SuppressWarnings("FieldAccessNotGuarded")
public void remove(String k) {
map.remove(k);
}

@Override
public String toString() {
synchronized (obj) {
return "GuardedByExample{" +
"map=" + map +
'}';
}
}

Tips: Code Example from Apache Druid;另外,error-prone 工具支持对多种版本@GuardedBy 进行检查

阅读全文 »

什么是 Docker?

Docker™ provides a way to run applications securely isolated in a container, packaged with all its dependencies and libraries.

环境搭建

MacOS

1
$ brew cask install docker

Windows

下载

 从 Toolbox 的 Archive 页面找到 DockerToolbox-19.03.1.exe 并下载

安装

 注意安装组件的时候,选择 Full installation,其他的均使用默认的选项,即可

配置

代理
1
$ vim ~/.docker/config.json
1
2
3
4
5
6
7
8
9
{
"proxies": {
"default": {
"httpProxy": "socks5://127.0.0.1:1080",
"httpsProxy": "socks5://127.0.0.1:1080",
"noProxy": "*.yuzhouwan.com"
}
}
}
阅读全文 »

LeetCode 组队刷题活动

组队刷 LeetCode

介绍

代码仓库

 代码仓库的坐标:asdf2014 / algorithm

报名途径

 只需要在《Algorithm》文末留言,即可随时参与

留言内容的话,至少要留一下自己的 Github 名称,方便我们这边统计汇总。另外,也可以说明下自己能接受的刷题频率、希望的选题策略,亦或者,对算法知识沉淀的模式有好的建议,都可以提出

参与方式

 每位参与的小伙伴,都会获得代码仓库的 Collaborator 权限,可以自由地提交代码(不限制语种)。在 /Codes/${User} 目录下,每人都将拥有一个自己的代码库。留下 Github 名称后,将很快会收到邀请函,大家可以在 asdf2014 - algorithm - invitations 链接中认领。随后,可以在任意目录下(不需要是空目录),使用如下命令,一键完成您的第一次代码提交:

1
bash -c "$(curl -L https://raw.githubusercontent.com/asdf2014/algorithm/master/first_commit.sh)"

刷题频率

 考虑到可能大家的闲暇时间并不多,我们暂定刷题频率为“一周一题”

选题策略

 分为两个阶段:

  • 前 100 题都是经典中的经典,所以我们第一阶段先将这些题目吃透
  • 第二阶段,通过程序进行随机选定,历史题库可以点击链接看到

其他

 操作 Git 时遇到问题的话,可以参考我的一篇博客《Git 高级玩法

也可以直接在文章最后留言。目前,支持 Gitalk + Disqus 两种留言系统,以便更好地服务于国内和海外的小伙伴

 同时,为了大家更加方便地交流,也欢迎加入算法 QQ 群 或者 Gitter 聊天室

但是,请不要在评论区讨论入群问题的答案,避免打广告的进入

 另外,因为大部分算法都会有很多实现思路,我们会尽可能地展现所有可能的解题方法。但为了文章的排版更加地紧凑,我们会将同一算法的不同实现,通过选项卡的形式展现。且默认展示的选项卡将会是最优解。这样的话,如果您想要快速阅读本文,则可以不用翻看其他的选项卡。实际效果如下:

迭代解

1
2
3
4
5
6
7
8
9
10
11
def solution(n):
if n <= 1:
return n
a = 0
b = 1
while n > 1:
n = n - 1
sum_ = a + b
a = b
b = sum_
return b

递归解

1
2
3
4
5
def solution(n):
if n <= 1:
return n
else:
return solution(n - 1) + solution(n - 2)

动态规划解

1
2
3
4
5
6
7
8
def solution(n):
if n <= 1:
return n
cache = [x for x in range(0, n + 1)]
cache[1] = 1
for i in range(2, n + 1):
cache[i] = cache[i - 1] + cache[i - 2]
return cache[n]
阅读全文 »