Technology and Investing Blog


  • Home

  • About

  • Tags

  • Categories

  • Archives

七天学会Python编程 -- 第二章 基础入门

Posted on 2018-11-19 | In 技术 |

2.1 先一起写个 Hello World

1
print "Hello World"

保存上面这行代码到一个名字为 helloworld.py* 的文件里,这就是一个完整的可以运行程序了。

翻译一下这行代码,print 是 Python 提供的函数,可以直接拿来用。函数后面会详细讲,这里可以看作是一种可以重复使用的代码,print 函数的目的是打印信息到屏幕上。背后是 Python 提供的一段代码,当你使用时,会触发后台代码,并运行这段程序代码,可以重复使用。也就是说你用这个函数的时候也就是在用背后的那段代码。

用函数有几个关键要素,一个是函数名称,这里是 print,另一个是参数,就是你要传给这个函数的数据,让这个函数去处理。对这个 print 函数来说,参数就是你要它打印的信息,就是 “Hello World”这个字符串。

字符串是什么?字符串是一种数据类型,常见的数据类型有数字型和字符串型,数字型是能进行加减程序运算的,例如 10、35 这样的;字符串主要用于文字记录,比如姓名和电话号码这样的信息。

print 和 “Hello World” 之间的空格表示把 “Hello World” 这个字符串作为参数传给 print 这个函数,这是 Python 的语法。其实函数的通常用法是 print(“Hello World”),也就是函数名字后面是括号,括号里面是参数,但 Python 既允许函数名字和参数之间用空格,也可以用括号。

再看下这行代码

1
print "Hello World", "Hello again"

这是什么意思?这表示传两个参数给 print 函数,这个函数都会打印出来。也可以这样用:

1
print("Hello World", "Hello again")

下面我们运行一下这个程序,要了解一些命令行操作了。这里假设你使用 Windows 电脑并且已经安装好 Python 环境。

鼠标点击屏幕左下角的 Windows 图标,选择”运行”,在出现的输入框里输入 cmd 后按回车键,这时会打开一个黑色背景的窗口,里面就可以输入命令了,敲入 cd 程序保存目录,例如 cd c:\programs ,表示你的程序保存在 c:\programs 目录下,你在命令行窗口里切换到这个目录下。

敲入 python helloworld.py 后按回车,这时候就会打印出 “Hello World”。

Python 是安装的 Python 环境提供的命令,用于执行 Python 程序文件。helloworld.py 就是刚才你保存的那个程序文件的名字。

*:一般的 Python 程序都是以后缀名“py”来创建的。程序会通过此识别 Python 程序文件。

2.2 什么是变量?

先大概讲一下计算机的主要组成,CPU 和内存是主要组成部分,CPU 是用于计算的,它可以飞速地处理计算。内存是用于暂存数据,而硬盘是永久保存数据。

变量是用于标识内存中的某块存储空间,用于存储某种数据,比如这行 Python 代码

1
a = 10

就表示定义一个名字叫 a 的变量,在内存中分配一块存储空间,暂存 10 这个数据到这块空间里,这种让一个变量等于一个数值的操作叫作赋值,赋值这个概念后面会经常用到。

上面的内容可以有点难理解,举个生活中的例子来描述一下。比如你有个篮子,放进去两个苹果,这个篮子可以看作是变量,两个苹果是里面的数据,两个苹果可以换成1个苹果,或者换成3个桔子,表示变量里面的数据是可以变化的。

为什么要用变量?让我们看个例子,假设你要写个加法计算器程序,让用户输入两个数字,你的程序把两个数字加起来,显示出结果。用户输入的这两个数字就需要暂存到内存里,然后把计算结果也暂存在内存里,最后再把结果显示出来。

常见的变量类型有数字类型、字符串类型和布尔类型,例如上面用 a = 10 定义的 a 就是数字类型 int。而 b = “Hello World” 定义的 b 就是字符串类型 str。c = True 定义的 c 就是布尔类型 bool,布尔类型常常用于条件判断指令。布尔类型可能有些难以理解,其实就是相当于一个嫌疑人说出辩词,法官根据证据判断真假。判断结果有罪或无罪。

数字类型可以进行加减乘除,例如下面的代码:

1
2
3
4
5
6
7
a1 = 10

a2 = 20

a3 = a1 + a2

print(a3)

上面代码是定义了3个变量,a1 和 a2 是直接赋给了数值,a3 是等于 a1 和 a2 相加的和,然后把 a3 打印出来。

2.3 列表是什么?

列表是指一个变量名字表示内存空间中多个数据,例如这行代码就是定义一个列表:

1
a = [10, 20, 30]

这个列表变量名字是 a ,有3个数据,中括号就表示一组数据。相当于一个篮子,里面有苹果,梨和橙子,这些水果就是数据,而装着水果的篮子就是一个列表。

为什么要用列表?

是因为在一些情况下用单个变量表示很多数据时比较麻烦,例如我们要用单个变量保存一万个学生的数学考试成绩,是不是要定义一万个变量?像这样:

1
2
3
4
5
6
7
8
9
a1 = 90

a2 = 92

a3 = 89

a4 = 85

...

而用列表就可以这样定义了

1
a = [90, 92 , 89, 85, ...]

读取单个成绩时用这样方式:

a[0] 表示访问第一个数据,a[1] 表示访问第二个数据,依次下去。中括号里面的数字是顺序号,从 0 开始计算,第一个数据的顺序号是 0。

Python 用 list 表示列表,其他编程语言里还有数组的概念,数组一般是指数据数量不可变的,比如前面的一万个学生的数学成绩,如果想增加几个或减少几个都不可以。而列表一般是可变的,比如一开始只有 3 个数据,可以再增加两个,也可以再减少几个,所以用起来很灵活。Python 不区分数组和列表,都统一为列表。

2.4 字典是什么?

字典在 Python 里叫 dict,在其他语言里叫 Map,也是指一个变量名字表示内存空间中多个数据,但这多个数据在字典里面又可以定义容易识别的名字,这个名字也叫 key 值,而不是像列表那样只能用顺序索引去访问。

例如下面就是定义一个字典:

1
a = { "name": "Tom", "mobile": "1300000" }

我们可以用 a[“name”] 访问字典内的一个数据,用

1
print( a["name"] )

来读取数据后打印,也可以

1
a["name"] = “John”

这样是修改一个数据。

列表跟字典的最大差别是字典提供了更容易识别的内部数据访问方式,而列表只能用顺序索引,有时候容易搞混。

字典的常用使用方法有这几个,一个是判断某个 key 值是否存在,这样用:

1
2
3
4
5
a = { "name": "Tom", "mobile": "1300000" }

isNameExisted = "name" in a

print( isNameExisted )

“name” in a 这个就是判断某个 key 值在字典中是否存在,上面代码是把判断结果放到 isNameExisted 变量中,是布尔类型,True 或 False,上面代码会打印 True。

从字典里删除某个 key 值及对应的数据是这样用:

1
2
3
4
5
6
7
a = { "name": "Tom", "mobile": "1300000" }

del( a["name"] )

isNameExisted = "name" in a

print( isNameExisted )

上面代码会打印 False,因为我们删掉了 “name” 这个 key 值。

如果看不太明白可以参照原来列表那个例子,也大致相同。

2.5 对象是什么?

一切皆是对象。

是不是感觉这句话有点夸张?实际上我们前面两个章节学过的变量和列表都是属于对象。

对象的特点是什么?对象一般有属性,也有能被调用的方法,方法也就是函数。例如对 car 这样一个对象,可以有个属性是:

1
car.color = "red"

表示它有个 color 属性,属性的值是 “red”,我们可以用 car.color 这种方式访问属性。

可以有个方法是:

1
car.move()

表示移动,调用这个方法时以为着 car 对象会移动,至于到底怎么移动的我们可以不用管,是 car 对象自己要解决的问题。

那拿我们前面学过的变量为例:

1
a = "a string"

它有这样一个属性

1
a.__doc__

表示对字符串对象类型 str 的用法解释,用

1
print(a.__doc__)

可以打印出来。

它有个方法是

1
a.upper()

表示把字符串里的字母都转为大写字母。

列表的例子:

1
b = [10, 20, 30]

可以用

1
b.append(40)

这个方法追加一个数据。

列表的属性一般用的比较少,主要是使用各种方法,它也可以使用 b.doc 来访问 b 对象对应的列表类型 list 的使用说明。

另外我们也可以自己定义一个对象类型,专业的名字叫“类”,就是我们定义一个类的属性和方法,然后在程序里就可以定义一个变量为这个类的类型。这个比较复杂,在简单程序里用得不多,这里解释一下主要为了后面的课程,可能会用到类。

建议上网更多地了解一下对象的应用和例子。

2.6 实践练习时间

过去这个章节我们学习了变量、列表和对象,现在开始做几个实践练习,可以用在线 Python 练习环境,也可以用本地安装的 Python 环境。练习时注意一定要让程序能正常运行,并且按要求输出结果。

练习1:

写一个程序,定义两个变量,变量名字分别是 a 和 b,给 a 赋值 179,给 b 赋值 257,然后把 a 和 b 相加的和赋给变量 c,打印变量 c 。

练习2:

写一个程序,定义一个列表 list1,里面保存 100, 200, 300, 400, 500 这几个数字,然后把数组里的数字加起来后把结果赋给变量 sum,并且打印变量 sum。

练习3:

写一个程序,定义一个字符串变量 str1,赋值 “Hello Python”,先打印 doc 属性,然后使用 lower() 方法转成小写字母后打印出来。

七天学会Python编程 -- 第一章 概要介绍

Posted on 2018-11-19 | In 技术 |

1.1 为什么让少年儿童学编程?

It’s cool!

跟身边朋友说一下自己懂 Python 编程,能写个爬虫程序把王者荣耀自己想要的英雄的皮肤模型和头像都爬取下来,甚至能写程序恶搞一下自己的朋友,做一个黑客一样的电脑专家是不是很 Cool?

从社会发展趋势角度看

当今社会移动互联网、大数据和人工智能等领域飞速发展,带动社会不断发生变更,根据一些预测分析,未来有超过50%的工作种类都可能被人工智能替代,这对很多人来说可能会失去工作机会,但也意味着会有越来越多的人从事跟人工智能及开发的工作,这是为了让 AI 能替代越来越多的人力工作。

这里带来一个比较沉重的话题,那么多人失业后要怎么安排?根据一些分析,很多人会转向娱乐服务业,因为人工智能让很多人有了足够的休闲时间,这自然就促进了娱乐领域的发展,也相应会有很多人从事娱乐相关的行业,例如电影、游戏、旅游等等。也会有一部分人转向人工智能领域,或者做数据分析,或者做开发,或者其他相关的,这样编程就是一项重要的技能。

从少年儿童自身素质提高角度看

编程需要良好的逻辑思维能力,学习编程会培养少年儿童这方面的能力,让他们思维更清晰、更有条理。

未来教育领域很多科目会跟编程结合,特别是理科类,可能老师让学生编个程序来模拟某个理论,这样能促进学生对该理论的理解。

1.2 为什么选择Python?

主要原因是Python很热门,热门的原因有不少,分析一下主要有下面几个:

1.容易上手

语法相对简单,上手很快,这个是很大优势,因为有挺多编程基础有限的人转来学习编程,他们可能是从其他领域转行过来,如果难度太大就难以在短时间内掌握。

2.规范化程度高

Python程序代码看起来都挺像的,这得益于它在程序格式方面的限制,主要是缩进方面,语法跟排版相结合,看起来很清晰,比较一致。

3.适用面广

Python 以前的普及程度不算高,是最近几年随着大数据和人工智能领域快速普及起来。Python最初在服务器端脚本(简化操作系统管理员的工作)开发方面用得比较多,后来在Web开发领域发展起来,然后又在大数据和人工智能领域迅速发展。

概括一下,Python 可以做服务端脚本开发、Web开发、大数据开发、人工智能开发等等,是不是很强悍?

掌握Python后可以做很多领域的开发工作。

1.3 选用什么电脑学Python编程?

对于Python基础方面的学习,可以用在线的练习环境,任意一台电脑只要能上网就可以打开在线的练习环境,进行实际练习,具体可以看一下附录中的“在线 Python 练习环境”章节。

在线练习环境的优点是不需要在自己电脑上安装Python环境,随时都可以使用;但缺点是不能保存写过的程序,也不能安装额外的Python模块,学到后面不建议用线上编程。

在本书后期的 Web 开发章节,需要有环境能安装Python模块,这时候推荐买一个树莓派,现在卖的是树莓派3小主机,200元左右,预装的系统里Python环境和编辑器都有了,额外再配一套无线鼠标键盘和HDMI线就可以接到电视上作为一套完整的开发电脑用了。

树莓派+外壳+电源线:220左右

无线鼠标键盘:60左右

HDMI线:20左右

总共成本300左右,比较超值。

电脑有几个主要部分,这套环境就是由那几个部分拼接而成的,可以让孩子很好地清楚电脑的结构。现在他们接触的大多是手机、平板电脑等,他们往往不知道电脑具体是怎么组成的。

对于普通的Windows电脑,可以访问Python语言的官方网站的下载地址

https://www.python.org/downloads/windows/

下载 Python 2.7 版本的,这里又有了 3.0 和 2.0 的版本之争,未来 3.0 是趋势,但 2.0 目前是主流。而且对于编程入门来说 2.0 跟 3.0 的差异很小,通过 2.0 版本学会编程后基本可以无障碍地切换到 3.0。

1.4 学习步骤是怎样的?

首先会解释必要的概念,我们会尽量用生动有趣的方式去讲解,然后会举例说明怎样去用,同时会介绍在实际生活中可能的用途。

下面就是实践练习环节,基本每章节都有这部分,目的是为了加深对所学内容的理解。这部分会出一个跟实际有联系的题目,让学习者尝试自己去编程实现。要多发挥主观能动性,有不懂的地方多去翻阅前面的概念解释,或者自己上网搜索资料。

如果有觉得很重要的概念可以做好笔记,不清晰的地方一定要理解透彻,小洞不补,大洞吃苦。

多翻翻学习过的内容,巩固一下以前的。一个复杂的程序也是由简单的内容构成的,所以要多复习一下。

多去想想现实中有什么问题,可以用自己掌握的编程技术去解决一下,不用企图改变世界,每次能解决一个小问题,累积起来可能在不经意间就改变世界了。

1.5 学习过程中要注意什么问题?

学习编程需要多实践,所以有个可以随时用的编程环境是很重要。一开始可以使用附录中在线练习环境,比较方便,到后期一些比较高级的课题需要有个能自己安装Python模块的开发环境。

养成一个习惯,只要在教程里看到代码就去编程环境试一下,不要纸上谈兵。很多时候只是看了理解了,其实认识还不够深刻,只有反复实践才能真正掌握,每次写完程序都尝试用自己的语言翻译代码,这样对理解有很大帮助。从理解慢慢开始到能熟练运用。

要学会去网上搜索资料,如果看教程有不太懂的地方多去上网搜索一下,看看别人是怎么解释的。网上关于编程的资料非常多,特别是有关Python这种热门编程语言的,小到一个命令或函数的用法,大到一个现实问题的解决方案,都能找到相关的信息。

关于教程选择方面,网上可选的编程教程很多,目的都是教让你掌握编程技术,但讲的方式不一样,也不用选太多,找到一个比较适合自己的坚持学完,这样就比较系统地掌握编程的有关内容了,然后可以再选择性地找些其他教程,看看有什么可以补充的,或者对某些知识点有其他解释方法能加深理解的。

学习 Python 的要点

虽然学习 Python 可能会有点枯燥,但不要半途而废。当你解决了一次次问题,克服了一次次困难,最终编出了一套成功的程序后,你会很有成就感的。

不管是学什么,一定要记住:理解胜于记忆。如果你背程序的公式来学习编程的话,那会非常困难。如果理解了再去编写程序,你会很轻松的。对各个概念一定要有清晰的理解。可以学画一个脑图,方便理解,理解总结也是一个很好的习惯。

学会举一反三,学会理解程序的变形和同一用法对不同程序的应用,这可以方便你在之后解决问题时迅速理清思路,构思出程序思路和需要的代码,快速解决问题。

最后,希望你能通过此书走上编程的成功之路。

七天学会Python编程 -- 目录

Posted on 2018-11-19 | In 技术 |

第一章 概要介绍

第二章 基础入门

第三章 条件控制

第四章 循环遍历

第五章 函数

第六章 文件操作

第七章 模块

第八章 数据分析

第九章 Web开发

第十章 附录

七天学会Python编程 -- 前言

Posted on 2018-11-19 | In 技术 |

关于这本书

你想学会当下最火热的编程吗?你想成为一名计算机专家吗?你想在你的朋友面前炫耀一下你的高超技术吗?那么请从此书开始这条成功之路吧。

这本书由浅入深,从刚开始的变量,字符串到后续的Web开发,甚至做出复杂网页功能 ……应有尽有。初学者阅读这本书,能深深爱上编程;技术人员阅读之后,能产生更深层的思考……

未来发展趋势

人工智能随着当今社会的发展变得越来越重要,未来AI会替代人们打扫卫生、搬运木材,甚至还可以开车……而人工智能的实现跟编程息息相关。近期,政府也提出倡议,在中小学开设编程课程。作者针对目前时代的发展,认为有必要让新一代青少年和工作者学会编程并运用它。

有人问:”现在收入最高的产业是什么?”可以毫不犹豫地说是游戏产业。王者荣耀,一款moba类游戏,它仅仅靠一个限定皮肤就在一天收入了1.5个亿。光是这个游戏,就已经打垮了全国80%的上市公司,这在10年前都是不可想象的,也最直接地验证了“科技是第一生产力”这句话。精通了程序开发,你完全可以开发出游戏,创造出不可估量的价值。

作者的话

我是Tim Deng,Ken Deng的儿子。刚开始学编程的时候,我也同样和很多人一样,觉得特别困难。在程序里的很多东西都很抽象。我原来是记忆程序来学习编程的,但如果程序要求变动一下,那你就会一脸懵。所以无论如何不要死记硬背,理解之后要举一反三,才能真正精通编程。下面我列举几个难点,也是我的学习经验:

  1. 理解函数的作用和定义
  2. 对读写文件一定要深入理解
  3. 对模块要有清晰的概念

这就是三大重点难点,只要理解,就会变得简单。

最后,勇敢地打开第一页吧,因为你已经走上了一条成功的路。

Tim Deng
2017-10

区块链入门介绍

Posted on 2018-11-19 | In 技术 |

什么是区块链

区块链的原理是一个个区块通过数字指纹技术连接起来,并且数据保存在很多个节点,难以伪造,也很难篡改,简单来说就是一个分布式账本。

详细介绍

区块

下面详细解释一下,首先看一下区块,区块是表示一个数据存储空间,里面保存多条交易数据。

数字指纹技术

数字指纹技术是指对区块里包含的数据用一种算法计算出一小段类似指纹的数据,表示这个区块的唯一数字指纹,这个区块内的任何数据变动都会使数字指纹发生变化,从而能识别出是否被改动。

链

怎样把区块连接起来?

区块里有个位置会存放上一个区块的编号以及对应区块的数字指纹,一个区块链的第一个区块没有上个区块信息,这第一个区块就成为创世纪区块。比特币的发明者中本聪就是创建了一个创世纪区块,里面是发行给他自己的比特币交易。

防篡改防伪造

那怎样防篡改防伪造呢?每个区块都有个顺序编号,以及上一个区块的编号和数字指纹信息,这样就把各区块连接起来了。如果修改了某个区块的数据,对应数字指纹也会改变,这时在验证整个区块链的有效性时就会出问题,会发现数据被改动过的那个区块。

分布式存储

怎样理解数据存储在很多个节点呢?大家都知道,传统的信息系统是中央式架构,也就是数据保存在一个地方。这样的架构在受到黑客攻击,或者出现服务器设备物理故障时就会出问题了,数据可能会丢失,甚至被恶意篡改。我们在上面提到借助区块的数字指纹技术就能防止被篡改,但如果我们从第一个区块开始依次改动后面每个区块的数字指纹,还是能够改动整个区块链的数据的。

所以这就要用到分布式存储技术了,简单说就是一个区块链的全部数据会同时保存在多个服务器节点上,当一个服务器节点出问题时,其他节点还能正常提供服务。更重要的是,这些服务器节点能够相互验证区块链的有效性,防止某个节点的数据被篡改导致所有服务器节点的数据都被破坏掉。

举个例子说明一下,比如有三个人一起记账,记录下A转账给B 10块钱,当其他人查询这笔交易时,需要同时问这三个记账的人,当他们三个记账都一致时表示交易数据是正确的,可以信任。但如果问这三个记账的人,有一个人记录的跟其他人不一样,而其他两个人记录的是一样的,这种情况下怎么办?

这时就需要根据一定的共识机制来判断,例如可以按照少数服从多数的原则,相信那两个记账人的记录。

总结

以上就是区块链技术的原理介绍,可能有的方面还不够深入,但已经足够理解其基本原理了。

机器学习入门介绍

Posted on 2018-11-19 | In 技术 |

机器学习跟通常的编程开发比较有什么差别?

我们一般接触到的编程开发一般都是根据规则编写程序代码,然后录入数据后按照规则运算结果。而机器学习是根据数据和对应的结果去找规则,找出的规则就可以用来分析处理新的数据。这就是通常的软件开发跟机器学习的主要差别。

举个例子说明一下,比如经典的鸢尾花案例,这个案例在很多机器学习的教材里都能看到。这个案例收集了很多数据,主要是花瓣的几个特征值,以及对应花的种类。花瓣的特征值就是数据,而花的种类就是对应结果。那就可以用机器学习对这些数据做学习,希望能找出背后的规则,也就是当特征值满足什么条件时就说明它属于某个种类。

而通常的软件开发是先人工分析这些数据,寻找内在的规律,总结出规则,然后让开发人员根据规则编写程序代码。

机器学习存在的一个主要问题

这种根据数据找规则的方式有个潜在的问题,因为它是基于已有的数据,并非是全部数据,所以难免会碰到新的数据新的规则的情况,这就有准确率的问题,也就是说老的规则判断新数据时出错。这就需要持续不断地学习,把新的数据和对应结果作为新的输入,让机器学习继续寻找规则,到达一定准确率后就可以发挥较大的价值了。

其实通常的软件开发在一开始靠人工分析找出的规则也难免会有误差的,后面也需要根据新的情况不断完善规则提高准确率,这就要不断改进程序代码。

总结及深入

我们已经了解到机器学习是根据数据找规则,并且需要持续学习不断完善规则。机器学习有很多比较成熟的算法,大致分为有监督、无监督和强化学习几个类别。有监督的意思是有数据有结果,然后找内在的规则,就像上面鸢尾花的案例。无监督的意思是只有数据,需要找结果和规则,例如我们有很多会员,需要自动分类。强化学习是一个比较特定的领域,像自动驾驶就属于这个领域,需要根据数据输入很快反馈并不断改进规则。

一个基于 Groovy 闭包实现的低侵入缓存设计

Posted on 2018-10-26 | In 技术 |

缓存技术是目前很常用的一种技术,当你的系统的并发访问到达一定数量级后,后台的数据库就难以应付了,需要考虑缓存技术,但缓存又会涉及到如何跟数据库保持数据同步的问题。这篇文章介绍一个基于 Groovy 闭包技术实现的低侵入方案。

基本设计思路

读取数据时优先从缓存读取,缓存没有时从数据库读取,同时写到缓存中,隔一定时间后触发缓存刷新。

实现说明

定义一个统一的服务方法

这个服务方法能同时完成基本设计思路里的几个方面,这个服务方法名字为 getLazyCache,参数分别是:

cacheKey:缓存 key 名;
refreshClosure:获取对应数据的闭包方法;
closureParams:闭包方法需要的参数,是 Map 类型;
expireSeconds:缓存超时时间,单位是秒,缓存服务器会自动清除超时的缓存;

使用示例

1
2
3
4
5
6
7
8
9
10
//先定义一个闭包方法,方法里写读取数据库数据的代码,下面的例子是根据传参 appId 通过 Grails 的 GORM 方法查询数据,
//并转成 JSON 格式,以 String 类型返回(这是为了方便保存到 Redis 缓存里,采用 JSON 格式序列化数据)。
def refreshClosure = { paramsMap ->
def appId = paramsMap.appId
return String.valueOf(AppInfo.findAll('from AppInfo where id = ?', [appId]) as JSON)
}

def closureParams = ['appId': 'test_app_001']

def cacheValue = getLazyCache('CACHE_' + closureParams.appId, refreshClosure, closureParams, 300)

上面就是使用方法,很简单,而且能自己定义读取数据库数据的方式,getLazyCache 会先根据 cacheKey 去缓存中查是否存在,存在就直接返回,不存在就调用 refreshClosure 这个闭包方法重新读取,读取后写到缓存并返回。

getLazyCache 实现代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def getLazyCache(cacheKey, refreshClosure, closureParams, expireSeconds) {
//getCache 是一个已有的读取缓存的方法,这里直接调用
def cacheValue = getCache(cacheKey)

//如果查不到缓存就调用刷新缓存的闭包方法读取数据,并写到缓存
if (cacheValue == null) {
//调用闭包方法
cacheValue = refreshClosure.call(closureParams)
//putCache 是已有的方法,写缓存,并设置超时时间
putCache(cacheKey, cacheValue, expireSeconds)
}

return cacheValue
}

总结

以上就是整个实现方案,清晰易懂,而且对已有代码影响比较小,能够快速实现缓存功能,大大提高系统的并发容量。

Trying TiDB

Posted on 2018-10-16 | In 技术 |

TiDB体验记录

一直在寻找分布式数据库解决方案,有看过MyCat,MyCat是一个数据库中间层产品,通过数据库分区技术能提供一个理论上无限扩展的大数据库,背后核心还是MySQL,我感觉不是终极解决方案,但可以算作是过度方案。

TiDB进入我的视野,觉得思路比较有趣,对外以MySQL 协议提供关系数据库存储服务,而核心是NoSQL技术实现分布式存储和分布式计算。先不看其核心部分,单从对外提供兼容 MySQL服务这个角度看,这是很聪明的选择,可以吸引庞大的MySQL用户群来尝试使用。

我们已经基于MySQL开发了很多项目,目前面临的一个瓶颈是随着数据量越来越大,存储空间扩展方面和查询性能方面都面临比较大的问题。一台服务器的存储容量总归是有限的,如何能有效利用其他服务器的存储资源?还有计算资源等。

一般场景下MySQL是搭建了主从环境,这意味着写数据时必须要写到主服务器上,其他从服务器可以同步到最新的数据。这样就可以通过查询从服务器实现读写分离,大大减轻主服务器的压力。

但随着数据量不断增长,主服务器和从服务器的存储都会出现难以满足的情况,这时可能会考虑数据分区的方案把数据库分拆成多个,分别存储到不同服务器上,但这需要迁移大量数据,可能在考虑不周的情况下会多次迁移数据,这在数据量到一定规模时迁移数据耗时会很长。而且应用程序往往也要适应这种数据库分拆做改动,成本可能很高。

有没有一种解决方案能弹性扩张数据库的存储资源和计算资源,也不需要复杂的数据分区以及改动相关应用程序?

这就是TiDB 的解决方案,底层的数据存储和计算资源可以动态扩展,前端的数据访问服务是以兼容MySQL的协议开放出来,堪称完美。

据TiDB官方介绍,他们在兼容MySQL方面花了相当的精力,据说是直接用MySQL的单元测试代码来测试他们的代码,保证完美兼容。

我试着搭了一个有3个节点的TiDB环境,把我们一个系统的接口调用日志数据转移过去,并且进行实时写入。同时也开发了统计分析方面的查询,测试跟MySQL的兼容性和性能,总体评估感觉是挺理想的,后面还需要持续测试一段时间观察一下。

根据TiDB官方网站上讲的,是希望满足100% OLTP数据库以及80%的OLAP数据库应用场景,这个目标是很有野心的,期待他们能达成,这样我们就可以有一个相当完美的数据库解决方案了。

Grails, a sharp toolkit for Internet software development

Posted on 2018-10-15 | In 技术 |

Grails,移动互联网时代服务器端开发的利器

Grails 对国内的很多开发人员来说可能比较陌生,它是一个基于Groovy编程语言的开发框架,Groovy是基于JVM的一种动态编程语言,在Java语法基础上增加了很多有用的动态特性。

目前移动互联网时代前端开发项目越来越多,包含有Android/iOS原生开发,还有HTML5开发。前端开发要跟后台服务器端交互,一般是通过调用服务器端HTTP API接口的方式,所以服务器端的API接口开发越来越重要。

为什么要选择 Grails 做服务器端API接口开发?

首先,Grails 是基于Java虚拟机这个基础平台的,在 Grails 里可以很方便地调用Java代码,也就是说Java领域这么多年来所积累的各种各样的技术,在 Grails 框架上都可以发挥作用。这是一个很关键的因素,例如各种数据库驱动、各种网络协议开发包和最近比较流行的大数据方面的各种开发技术等,这些项目和产品首先会考虑支持Java。

后端接口API要重点考虑后端系统整合问题,这样才可以为前端提供功能强大的接口,因此Java领域的各种技术沉淀是很宝贵的。例如很早以前的金融类的很多大型系统是用EJB技术开发的,如果在API接口里要实现跟EJB对接,这个就不是其他开发语言能做到的了。

像目前的Node.js是基于JavaScript的服务器端开发技术平台,因为比较年轻,技术沉淀还不够多,所以在对接一些已有系统方面,相对薄弱一些。还有像Python和Ruby等,也是面临类似的问题。

其次,Grails 大大简化了服务器端的开发工作。Grails 是基于 Spring MVC 和 Hibernate 技术的,最近的版本已经支持多种 NoSQL 数据库,然后进行了很大幅度的封装,简化了很多繁琐的处理,提供了简单而且一致的数据库层及Web层的开发标准。

我们拿Java开发常用的一些开发技术为例探讨一下,比如数据库层,目前有很多选择,像JPA/Hibernate、JDO、iBatis/MyBatis 和 JDBC 等,你会选择哪一种?每个Java开发人员应该都有自己的偏好,由此引起的争论也总是比较激烈。

这还仅仅是数据库层,在服务层和Web层又会有多种选择,所以从整套开发框架角度(Full Stack)看,这种技术组合就太多了。所以当一个Java开发人员到了一个新环境,往往会发现,这个新环境所用的Java的技术组合跟他以前用得是不一样的,所以只能花时间去学些这个新组合,要达到很熟练的程度需要花不少时间的,相信每个Java开发人员都会有这方面的体会。

Grails 是基于主流的Java技术,例如 Spring MVC 和 Hibernate,然后进行封装,提供了一致的技术标准,对于后来的新技术支持也是类似。比如对于数据库层,基于Hibernate的数据库访问接口跟后来的基于NoSQL的数据库访问接口基本是一致的,开发人员不需要再去学习新的一套接口标准,所以可以把主要精力集中到具体业务应用的开发上面。

最后,Grails 所基于的 Groovy 动态开发语言所带来的效率提升是巨大的。这方面举个例子会比较容易理解,每个开发团队做项目做久了都会积累一套自己的工具类库,这些工具类库把一些重复性的处理提供了简化的解决方案,比如以前一大堆代码要实现的功能现在调用一个工具类的函数就搞定了。

如果这种工具类的函数积累的越来越多,对于原有团队的开发人员来说,开发效率应该是越来越高,这就是技术积累所发挥的作用。而基于这些函数开发出来的项目对于那些只熟悉标准Java技术的开发人员来讲,就难以理解了,感觉就像是一套新的开发技术一样。

Groovy 跟这个道理类似,它把平时Java开发中一些常见的繁琐处理做了很多简化,以前要很多行代码实现的功能现在可能用1行代码就能做到了。但它更进了一步,是抽象到一套开发语言的层次了,不是简单的函数调用了,你用它的语法编程,它在后台为你自动完成相应工具类函数的调用。

但 Groovy 在兼容 Java 标准语法方面考虑得很周到,绝大部分普通Java类可以直接作为 Groovy 代码来用,也就是说你以前写的一个类叫 Test.java,一般直接改文件名为 Test.groovy 就可以作为 Groovy 代码执行了。这个跟其他的基于Java的动态语言是不同的,例如Scala,是跟 Java 完全不同的一套编程语法,Scala这种学习曲线是很比较陡的,而 Groovy 相对就比较平缓,普通 Java 开发人员可以继续用 Java 的语法做开发,然后渐渐学习 Groovy 的特性,就可以越来越多地用 Groovy 语法了。

实际示例:

下面举个API开发的示例来体会一下 Grails 的效率。

我们做一个简单的电话号码簿的查询接口。

先定义一下数据模型:

class Phone {
   String name
   String phoneNumer
   String memo
}

上面是定义了一个 Grails domain 类,Grails 会自动同步创建数据库的表。

然后做一个 Controller 类,写一个根据姓名查询对应电话号码的接口。

class PhoneApiController {
   def queryPhone() {
      //拿到URL传递过来的查询参数
      def queryParameter1 = params.name
      //调用domain类的查询接口,这些接口是 Grails 自动提供的,不需要我们写什么代码
      def phone = Phone.findByName(queryParameter1)

      //如果查询到结果
      if (phone) {
         //把查询结果以JSON格式返回给调用端
         render phone as JSON
      } else {
         //返回错误信息给调用端,一般需要封装一个 errorCode 返回值用于调用端识别是否没有查询到结果,这里只是简单返回错误信息
         render "查不到电话号码"
      }
   }
}

上面的这个接口可以通过这个 URL 来调用:

http://服务器IP:端口/项目名/phoneApi/queryPhones?name=张三

是不是很简单,很容易理解?

Grails 对于提高服务器端的开发效率很有帮助,建议Java开发人员了解学习一下,并且可以考虑应用到具体项目中。当你熟练掌握 Grails 的时候,你会觉得写代码也可以是很美妙的事情,因为你可以专注于要解决的实际业务需求,而不是翻来覆去地折腾开发框架方面的问题。特别是对于移动互联网时代的开发,这种快速开发服务器端接口的能力是很重要的,而同时也不需要放弃以前Java领域那么多的技术积累。

注:附件是本文中示例的源代码,可以直接运行,示例用的是 Grails 2.3.11 版本。

Best and Simple Machine Learning Explaination

Posted on 2018-10-11 | In 技术 |

I found a simple explaination for machine learning, and it is the best explaination I have ever seen.

Here it is:

best and simple machine learning explaination

1…456

Ken Deng

53 posts
5 categories
29 tags
© 2020 Ken Deng
Powered by Hexo
|
Theme — NexT.Muse v5.1.4