来自“风味人间”的类比
所谓美食,不过是一次又一次的相逢。我们带您穿越山海之间,偶尔的落地生根,成就万千肴变,随即化作滚滚红尘,穿越香料歧路,几度江湖夜雨后,点亮万家灯火。
《风味人间》
浮华随风去,一菜一江湖。无论置身繁华闹市,还是身居乡野陋巷,世上的滋味,就这样流转于方寸餐桌,交织在冷暖人间。我们说五味杂陈,这五味就是酸、苦、甘、辛、咸。
而我们日常食物中的食材种类可谓是丰富多彩了。简单列一下日常主要食物食性分类表:
一、寒凉类食物
1、粮油类:小米、大麦、荞麦、绿豆、薏苡仁、麻油、猪油、豆腐、黄豆芽、绿豆芽、淡豆鼓、麦芽
2、蔬菜类:芹菜、菠菜、蕹菜、苋菜、大白菜、莼菜、紫菜、甜菜、油菜、黄花菜、薇菜、生菜、丝瓜、黄瓜、冬瓜、苦瓜、竹笋、芦笋、莴苣笋、茄子、番茄、茭白、百合、荸荠、莲藕、慈姑、马兰头、马齿苋、枸杞头、白萝卜、青萝卜、菜瓜、葫芦、蘑菇、草菇、海带、葛根、鱼腥草、苤蓝
3、鱼肉类:羊肝、鸭肉、鸭血、兔肉、鸭蛋、黑鱼、田螺、螺蛳、蟹、蚌、蛤蛎、牡蛎、蛏、河蚬、青蛙、牛乳、发菜
4、水果类:梨、柑、柚子、罗汉果、柿子、杨桃、芒果、猕猴桃、香蕉、橙子、草莓、西瓜、甜瓜、胖大海、余甘子、栀子
5、其 他:食盐、白糖、蜂蜜、酱油、酱、茶、啤酒、薄荷、菊花、淡竹叶、金银花、决明子、菊苣、菰米、鲜白茅根、鲜芦根、桑叶
二、平性类食物
1、粮油类:小麦、燕麦、玉米、粳米、黄豆、黑大豆、玉米油、赤小豆、白扁豆、黑芝麻、花生、花生油、豆腐浆、豆腐皮、腐乳、大豆黄卷
2、蔬菜类:荠菜、花菜、卷心菜、蓬蒿菜、青菜、塌棵菜、西洋菜、清明菜、北瓜、马铃薯、芋艿、山药、胡萝卜、苜蓿、芡实、香菇、猴头姑、木耳、银耳、蒲公英、豌豆、蚕豆、四季豆、扁豆、荷兰豆、西兰花、甘薯、豇豆、金针菇
3、鱼肉类:猪肉、猪心、猪肝、猪脑、猪骨、火腿、牛肚、鸡肫、鹅肉、鹌鹑肉、鸽肉、鸡蛋、鹅蛋、鹌鹑蛋、鸽蛋、青鱼、鲤鱼、鲫鱼、鲈鱼、刀鱼、鲥鱼、鲟鱼、鳗鲡、白鱼、银鱼、黄鱼、鲳鱼、鳜鱼、鳐鱼、墨鱼、鲨鱼、橡皮鱼、鳖、海蜇、人乳、乌梢蛇
4、水果类:枇杷、桑椹、莲子、枣、榛子、苹果、无花果、梅子、乌梅、菠萝、甘蔗、橘仁、香榧、菱角、葵花子、西瓜子、枸杞子、枣仁、桃仁、白果、郁季仁、火麻仁、刺梨
5、其 他:味精、甘草、茯苓、菜菔子、代代花、荷叶、鸡内金
三、温热类食物
1、粮油类:高粱、籼米、糯米、牛油、菜油、豆油
2、蔬菜类:芥菜、韭菜、大头菜、南瓜、刀豆、香椿头、芫荽、辣椒、大蒜、葱、洋葱、生姜、平菇、金瓜、木瓜、魔芋
3、鱼肉类:猪肚、牛肉、牛骨髓、羊肉、羊肚、羊脑、狗肉、鸡肉、麻雀肉、雉肉、草鱼、鲢鱼、鳙鱼、鳊鱼、鳟鱼、塘鳢鱼、带鱼、黄鳝、泥鳅、蚶、河虾、海参、鲍鱼、羊乳、淡菜
4、水果类:桃子、李子、葡萄、龙眼、椰子、橄榄、杏子、杏仁、橘子、金橘、荔枝、柠檬、樱桃、杨梅、石榴、槟榔、香橼、佛手、山楂、栗子、松子、南瓜子、核桃、益智
5、其 他:红糖、桂花、桂皮、花椒、胡椒、茴香、八角茴香、丁香、砂仁、薤白、玫瑰花、玉兰花、醋、咖啡、米酒、白酒、黄酒、葡萄酒、红花、肉豆蔻、紫苏、陈皮、五香粉、高良姜、肉桂、白芷、藿香、沙棘、黄芥子
这食材,就像是程序设计中的数据结构 Number、String、Array、List、Link、Map、Tree 、Graph 等,组合成不同的抽象数据类型(ADT),你也可以理解成数据结构、模型、类、对象等范畴。
然后,这些食材怎样早就这“风味人间” (互联网软件系统、虚拟数字世界)呢?这就必须要来好好讲讲“烹饪技法”了。做菜所要的时间和调料是非常讲究的,做到位了,所做的菜的营养、色味俱全,让人吃了回味无穷,即养身体又养眼。
炒爆熘炸烹…… 让我们来看看百度百科上列出的26种烹饪技法:
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 焗
厨艺世界的艺术,类比到计算机程序设计领域里面就是:
风味 = 食材 + 烹饪方法
程序 = 数据结构 + 算法
Tips:类比是思想之基。参考:《表象与本质》(Surfaces and Essences) , 作者: [美]侯世达 / [法]桑德尔。
当一个人深深地沉浸在某个活动,或被某个极不寻常的事迷住时,这强烈的兴趣可能会使大量的类比不请自来,涌入脑中。而且,是那些绝不会在其他地方产生的类比。这一现象,就像是类比的阿喀琉斯之踵,它可能会导致我们对情境产生荒诞的理解,并最终作出十分糟糕的决定。不过,在着迷的时候容易作出不同寻常的类比,这同样也是伟大灵感的源泉。准确来讲,正着迷时,发现的相似之处大部分没什么深刻的见解,但时不时的,这种由类比引来的联系,就会成为人类思维奇迹的神来之笔。实际上,当一个人对某物着迷的时候,到处都会看到有关他所迷恋事物的类比,这发生在生活的每一个角落,日夜不停。而且,每一件很微小的事都有可能对应上所迷恋事物的一部分。所以说,尽管并不常见,但有时这种不可抗拒的冲动真的会创造出非比寻常的事。
—— 引自章节:5 类比如何操纵我们
做美食,品的是风味,尝的是人间。
做程序,思的是理想,考的是现实。
程序设计是一门艺术
我们不得不接受这样一个事实:
一个未知的、无序的世界,是不可能实现“程序”的。
于是,我们抽象它,建立模型——把问题转化为结构,或者对象,或者列表,或者映射表,或者树,或者网,或者某个可以用具体规则步骤描述的事物——这就是“算法”,然后,用编程语言来表达之,或为手机APP,或为PC 网页,或为图画,或为声音,或为视频,或为3D、4D虚拟现实世界。
同样的食材,不同厨师做出来的味道,自然是千差万别。那么,同样的数据结构,不同程序员设计出来的算法和写出来的代码,实现出来的系统,自然也是不同的。
风味,不是一蹴而就,需要时间与火候;画作,不是寥寥几笔,需要不断揣摩线条、色彩、构图、光线。在追求探索美味与美色的道路上,食艺家与画艺家需要达到禅的境界,在仿佛时间静止的流动中,付出全情之投入与专注。
同样的,一个美妙的系统,代码,架构——我们这些程序艺家门,也需要臻于至善之境——禅。
编程是一门艺术——我们不得不承认。这里面倾注了人类高度的创造性与智慧。
代码欣赏: KMP 算法源代码
/**
* getNext (pattern) 函数: 计算字符串 pattern 的最大公共前后缀的长度 (max common prefix suffix length)
*/
fun getNext(pattern: String): IntArray {
val n = pattern.length
val next = IntArray(n, { -1 })
var j = 0
next[0] = j
(1 until n).forEach {
val i = it
while (j > 0 && pattern[i] != pattern[j]) {
j = next[j - 1]
}
if (pattern[i] == pattern[j]) {
j++
}
next[i] = j
}
return next
}
/**
* kmp substring search algorithm
* @param text : the source text
* @param pattern : the search pattern
*/
fun kmp(text: String, pattern: String): Int {
val m = pattern.length
val n = text.length
if (pattern.isEmpty()) {
return 0
}
// j: the current index of pattern
var j = 0
val next = getNext(pattern)
(0..n - 1).forEach {
// i: the current index of text
val i = it
while (j > 0 && text[i] != pattern[j]) {
j = next[j - 1]
}
if (text[i] == pattern[j]) {
j++
}
if (j == m) {
return i - m + 1
}
}
return -1
}
fun main() {
var text = "addaabbcaabffffggghhddabcdaaabbbaab"
var pattern = "aabbcaab"
print("${getNext(pattern).joinToString { it.toString() }} \n")
var index = kmp(text, pattern)
println("$pattern is the substring of $text, the index is: $index")
text = "hello"
pattern = "ll"
print("${getNext(pattern).joinToString { it.toString() }} \n")
index = kmp(text, pattern)
println("$pattern is the substring of $text, the index is: $index")
text = "abbbbbbcccddddaabaacabdcddaabbbbaad"
pattern = "aabaacab"
print("${getNext(pattern).joinToString { it.toString() }} \n")
index = kmp(text, pattern)
println("$pattern is the substring of $text, the index is: $index")
}
// 输出:
//0, 1, 0, 0, 0, 1, 2, 3
//aabbcaab is the substring of addaabbcaabffffggghhddabcdaaabbbaab, the index is: 3
//0, 1
//ll is the substring of hello, the index is: 2
//0, 1, 0, 1, 2, 0, 1, 0
//aabaacab is the substring of abbbbbbcccddddaabaacabdcddaabbbbaad, the index is: 14
《禅与计算机程序设计艺术》 / 陈光剑 目录
第一性原理
什么是禅?
什么是计算机?
什么是程序设计?
什么是艺术?
风味人间与计算机程序设计艺术
宇宙之起源
物质之形成
半导体材料
纳米光刻
二极管、三极管
太极阴阳与二进制
布尔代数与数字逻辑系统
模拟电子电路系统
信号与处理
信息论
图灵机模型
冯诺依曼模型
计算机演化史
什么是编程?
编程语言进化史
程序 = 数据结构 + 算法
模型关系思维
真理与模型
建筑工程、机械工程、电气工程与软件工程
CPU架构设计
缓存思想
计算机科学中的中间层理论
从01机器码到汇编指令到高级编程语言:一切皆是映射
美妙的递归
用计算机画一张分形图
分层思想
硬件驱动
操作系统
通信原理:TCP/IP 与 HTTP 协议、WIFI无线协议
互联网简史
数据的存储:从ROM、RAM到寄存器到L1/L2 Cache 再到磁盘文件
索引原理:来自大自然的启示 Tree 结构
人类社会数字化
人工智能
虚拟现实
技术、艺术与禅道
// TODO ...... 待续