张奔营小学二年级中考试卷朱佳祺2015中考成绩

合作账号登录
后使用快捷导航没有帐号?
查看: 34|回复: 0
[求助]张奔营小学二年级朱佳祺2015中考成绩
TA的每日心情减肥 11:00签到天数: 1 天[LV.1]初来乍到主题帖子积分
张奔营小学二年级朱佳祺2015中考成绩822204保定地区,张奔营村,的具体位置_百度知道
保定地区,张奔营村,的具体位置
我有更好的答案
河北省保定市高碑店市新城镇张贲营村
其他类似问题
为您推荐:
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁您所在位置: &
&nbsp&&nbsp&nbsp&&nbsp
关于公示2014年国中学生生物学联赛.doc1页
本文档一共被下载:
次 ,您可免费全文在线阅读后下载本文档
文档加载中...广告还剩秒
需要金币:200 &&
你可能关注的文档:
··········
··········
关于公示2014年全国中学生生物学联赛
(江苏赛区)一二等奖获奖名单的通知
2014年全国中学生生物学联赛江苏竞赛 城市 准考证号 姓名 学校名称
孙文博 江苏省扬州中学
张怡然 江苏省锡山高级中学
范天毓 江苏省锡山高级中学
谢宇 江苏省兴化中学
顾思鉴 江苏省兴化中学
吴弘毅 江苏省泰兴中学
陈铭哲 江苏省泰兴中学
卢聪健 苏州市第一中学
金诚开 江苏省木渎高级中学
郑钰琪 江苏省梁丰高级中学
沈达 江苏省昆山中学
王李栋 江苏省常熟中学
单华 江苏省通州高级中学
杨富强 南师附中江宁分校
彭正康 南师附中江宁分校
郑子谅 南京师范大学附属中学
夏心悦 南京师范大学附属中学
韩顶 南京师范大学附属中学
吴东宇 金陵中学
王占宇 江苏省新海高级中学
周典 东海高级中学
袁依雯 省常中
王芮 省常中
蔡子] 省常中
2014年全国中学生生物学联赛(江苏赛区)一等奖名单
序号 城市 准考证号 姓名 学校名称
赵君杰 镇江市实验高中
朱靖泰 江苏省镇江中学
熊铭港 江苏省镇江中学
夏璐 江苏省镇江中学
吴昊宸 江苏省镇江中学
宋心宇 江苏省镇江中学
7 镇江市 2014045
正在加载中,请稍后...您所在位置: &
&nbsp&&nbsp&nbsp&&nbsp
温教办体〔二零一六〕51号.doc87页
本文档一共被下载:
次 ,您可全文免费在线阅读后下载本文档。
文档加载中...广告还剩秒
需要金币:98 &&
温教办体〔二零一六〕51号.doc
你可能关注的文档:
··········
··········
温教办体〔2014〕51号
温州市教育局办公室关于公布
温州市第二十六届中小学艺术节比赛结果的通知
各县(市、区)教育局,经济技术开发区文教体局,市局直属各学校:
温州市第二十六届中小学艺术节已圆满结束。本次艺术节共收到参赛作品2074个,其中包括书法、篆刻、绘画、摄影、剪纸、设计、立体造型、动漫、声乐、舞蹈、器乐、儿童歌舞剧等
12个类别。通过专家评审,评出全市一等奖342个、二等奖652个、三等奖1080个、优秀组织奖12个、优秀承办奖10个、优秀指导师426名;市直选拔赛一等奖36个、二等奖59个、三等奖66个。现将名单予以公布。
希望获奖单位和师生戒骄戒躁,再接再厉,不断取得新的成绩。同时,希望各地各校认真总结经验,面向全体学生,大力开展中小学文化艺术活动,积极培养优秀艺术后备人才,为推动学校艺术教育再上新台阶而不懈努力。
附件:温州市第二十六届中小学艺术节获奖名单
温州市教育局办公室
抄送:省教育厅,市委,市人大,市政府,市政协。
温州市教育局办公室 日印发
温州市第二十六届中小学艺术节获奖名单
优秀组织奖
鹿城区教育局
龙湾区教育局 瑞安市教育局
平阳县教育局
苍南县教育局 永嘉县教育局
温州中学 温州市第二中学
温州市第三中学
温州市实验中学
温州市实验小学
温州市籀园小学
优秀承办奖
温州市青少年活动中心 温州市少年宫
温州市第七中学 温州市第十四高级中学
温州市第十二中学 温州市第二十一中学
温州市第二十二中学 温州市职业中等专业学校
温州市绣山中学 温州市电教馆
获奖作品(节目)
一、书法比赛(336个)
(一)软笔(186个)
小学组(75个)
正在加载中,请稍后...朱佳祺,折腾,程序员(不是折腾程序员)
创业毁一生
别问我性价比
我来回答:头疼好的耳机大多做工精良,自重较大,佩戴舒适但热或者是顶得,夹的耳朵…
单从微信文章来看没太多细节公布,如果有人能详细说说这个系统本身的调度策略/算法…
顺便说一句楼主的代码是python3的。python2中的filter返回一个listpython2版本impor…
103 人关注
这么多人点赞,更新一下:&br&&br&9. &a href=&///?target=http%3A//dreamsome.org/1077& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Dreamsome: 如何解决系统问题&i class=&icon-external&&&/i&&/a&&br&&img src=&/cf31bc8a61f17c30a760_b.png& data-rawwidth=&929& data-rawheight=&627& class=&origin_image zh-lightbox-thumb& width=&929& data-original=&/cf31bc8a61f17c30a760_r.png&&&br&10. &a href=&///?target=http%3A//dreamsome.org/1077& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Dreamsome: 如何解决系统问题&i class=&icon-external&&&/i&&/a&&img src=&/d482ad308aefd78c2c856fba_b.png& data-rawwidth=&306& data-rawheight=&444& class=&content_image& width=&306&&&br&&br&11. &a href=&///?target=http%3A//dreamsome.org/1102& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Dreamsome: 倒茶&i class=&icon-external&&&/i&&/a&&br&&img src=&/5bc2fa9eacce60912acba5e_b.png& data-rawwidth=&314& data-rawheight=&364& class=&content_image& width=&314&&&br&&br&500 个赞以后我会再回来更新的~&br&&br&友情提示:鼠标悬停在图片以后可以看到彩蛋&br&&div class=&highlight&&&pre&&code class=&language-text&&&div id=&transcript&&&p&男1:你为什么要定义两种不同的SUCCESS?
男2:GREAT_SUCCESS只有在行数超过500的函数末尾返回。
男2:居然连一个错误都没有发生。那可是整整500行代码啊!
[[ Title-text: SUCCESS(200行),MINOR_SUCCESS(50行),NOT_EVEN_A_SUCCESS(20行) ]]&/p&
&/code&&/pre&&/div&&br&原贴:&br&&br&1. &a href=&///?target=http%3A//dreamsome.org/1057& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Dreamsome: MD5&i class=&icon-external&&&/i&&/a&&img src=&/6dc7a6a7dd03e12ddc499_b.jpg& data-rawwidth=&859& data-rawheight=&305& class=&origin_image zh-lightbox-thumb& width=&859& data-original=&/6dc7a6a7dd03e12ddc499_r.jpg&&&br&&br&2. &a href=&///?target=http%3A//dreamsome.org/1082& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Dreamsome: 抄作业&i class=&icon-external&&&/i&&/a&&br&&img src=&/36ad3a80fafb7f437dfb58bf823c4314_b.jpg& data-rawwidth=&373& data-rawheight=&430& class=&content_image& width=&373&&&br&&br&3. &a href=&///?target=http%3A//dreamsome.org/1033& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Dreamsome: 理性&i class=&icon-external&&&/i&&/a&&br&&img src=&/62db9cadb07b1eb27bdf19_b.jpg& data-rawwidth=&740& data-rawheight=&213& class=&origin_image zh-lightbox-thumb& width=&740& data-original=&/62db9cadb07b1eb27bdf19_r.jpg&&&br&&br&4. &a href=&///?target=http%3A//dreamsome.org/1044& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Dreamsome: BOOTSTRAP&i class=&icon-external&&&/i&&/a&&img src=&/408ef70e51e5bb4bc69fa_b.jpg& data-rawwidth=&465& data-rawheight=&352& class=&origin_image zh-lightbox-thumb& width=&465& data-original=&/408ef70e51e5bb4bc69fa_r.jpg&&&br&&br&5. &a href=&///?target=http%3A//dreamsome.org/1038& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Dreamsome: 通信协议&i class=&icon-external&&&/i&&/a&&img src=&/bc0efc821fc56e2ecff257b0a5612daf_b.jpg& data-rawwidth=&1024& data-rawheight=&601& class=&origin_image zh-lightbox-thumb& width=&1024& data-original=&/bc0efc821fc56e2ecff257b0a5612daf_r.jpg&&&br&6. &a href=&///?target=http%3A//dreamsome.org/1017& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Dreamsome: Homo&i class=&icon-external&&&/i&&/a&&img src=&/54478dcb6e45edc42b8a33e925c29a25_b.jpg& data-rawwidth=&458& data-rawheight=&276& class=&origin_image zh-lightbox-thumb& width=&458& data-original=&/54478dcb6e45edc42b8a33e925c29a25_r.jpg&&&br&&br&7. &a href=&///?target=http%3A//dreamsome.org/1079& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Dreamsome: 巨大的成功&i class=&icon-external&&&/i&&/a&&img src=&/00a206deb405a_b.jpg& data-rawwidth=&731& data-rawheight=&276& class=&origin_image zh-lightbox-thumb& width=&731& data-original=&/00a206deb405a_r.jpg&&&br&&br&8. &a href=&///?target=http%3A//dreamsome.org/1080& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Dreamsome: 时间的起点&i class=&icon-external&&&/i&&/a&&br&&img src=&/20b131ccfeb76f01fd4aa75_b.jpg& data-rawwidth=&592& data-rawheight=&403& class=&origin_image zh-lightbox-thumb& width=&592& data-original=&/20b131ccfeb76f01fd4aa75_r.jpg&&
这么多人点赞,更新一下:9. 10. 11. 500 个赞以后我会再回来更新的~友情提示:鼠标悬停在图片以后可以看到彩蛋&div id="transcript"&&p&男1:你为什么要定义两种不同的SUCCES…
&img src=&/224b10fd_b.png& data-rawwidth=&1920& data-rawheight=&964& class=&origin_image zh-lightbox-thumb& width=&1920& data-original=&/224b10fd_r.png&&&p&在 &a href=&/?target=http%3A//mp./s%3F__biz%3DMzA3NDM0ODQwMw%3D%3D%26mid%3Didx%3D1%26sn%3D575ae8fdf163afa079fd%26scene%3D21%23wechat_redirect& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&再谈 API 的撰写 - 总览&i class=&icon-external&&&/i&&/a& 里我们谈到了做一个 API 系统的基本思路和一些组件的选型,今天谈谈架构。&/p&&h2&部署&/h2&&p&首先要考虑的架构是部署的架构。部署的方案往往会深刻影响着系统的结构。我们需要问自己一个问题:从宏观上看,这个系统我们希望如何进行部署?&/p&&p&很多 API 系统是这样部署的(方案一):&/p&&p&&img src=&/9debf678b2ede3a87250b_b.png& data-rawwidth=&2204& data-rawheight=&710& class=&origin_image zh-lightbox-thumb& width=&2204& data-original=&/9debf678b2ede3a87250b_r.png&&(load balancer 和 nginx proxy (web server) 可能是同一个 cluster。这里逻辑上把他们划分开来。)&/p&&p&这是很典型的做法,所有的 API 在一套系统里部署,简单,高效,比较容易上手。然而,随着时间的推移,功能的复杂,这样的系统会越来越不堪重负。比如说我们做一个内容发布平台的 API 系统(类似于知乎日报),起初我们可能只需要内容相关的 API,渐渐地你要加入统计(tracking)相关的 API,然后我们又需要用户行为相关的 API,它们各自访问不同的数据源,行为方式也大不相同(内容相关的 API 可以做 cache,而统计和用户行为相关的 API 不能 cache)等等,当这些逻辑结构各异的 API 被揉进一个系统里时,这个系统会越来越难以维护。&/p&&p&所以,这样的部署方案会演进成下面的部署方案(方案二):&/p&&img src=&/b7b6fb62eb592bbbe13b_b.png& data-rawwidth=&2238& data-rawheight=&1008& class=&origin_image zh-lightbox-thumb& width=&2238& data-original=&/b7b6fb62eb592bbbe13b_r.png&&&p&我们把 API 按照功能做了拆分,load balancer / nginx proxy 之后是一个个 API application。它们有自己的 load balancer / nginx proxy,可以按照每个 API application 本身的规模进行 scale up / down。比如说内容相关的 API,访问量(折合成运算量)是用户相关的 API 的 5 倍,那么,部署的时候我们可以把资源按照 5:1 的比例部署;再比如在高峰期整个系统负载过大,可以把统计 API 关掉,在 proxy 侧直接返回 503,把节省的资源配置到其他地方。&/p&&p&这里谈到的部署方案刻意忽略了一些细节,比如说日志如何收集和管理,服务本身的监控和信息的收集(APM)等没有提及。它们是部署方案中的关键环节,但毕竟本文不是专门讲部署的,故而忽略。&/p&&p&显而易见地,方案一和方案二的软件架构也会有所不同。方案二中,两个 API application 间的访问会通过 RPC(也可以使用 HTTP,但效率略低)完成,而方案一种,可能直接就是一个 function call 或者直接访问对方的数据库。方案二是一种分治的思想,把大的问题变成一条公共路径上若干相似的小问题的解决。&/p&&h2&Pipeline&/h2&&p&接下来的文章中,我们以方案二为蓝本,描述一个 API application 的架构。之前我们提到了这些目标:&/p&&ul&&li&&p&A well defined pipeline to process requests&/p&&/li&&li&&p&REST API done right (methods, status code and headers)&/p&&/li&&li&&p&Validation made easy&/p&&/li&&li&&p&Security beared in mind&/p&&/li&&li&&p&Policy based request throttling&/p&&/li&&li&&p&Easy to add new APIs&/p&&/li&&li&&p&Easy to document and test&/p&&/li&&li&&p&Introspection&/p&&/li&&/ul&&p&除了后面三个,其他都和 API 处理的 pipeline 有关。我们知道,一个 API 的执行,从 request 到 response,整个 pipeline 能够划分成几个阶段:request -& pre-processing -& processing -& post-processing -& response。其中,&processing& 指的是 API 路由真正执行的代码。好的架构应该尽可能把 API 执行路径上的各种处理都抽象出来,放到公共路径(或者叫中间件,middleware)之中,为 API 的撰写者扫清各种障碍,同时能够促使 API 更加标准化。&/p&&p&下图是我构思的一个 pipeline,它并不是最好的,但最能反映我的思想:&/p&&img src=&/d3a3b76be011ba0a0bdd5d3f50c51be7_b.png& data-rawwidth=&2242& data-rawheight=&1126& class=&origin_image zh-lightbox-thumb& width=&2242& data-original=&/d3a3b76be011ba0a0bdd5d3f50c51be7_r.png&&&p&我们详细说说这个 pipeline 下的每个组件:&/p&&ul&&li&&p&throttling:API 应该有最基本的访问速度的控制,比如,对同一个用户,发布 tweet 的速度不可能超过一个阈值,比如每秒钟 1 条(实际的平均速度应该远低于这个)。超过这个速度,就是滥用(abuse),需要制止并返回 429 Too many requests。throttling 可以使用 leaky bucket 实现(restify 直接提供)。&/p&&/li&&li&&p&parser / validation:接下来我们要解析 HTTP request 包含的 headers,body 和 URL 里的 querystring,并对解析出来的结果进行 validation。这个过程可以屏蔽很多服务的滥用,并提前终止服务的执行。比如你的 API 要求调用者必须提供 X-Client-Id,没有提供的,或者提供的格式不符合要求的,统统拒绝。这个步骤非常重要,如同我们的皮肤,将肮脏的世界和我们的器官隔离开来。&/p&&/li&&li&&p&ACL:除了基本的 throttling 和 validation 外,控制资源能否被访问的另一个途径是 ACL。管理员应该能够配置一些规则,这些规则能够进一步将不合法 / 不合规的访问过滤掉。比如说:路径为 &/topic/& 的知乎话题,北京时间晚上10点到次日早上7点的时间端,允许在中国大陆显示。这样的规则可以是一个复杂的表达式,其触发条件(url)可以被放置在一个 bloom filter 里,满足 filter 的 url 再进一步在 hash map 里找到其对应的规则表达式,求解并返回是否允许显示。至于一个诸如country = &CN& && time &= 00:00CST && time & 07:00CST(这是一个管理员输入的表达式)这样的表达式如何处理,请移步 &a href=&/?target=http%3A//mp./s%3F__biz%3DMzA3NDM0ODQwMw%3D%3D%26mid%3Didx%3D1%26sn%3D9cc0fadcdbab12%26scene%3D21%23wechat_redirect& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&如何愉快地写个小parser&i class=&icon-external&&&/i&&/a&。&/p&&/li&&li&&p&normalization:顾名思义,这个组件的作用是把请求的内容预处理,使其统一。normalization 可以被进一步分为多个串行执行的 strategy,比如:&/p&&/li&&ul&&li&&p&paginator:把 request 里和 page / sort 相关的信息组合起来,生成一个 paginator。&/p&&/li&&li&&p&client adapter:把 API client 身份相关的信息(device id,platform,user id,src ip,...)组合成一个 adapter。&/p&&/li&&li&&p&input adapter:输入数据的适配。这是为处女座准备的。很多时候,输入数据的格式和语言处理数据的格式不一样,这对处女座程序员是不可接受的。比如说 API 的输入一般是 snake case(show_me_the_money),而在某些语言里面(如: javascript),约定俗成的命名规则是 showMeTheMoney,所以把输入的名称转换有利于对代码有洁癖的程序员。&/p&&/li&&/ul&&li&&p&authentication:用户身份验证。这个不多说,主要是处理 &Authorization& 头。对于不需要验证的 API,可以跳过这一步。做 API,身份验证一定不要使用 cookie/session based authentication,而应该使用 token。现有的 token base authentication 有 oauth, jwt 等。如果使用 jwt,要注意 jwt 是 stateless 的 token,一般不需要服务器再使用数据库对 token 里的内容校验,所以使用 jwt 一定要用 https 保护 token,并且要设置合适的超时时间让 token 自动过期。&/p&&/li&&li&&p&authorization:用户有了身份之后,我们进一步需要知道用户有什么样的权限访问什么样的资源。比如:uid 是 9527 的用户对 &POST /topic/&(创建一个新的话题),&PUT /topic/:id&(修改已有的话题)有访问权限,当他发起 &DELETE /topic/1234& 时,在 authorization 这一层直接被拒绝。authorization 是另一种 ACL(role based ACL),处理方式也类似。&/p&&/li&&li&&p&conditional request:在访问的入口处,如果访问是 PUT/PATCH 这样修改已有资源的操作,好的 API 实现会要求客户端通过 conditional request(if-match / if-modified)做 concurrent control,目的是保证客户端要更新数据时,它使用的是服务器的该数据的最新版本,而非某个历史版本,否则返回 412 precondition failed(更多详情,请参考我之前的文章 &a href=&/?target=http%3A//mp./s%3F__biz%3DMzA3NDM0ODQwMw%3D%3D%26mid%3Didx%3D1%26sn%3Dce67b093e0%26scene%3D21%23wechat_redirect& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&撰写合格的REST API&i class=&icon-external&&&/i&&/a&)。&/p&&/li&&li&&p&preprocessing hook:稍后讲。&/p&&/li&&li&&p&processing:API 本身的处理。这个一般是 API 作者提供的处理函数。&/p&&/li&&li&&p&postprocessing:稍后讲。&/p&&/li&&li&&p&conditional request:在访问的出口处,如果访问的是 GET 这样的操作,好的 API 实现会支持客户端的 if-none-match/if-not-modified 请求。当条件匹配,返回 200 OK 和结果,否则,返回 304 Not Modified。304 Not Modified 对客户端来说如同瑰宝,除了节省网络带宽之外,客户端不必刷新数据。如果你的 app 里面某个类别下有五十篇文章,下拉刷新的结果是 304 Not Modified,客户端不必重绘这 50 篇文章。当然,有不少 API 的实现是通过返回的数据中的一个自定义的状态码来决定,这好比「脱裤子放屁」—— 显得累赘了。&/p&&/li&&li&&p&response normalization:和 request 阶段的 normalization 类似,在输出阶段,我们需要将结果转换成合适的格式返回给用户。response normalization 也有很多 strategy,比如:&/p&&/li&&ul&&li&&p&output adapter:如果说 input adapter 是为有洁癖的程序员准备的,可有可无,那么 output adapter 则并非如此。它能保持输出格式的一致和统一。比如你的数据库里的字段是 camel case,你的程序也都是用 camel case,然而 API 的输出需要统一为 snake case,那么,在 output adapter 这个阶段统一处理会好过每个 API 自己处理。&/p&&/li&&li&&p&aliasing:很多时候,你获得的数据的名称和定义好的 API 的接口的名称并不匹配,如果在每个 API 里面单独处理非常啰嗦。这种处理可以被抽取出来放在 normalization 的阶段完成。API 的撰写者只需要定义名称 A 需要被 alias 成 B 就好,剩下的由框架帮你完成。&/p&&/li&&li&&p&partial response:partial response 是 google API 的一个非常有用的特性(见:&a href=&/?target=https%3A///%2B/web/api/rest/%23partial-response& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://&/span&&span class=&visible&&/+&/span&&span class=&invisible&&/web/api/rest/#partial-response&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a& ),他能让你不改变 API 实现的情况下,由客户端来决定服务器返回什么样的结果(当前结果的一个子集),这非常有利于节省网络带宽。&/p&&/li&&/ul&&li&&p&serialization:如果 API 支持 content negotiation,那么服务器在有可能的情况下,优先返回客户端建议的输出类型。同一个 API,android 可以让它返回 application/msgpack;web 可以让它返回 application/json,而 xbox 可以获得 application/xml 的返回,各取所需。&/p&&/li&&li&&p&postserialization:这也是个 hook,在数据最终被发送给客户端前,API 调用者可以最后一次 inject 自己想要的逻辑。一般而言,一些 API 系统内部的统计数据可以在此收集(所有的出错处理路径和正常路径都在这里交汇)。&/p&&/li&&/ul&&p&多说两句 response normalization,如果在这一层做得好,很多 API 里面啰啰嗦嗦处理的事情都能被处理的很干净。你只需要一套严格测试过的代码,就可以让所有的 API 在输出时大为受益。比如:&/p&&div class=&highlight&&&pre&&code class=&language-json&&&span class=&p&&{&/span&
&span class=&err&&errorName:&/span& &span class=&err&&'world',&/span&
&span class=&err&&errorMessage:&/span& &span class=&err&&'hello&/span& &span class=&err&&world',&/span&
&span class=&err&&details:&/span& &span class=&err&&{&/span&
&span class=&err&&...&/span&
&span class=&p&&}&/span&
&span class=&err&&}&/span&
&/code&&/pre&&/div&&p&在经过 response normalization:&/p&&ul&&li&&p&output adapter 把 camel case 变成 snake case,所以 errorName -& error_name&/p&&/li&&li&&p&aliasing(如果定义了 error_name -& err_name)把 error_name 转换为 err_name&/p&&/li&&li&&p&如果客户端访问时只想要 err_name / err_msg,那么 partial response 只返回这两个域&/p&&/li&&/ul&&p&返回结果如下:&/p&&div class=&highlight&&&pre&&code class=&language-text&&{
err_name: 'world',
err_msg: 'hello world'
&/code&&/pre&&/div&&p&这样的一个 pipeline 从具体的 API 的行为中抽象化出了一个 API 处理的基本流程,并且很容易在几个 hook 处进行扩展。&/p&&p&以上的描述基本上和语言,框架无关。回到 node 和 restify 本身,我们会发现,有些事情并不好处理。比如说,在 restify 里,一个路由的 action 往往就会直接调用 res.send() 发送数据,那么,post-processing 的各种行为如何能够注入?如果是从头开始构建一个框架,那么,pipeline 里的每个组件返回一个 Promise 或者 Observable,将其串联起来就可以了,但在 restify 里,你无法这么干。对于这样一个具体的问题,我采用的方法是使用 python 中 wraps 类似的方式:&/p&&div class=&highlight&&&pre&&code class=&language-text&&function wrap(fn, skipEventFn, name) {
return function newFn() {
if (!this.server) {
throw new Error('Cannot wrap to a function without this.server as context');
const params = Array.from(arguments);
const getEventName = prefix =& lodash.camelCase(`${prefix} ${name || fn.name}`);
const skip = skipEventFn ? skipEventFn(params) :
if (!skip) this.server.emit(getEventName('before'), params, this);
fn.apply(this, params);
if (!skip) this.server.emit(getEventName('after'), params, this);
// usage:
// res.send = wrap(res.send.bind(res), skipFn, 'send');
&/code&&/pre&&/div&&p&然后通过监听 'beforeSend','afterSend' 两个事件来起到注入逻辑的效果。这样虽说是个 hack,但是是眼下可能最好的解。&/p&&p&在 node.js 这样的异步系统里还要注意,event emit 的监听函数如果是异步的,处理起来的顺序可能并非如你所愿,为此,我开发了一个 eventasync 库,对 node.js 的 event emitter 做 monkey patch,使其支持 async listerner。&/p&&h2&接口&/h2&&p&理顺了 pipeline,整个架构基本就清晰了,接下来要考虑提供一个什么样的接口让 API 的写作能够高效。restify 提供的接口:&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span class=&nx&&server&/span&&span class=&p&&.&/span&&span class=&nx&&use&/span&&span class=&p&&(&/span&&span class=&kd&&function&/span&&span class=&p&&(&/span&&span class=&nx&&req&/span&&span class=&p&&,&/span& &span class=&nx&&res&/span&&span class=&p&&,&/span& &span class=&nx&&next&/span&&span class=&p&&)&/span& &span class=&p&&{&/span& &span class=&p&&...&/span& &span class=&p&&});&/span&
&span class=&nx&&server&/span&&span class=&p&&.&/span&&span class=&nx&&get&/span&&span class=&p&&(&/span&&span class=&s1&&'/topic'&/span&&span class=&p&&,&/span& &span class=&kd&&function&/span&&span class=&p&&(&/span&&span class=&nx&&req&/span&&span class=&p&&,&/span& &span class=&nx&&res&/span&&span class=&p&&,&/span& &span class=&nx&&next&/span&&span class=&p&&)&/span& &span class=&p&&{&/span& &span class=&p&&...&/span& &span class=&p&&});&/span&
&/code&&/pre&&/div&&p&虽然很简单,但是很难满足我们对于 pipeline 的需求,比如说,validation。如何做 validation 只能是某个 API 的作者来做决策,框架来收集这些决策信息并在 pre-processing 阶段执行。所以,我们必须在路由初始化之前收集这一信息;此外,还有很多信息,如一条路由是否需要 authentication,如何做 alias,这些信息都需要 API 的撰写者提供给框架,而框架来收集。所以,作为一个框架,我们需要一个更好的 interface 提供给 API 的撰写者。这是我的 proposal:&/p&&img src=&/ccbdd02c69850aa_b.png& data-rawwidth=&1936& data-rawheight=&1034& class=&origin_image zh-lightbox-thumb& width=&1936& data-original=&/ccbdd02c69850aa_r.png&&&p&这个接口包含几重信息:&/p&&ul&&li&&p&路由接受 POST method&/p&&/li&&li&&p&路由的 path 是 /logout&/p&&/li&&li&&p&路由有一个很详细的 markdown 撰写的文档(还记得我们的需求是:easy to document 么?)&/p&&/li&&li&&p&其接受一个参数为 (req, res, next) 的 action function(也可以是多个)&/p&&/li&&li&&p&其对 body 提供一个 joi validator(除 body 外,也可以对 header,param 和 query 做 validation)&/p&&/li&&li&&p&使用这个 API 需要 authentication,调用完毕后要记录 audit trail&/p&&/li&&/ul&&p&通过这样一个接口,我们把 API 系统区隔为「编译时」和「运行时」。这个接口写出来的 API,更像是一个等待编译的源文件。在 API 系统启动的时候,会经历一个「编译」的过程,把所有的 route 汇总起来,生成 restify 认识的路由形式,同时,收集里面的各种信息(比如 validator,authentication),供框架的各个 middleware 使用。&/p&&p&不要小看这样一个接口上的改变和「编译时」/「运行时」的区分,它除了可以让 API 的各个信息无缝地和 pipeline 对接,还能够实现我们期望的 introspection:&/p&&img src=&/fdcb090d13dd226c2ef430a345f52bc1_b.png& data-rawwidth=&1912& data-rawheight=&1178& class=&origin_image zh-lightbox-thumb& width=&1912& data-original=&/fdcb090d13dd226c2ef430a345f52bc1_r.png&&&p&(通过 route 生成的 swagger 文档,供 API 使用者使用)&/p&&img src=&/bf7344bcd9ccf0fa7d442f8_b.png& data-rawwidth=&2690& data-rawheight=&1516& class=&origin_image zh-lightbox-thumb& width=&2690& data-original=&/bf7344bcd9ccf0fa7d442f8_r.png&&&p&(通过 route 生成的 cli 文档,供 API 开发者 introspection)&/p&&p&相信通过这个接口,你能够更好地理解 David Wheeler 的那句:&/p&&blockquote&&p&All problems in computer science can be solved by another level of indirection.&/p&&/blockquote&&p&下一篇我们讲讲 CLI。&/p&
里我们谈到了做一个 API 系统的基本思路和一些组件的选型,今天谈谈架构。部署首先要考虑的架构是部署的架构。部署的方案往往会深刻影响着系统的结构。我们需要问自己一个问题:从宏观上看,这个系统我们希望如何进行部署?很多 …
&img src=&/d3b420d7a27fa34bb5dbf_b.png& data-rawwidth=&1280& data-rawheight=&720& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&/d3b420d7a27fa34bb5dbf_r.png&&&h1&背景&/h1&&p&去年我写过一篇文章:&a href=&/?target=http%3A//mp./s%3F__biz%3DMzA3NDM0ODQwMw%3D%3D%26mid%3Didx%3D1%26sn%3Dce67b093e0%26scene%3D21%23wechat_redirect& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&撰写合格的 REST API&i class=&icon-external&&&/i&&/a&。当时 Juniper 裁掉了我们在德州的一支十多人的团队,那支团队有一半的人手在之前的半年里,主要的工作就是做一套 REST API。我接手这个工作时发现那些API写的比较业余,没有考虑几个基础的HTTP/1.1 RFC(,5988等等)的实现,于是我花了些时间重写,然后写下了那篇文章。&/p&&p&站在今天的角度看,那时我做的系统也有不少问题,很多 API 之外的问题没有考虑:&/p&&ul&&li&&p&API 的使用文档。当时我的做法是把文档写在公司使用的协作系统 confluence 里,但这样做的最大的问题是:代码和文档分离,不好维护。&/p&&/li&&li&&p&API 的监控。整个 API 系统没有一个成体系的监控机制,各种 metrics 的收集严重依赖 API 的实现者处理,拿时髦的话说就是没法 orchestrate。&/p&&/li&&li&&p&API 的测试。做过大量 API 工作的人都知道,为 API 写测试用例是非常痛苦的事情,你不但要对 API 使用的代码做 unit test,还需要对 API 本身做 smoke test(最基本的 functional test),保证所有 API 是可用的,符合预期的。由于需要撰写的测试用例的数量巨大,一般我们写写 unit test 就了事。&/p&&/li&&/ul&&p&理想情况下,一个 API 撰写完成,应该能够自动生成文档和测试用例,而 API 系统也应该提供一整套统计的 API 用于生成 metrics。缺省情况下,API 系统本身就应该收集很多 metrics,比如每个 API 的 response time,status code 等等,使用 collectd / statd 收集信息,并可以进一步发送到 datadog / new relic 这样的 APM 系统。&/p&&p&在 adRise,我们有一套运行了数年的 API 系统,不符合 RFC,(几乎)没有文档,(几乎)没有测试,(几乎)没有监控,最要命的是,它的开发效率和运行效率都不高。因此,过去的一两个月,我主导开发了一个全新的 API 系统。&/p&&h2&目标&/h2&&p&在打造一个新的系统之前,我们需要确立一些目标。这是我在设计 API 时写下的一些目标:&/p&&ul&&li&&p&A well defined pipeline to process requests&/p&&/li&&li&&p&REST API done right (methods, status code and headers)&/p&&/li&&li&&p&Validation made easy&/p&&/li&&li&&p&Security beared in mind&/p&&/li&&li&&p&Policy based request throttling&/p&&/li&&li&&p&Easy to add new APIs&/p&&/li&&li&&p&Easy to document and test&/p&&/li&&li&&p&Introspection&/p&&/li&&/ul&&p&其中,introspection 包含两层意思:&/p&&ul&&li&&p&API 系统自动收集 metrics,自我监控&/p&&/li&&li&&p&无论是撰写者,还是调用者,都很很方便的获取想要获取的信息&/p&&/li&&/ul&&h2&选型&/h2&&p&有了以上目标,接下来的就是进行技术选型。技术选型是无法脱离团队单独完成的,如果让我个人选择一个基础语言和框架,我大概会选择基于 Erlang/OTP,使用 Elixir 开发的 Phoenix,或者,干脆使用 Plug(Phoenix 的基石)。因为 Plug / Phoenix 通过组合来构建 pipeline 的方式很符合我的思维,Elixir 对 macro 的支持和 Erlang 语言核心的 pattern matching 让诸如路由这样的子系统高效简洁美观,而 Erlang / OTP 的高并发下的健壮性又是一个 API 系统苦苦追求的。&/p&&p&然而,我需要考虑团队的现实。在 adRise,我们使用 node.js 作为后端的主要技术栈(还有一些 PHP / Python / scala),因此 API 系统最好是基于 node.js 来完成。node.js 下有很多适合于写 API 的框架,比如说:express,restify,hapi,loopback,sails.js 等。在综合考察了这些框架之后,我选择了 restify,原因有三:&/p&&ul&&li&&p&接口和结构非常类似 express(团队对此非常有经验),但比 express 更专注于 REST API&/p&&/li&&li&&p&一系列 middleware 和 route actions 可以组成一个灵活高效的 pipeline&/p&&/li&&li&&p&简单,可扩展性强,容易和其他库结合,很适合作为一个新的框架的起点&/p&&/li&&li&&p&源代码很好理解,一天内就能读完(好吧这是个凑数的原因)&/p&&/li&&/ul&&p&事实证明,这是个还算不错的选择。&/p&&p&定下了基础框架,接下来就是选择核心的组件。首先就是 validator。很多人做系统并不重视 validator,或者没有一个统一的视角去看待 validator,这样不好。任何一个系统的运行环境都是个肮脏的世界,到处是魑魅魍魉,污秽不堪;而我们希望系统本身是纯净的,是极乐净土,那怎么办?&/p&&p&简单,净化输入输出。对于一个 API,什么样的 header,body 和 querystring 是被允许的?什么样的 response body 是合格的?这个需要定义清楚。所以我们需要一个合适的 validator。如果说挑框架似四郎选秀女,环肥燕瘦让你眼花缭乱,选 validator 就像姜维点将,看来看去只有王平廖化堪堪可用。在 github 里逛了半天,最后能落入法眼的也只有 joi 和 json schema 可用。&/p&&p&json schema 其实很好用,很贴近各类 API 工具的 schema(swagger 直接就是用 json schema),可惜太 verbose,让程序员写这个有点太啰嗦:&/p&&div class=&highlight&&&pre&&code class=&language-text&&{
&title&: &Example Schema&,
&type&: &object&,
&properties&: {
&firstName&: {
&type&: &string&
&lastName&: {
&type&: &string&
&description&: &Age in years&,
&type&: &integer&,
&minimum&: 0
&required&: [&firstName&, &lastName&]
&/code&&/pre&&/div&&p&而 joi 是 hapi 提供的 validator,接口很人性化,相同的 schema,描述起来代码量只有前者的 1/3:&/p&&div class=&highlight&&&pre&&code class=&language-text&&joi.object().keys({
firstName: joi.string().required(),
lastName: joi.string().required(),
age: joi.number().min(0).description('Age in years'),
&/code&&/pre&&/div&&p&而且它还可以比较容易地逆向输出(当然,需要各种适配)成 json schema。输出成 json schema 有什么好处?可以用来生成 swagger doc!swagger 是一种 API 描述语言,可以定义客户端和服务器之间的协议。swagger doc 可以生成 API 的文档和测试UI,比如说:&br&&/p&&img src=&/fdcb090d13dd226c2ef430a345f52bc1_b.png& data-rawwidth=&1912& data-rawheight=&1178& class=&origin_image zh-lightbox-thumb& width=&1912& data-original=&/fdcb090d13dd226c2ef430a345f52bc1_r.png&&&p&在接下来的文章中,我会详细介绍 swagger。&br&&/p&&p&我们再看 ORM。经常使用 express 的同学应该了解,express 本身并不对你如何存取数据有过多干涉,任何人都可以按照自己的需求使用其所需要的数据访问方式:可以是 raw db access,也可以使用 ORM。这种灵活性在团队协作的时候是种伤害,它让大家很容易写出来风格很不统一的代码,而且,在写入数据库和从数据库中读取数据的 normalization,离了 ORM 也会带来很多 ad-hoc 的代码。因此,尽管 ORM 背负着很多骂名,我还是希望在涉及数据访问的层面,使用 ORM。&/p&&p&我们的系统的数据库是异构的,因此,纯种的,只对一类数据库有效的 ORM,如 Mongoose / Sequelize 就不太合适,上上之选是接口支持多种不同数据库,在需要特殊查询或者操作的时候还能转 native 的 ORM。这样,让工程师的效率和系统的效率达到一个平衡。在 node.js 下,这样的 ORM 不多,可用的似乎只有 waterline。waterline 是 sails.js 开源的一个 ORM,支持多种 db 的混合使用,在各个数据库无法统一的操作接口上(比如 mongodb 的 upsert),你可以方便地将其生成的 model 转 native,直接使用数据库的接口。&/p&&p&此外,waterline 的 model 的 schema 使用 json 来描述,这使得它可以很方便地转化成 joi schema,在系统的进出口进行 validation。&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span class=&c1&&// waterline schema&/span&
&span class=&kr&&const&/span& &span class=&nx&&attributes&/span& &span class=&o&&=&/span& &span class=&p&&{&/span&
&span class=&nx&&user_id&/span&&span class=&o&&:&/span& &span class=&p&&{&/span& &span class=&nx&&type&/span&&span class=&o&&:&/span& &span class=&s1&&'integer'&/span&&span class=&p&&,&/span& &span class=&nx&&required&/span&&span class=&o&&:&/span& &span class=&kc&&true&/span& &span class=&p&&},&/span&
&span class=&nx&&content_id&/span&&span class=&o&&:&/span& &span class=&p&&{&/span& &span class=&nx&&type&/span&&span class=&o&&:&/span& &span class=&s1&&'integer'&/span&&span class=&p&&,&/span& &span class=&nx&&required&/span&&span class=&o&&:&/span& &span class=&kc&&true&/span& &span class=&p&&},&/span&
&span class=&nx&&content_type&/span&&span class=&o&&:&/span& &span class=&p&&{&/span& &span class=&nx&&type&/span&&span class=&o&&:&/span& &span class=&s1&&'string'&/span&&span class=&p&&,&/span& &span class=&nx&&required&/span&&span class=&o&&:&/span& &span class=&kc&&true&/span& &span class=&p&&},&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&接下来是日志系统。一套 API 系统可能包含多台服务器,所以日志需要集中收集,处理和可视化。一般而言,我们可以用 ELK,或者第三方的服务。如果在设计系统之初就考虑日志的集中管理,那么日志的收集应该考虑用结构化的结构,而非字符串。字符串尽管可以使用 grok 来处理,但毕竟效率低,还得为每种日志写 grok 的表达式。由于 node restify 缺省使用 bunyan 作日志,而 bunyan 可以生成 json 格式的日志,因此直接满足我们的需求。&/p&&p&最后我们再看 test framework。一个合格的系统离不开一套合适的 test framework。我的选择是 ava / rewire / supertest / nyc。ava 是一个 unit test framwork,和 mocha / tape 等常见的 test framework 类似,解决相同的问题,不过 ava 能够并发执行,效率很高,而且对 es6 支持很棒,test case 可以返回 Promise,ava 处理剩下的事情。有时候我们需要测试一个模块里没有 export 出来的函数,或者 Mock 一些测试时我们并不关心的函数,rewire 可以很方便地处理这样的问题。supertest 可以做 API 级别的测试,也就是 functional testing,而 nyc 可以用来做 test coverage。&/p&&p&今天先讲这么多,下次谈谈如何架构一个 API 系统。&/p&
背景去年我写过一篇文章:。当时 Juniper 裁掉了我们在德州的一支十多人的团队,那支团队有一半的人手在之前的半年里,主要的工作就是做一套 REST API。我接手这个工作时发现那些API写的比较业余,没有考虑几个基础的HTTP/1.1 RFC(2616…
&img src=&/f4e6c310e49_b.jpg& data-rawwidth=&950& data-rawheight=&280& class=&origin_image zh-lightbox-thumb& width=&950& data-original=&/f4e6c310e49_r.jpg&&&i&题图来自&a href=&/?target=https%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&豆瓣市集&i class=&icon-external&&&/i&&/a&。&/i&&p&新年开始没多久,支付宝就如期寄来了年度账单,看着那个让人瞠目结舌的数字,我真有点怀疑全世界都在唱衰的中国经济是不是真的有这么不中用。这年头,最聪明的头脑们都去考虑如何让人们在网站上买更多的东西了。包邮、折扣、秒杀、导购、众筹、猜你喜欢和晒单红包,每一件事情都巧妙的改变着买卖这个古老的生意。看起来这是一件无需过分忧虑的事情,我们都有足够多的钱可以花在“立即购买”按钮上,信用卡和白条可以把存款减少带来的焦虑延后一点,或者均摊到未来的数月间,变得更加微不足道。我们没来由的乐观,认为美好的事情即将发生,我们的收入和存款总会增加,账单都是寄给未来的。&/p&&p&从支付宝的账单退出来,我看了看我的手机主屏。除了那几个基本的在“不智能手机”时代就存在的功能,真的想不出哪个应用是和买买买没关系的。好吧,随便挑几个说。地图?里面可以买电影、定餐馆、叫外卖。菜谱?一启动就是年货专场全场八折。微信、微博什么的,总会有的没的夹带一些向往美好生活的私货给你。高明之处在于不是用“立即购买”来和你谈钱,而是用“阅读全文”来和你调情。你点开手机屏幕上任何一个右上角挂着小红点的图标,三步之内就能点开一张精美的商品图片,下面还有一个过期不候的限时特价。中产阶级嘛,消费升级嘛,每个东西都是时尚大牌设计师款手工打造的,或者会在商品的售价中捐出一些给公益事业的钱。手机原来是交流的工具,现在变成了交易的渠道。几乎在所有的屏幕上,电商网站都占据着越来越正中的位置。我们获取的信息中,都隐约掺入了叫卖的嘈杂。卑微而忙碌的生活如同浸泡在商品的海洋里,而我们认真的挑选和比较,最终做出了附加了情怀、调性和品味的选择,才算是向着不远的未来美好的生活迈出了不大不小的一步。从淘宝小店,到京东正品,又到海外直购,价签越高,则人生越有进境。仿佛买得多,就是过得好。我们就是这样,被身上遮体的衣物、盘中果腹的食品代言来着。&/p&&p&买买买,在“Zero to One”这本书中意味着一种“没来由的乐观主义”(Indeterminate Optimism),就是说你坚定的相信未来会变好,但不知道以何种路径变好,也不知道会变成什么样的“好”。美国人就是“不确定的乐观主义”的典型,表现为整个社会在自然科学上的不思进取,却在消费和娱乐上空前繁荣。而对于中国消费者而言,买买买实际上还是一个刚刚萌生的念头。在作者、著名的风险投资家彼得·泰尔眼中,中国应该被定义为“没来由的悲观主义”:中国人习惯性的高额储蓄和疲软的消费欲望代表了对未来的悲观看法和不自信。现在看来,这一判断可能有待商榷:风险资本给在线购物加上了巨大的资本杠杆,补贴、降价和包邮已经让年轻的网购族群开始更勇敢的花钱,甚至愿意学着美国人的样子用“信用”担保透支。实际上,在拥有一件东西的满足感面前,极少有人能够抗拒。正如那个饱受争议的拍卖网站广告中所宣讲的一样:所有东西都可以被出售,只是价格问题。中国消费者的价格弹性如此之大,只要有些许实惠,就能撬动巨大的消费增量。从悲观主义到乐观主义,难道只差了一张更接地气的价格标签吗?&/p&&img src=&/d6a73e5e3ea18867ef03fd_b.png& data-rawwidth=&500& data-rawheight=&423& class=&origin_image zh-lightbox-thumb& width=&500& data-original=&/d6a73e5e3ea18867ef03fd_r.png&&&p&我们所身处的经济是一台累积了多年势能的生产机器。就在我们习惯于把多快好省的标签贴到这台机器的每一个零件上的时候,作为机器的操纵者,我们却没有足够的智慧预言消费的趋向。在生产能力和原材料消耗巨大的同时,我们却只能依赖于政府主导的基础设施投资来消化这些产能。有时候,这种生产就像妈妈夜以继日辛苦编织的旧式毛衣,尽管针针入魂,却也难以让孩子们提起兴趣。在大前研一的“M 型社会”一书中,他认为随着社会收入分层的逐步产生,新的经济增长点理应产生在那些“感觉好价格低”以及价廉物美的“新奢华”商品上。这一点可能已经悄悄的在我们的淘宝账单上体现出来了,无论是优衣库或 Zara 的快时尚,还是华为和小米的新国货,又或是滴滴和 Uber 的共享经济,都通过各自的方式创造了新的价值定位。如果深入分析,则会发现,它们的共同点并非单纯的底价,而是在价格之外提供更加优质的体验和质量。经过多年的经济繁荣,新兴的中国消费者实际上已经开始更加理性的进行消费决策。新的主力消费阶层并不随意在乐观和悲观之间摇摆,也不大会受到购物网站的一些小聪明而花大钱。真正值得押注的仍然是能否以合理的成本结构提升效率、体验和质量,而非以诱导那些非理性的冲动消费,透支未来。&/p&&p&在结束之前,我忍不住再想谈谈未来。科幻作家威廉·吉布森说:未来已来,只是分布不均。就在中国股市在开年以来数次下跌熔断而导致悲观情绪弥漫的同时,消费电子展 CES 和北美车展相继在拉斯维加斯和底特律召开。通用汽车公司接连宣布推出廉价纯电动汽车,并大笔投资类似 Uber 的出行公司 Lyft。福特、日产等几乎所有的主流车企都展示了自己在新能源、无人驾驶等方面的野心。汽车行业曾经被如此看衰,但却在短短几年之内咸鱼翻身。尽管中国大城市的地方政府一再补贴新能源汽车,但产品设计仍然差强人意,反而是让那些上路隐患重重的低速电动车获得了大笔补贴成功洗白。对于这样的“消费升级”,再多的担心也不为过。而未来的分布,也一定会偏爱那些更有远见和勇气的个体。&/p&&p&我们没有太多时间在衰退和繁荣的过分忧虑中摇摆不定。不过无论经济走势如何,总有一些基本的道理值得尊重。仅仅以买买买来定义未来显然是狭隘的,也丝毫不应该因为年复一年的花掉更多的钱而庆幸。对未来的乐观理应有来由、更精致、更清晰。&/p&
题图来自。新年开始没多久,支付宝就如期寄来了年度账单,看着那个让人瞠目结舌的数字,我真有点怀疑全世界都在唱衰的中国经济是不是真的有这么不中用。这年头,最聪明的头脑们都去考虑如何让人们在网站上买更多的东西了。包邮、折扣、秒杀、导购、…
&img src=&/02d2cdca65c23add424608_b.jpg& data-rawwidth=&800& data-rawheight=&450& class=&origin_image zh-lightbox-thumb& width=&800& data-original=&/02d2cdca65c23add424608_r.jpg&&&p&教父级的风险投资家、顶级孵化器的创始人 Paul Graham 这样&a href=&/?target=http%3A///growth.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&教导我们&i class=&icon-external&&&/i&&/a&:&/p&&blockquote&Start-up = Growth. &br&创业公司即增长机器。&br&&br&A startup is a company designed to grow fast. Being newly founded does not in itself make a company a startup. Nor is it necessary for a startup to work on technology, or take venture funding, or have some sort of &exit.& The only essential thing is growth. Everything else we associate with startups follows from growth.&br&创业公司的定义就是快速增长的公司。成立时间短,有技术,有风险投资或者以某种形式“退出”套现,都不是它的定义。唯一核心的事情就是增长。其它事情都因增长而来。&/blockquote&&p&然而,现实情况是,大部分成功进入增长阶段(Growth Stage)的创业公司都难以把增长变成一个持续的过程。过去在创业公司工作的经验告诉我,一个创新产品的增长动力会随着用户群的扩大而发生迁移,对这个过程描述最好的莫过于&a href=&/?target=http%3A///subject/1431653/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&《跨越鸿沟》(Crossing the Chasm)一书&i class=&icon-external&&&/i&&/a&中对创新扩散曲线的解读:&/p&&p&&img src=&/e2a049aeeb5bbf02b54985e_b.png& data-rawwidth=&912& data-rawheight=&519& class=&origin_image zh-lightbox-thumb& width=&912& data-original=&/e2a049aeeb5bbf02b54985e_r.png&&这本书的副标题叫做 Marketing and Selling Disruptive Products to Mainstream Customers,是一本名副其实的硅谷畅销书,很多创业者都熟稔书中提出的理论:&/p&&ol&&li&创新产品在早期的两个阶段时,主要受众是创新者(Innovators)和早期接受者(Early Adopters),这些受众的核心诉求是技术和性能。很多时候,这些人就是在新产品内测时就来排队的那些人。这些人如果不是行业中人,就是具有足够的好奇心和兴趣,他们经常也通过各种形式有一些圈子,能够快速传播消息,形成早期的快速增长动力。&/li&&li&在经历了早期增长期后,就进入了最重要的那个阶段:让大多数人都接受一个前所未见的新鲜事。这时候,受众关注的要点是产品能够解决问题,使用是否方便等实用性和功利性的要素。此书最大的价值在于告诉创业者,两个阶段之间存在一条鸿沟(Chasm),只有跨越这条鸿沟,才能触达大多数人,形成真正持续的增长。&/li&&/ol&&p&这就是说,不管你这个季度的增长曲线又多么好看,都可能只是处在鸿沟之前的那个阶段。增长只是来自于一个其乐融融的小圈子。而大多数人对你的产品闻所未闻,未来也可能漠不关心。突然有一天,漂亮的增长趋势可能会戛然而止。&/p&&p&Greylock Partners 分享了下面两张图。&/p&&img src=&/0f012f7ce2dba35bb7001710bcd206ef_b.jpg& data-rawwidth=&800& data-rawheight=&450& class=&origin_image zh-lightbox-thumb& width=&800& data-original=&/0f012f7ce2dba35bb7001710bcd206ef_r.jpg&&&img src=&/25ca51dc992f8db0fccf132e_b.jpg& data-rawwidth=&800& data-rawheight=&450& class=&origin_image zh-lightbox-thumb& width=&800& data-original=&/25ca51dc992f8db0fccf132e_r.jpg&&&p&如果仅看第一张图,那么你几乎会马上得出结论说,这些公司在增长方面都很成功。但熟悉的情节发生在第二张图上,除了 Snapchat 之外,其余三个公司的增长曲线都几乎是在一夜之间开始跌落。&/p&&p&作为曾经的创业者,我亲身经过类似的情景。早在 2012 年的时候,我曾经创办过一家移动广告方面的公司。当时正是中国移动互联网发展的早期,那些喜欢尝鲜的科技爱好者已经开始购买自己的第一部 iPhone 或者 Android 手机,并逐步扩散到更多的人群。我们的广告流量也因此快速增长,在一周之内涨了 10 倍。我们当时挤在面对北京建国门桥的一间会议室里办公,看完流量数据,我愉快的站起身来,面对着东二环熙熙攘攘的车流,心里颇有一种指点江山的快意。后面的故事你应该猜到了,曲线经历了一段时间的停滞之后,开始调头向下。再好的商务拓展团队也无力回天。&/p&&p&我不止一次和小伙伴们聊起这段经历,每次都会加上一句话:如果你不知道是怎么涨上去的,也不会知道什么时候就会跌下来。&b&要想遏制这样的悲剧,几乎只有不停的寻找让产品跨越鸿沟的机会点。在这个过程中,有时候甚至需要勇敢的否定掉一开始的那个让你获得最早的 10 万用户的方向,因为那个方向很可能只对早期用户有吸引力,而对后续讲求实用性的大多数人毫无帮助。&/b&&/p&&p&Greylock Partners 认为,单纯关注用户数量增长的趋势是不够的,更关键的是定义产品的核心用户行为,跟踪完成这个行为的数量变化才能得到增长的实际趋势。一个反例就是 Viddy 这个曾经在 Facebook 上风靡的短视频应用:&/p&&p&&img src=&/bb3c087068cf_b.jpg& data-rawwidth=&800& data-rawheight=&450& class=&origin_image zh-lightbox-thumb& width=&800& data-original=&/bb3c087068cf_r.jpg&&尽管曾经获得 Facebook 在信息流里面的推荐,短期用户量快速增长,但很快就出现了增长停滞的情况。核心原因是导入的新用户并没有为 Viddy 的核心功能短视频拍摄买单,更遑论形成稳定的用户习惯。说直白一点,就是产品“没用”。这样的情况还发生在大量“现象级”的产品身上,国内也有很多例子,就不一一点名了。&/p&&p&Greylock Partners 最后用这张图总结了持续增长,直至成为十亿美金公司的规律:&/p&&img src=&/02d2cdca65c23add424608_b.jpg& data-rawwidth=&800& data-rawheight=&450& class=&origin_image zh-lightbox-thumb& width=&800& data-original=&/02d2cdca65c23add424608_r.jpg&&&ol&&li&第一阶段:专注于让用户完成核心行为&/li&&li&第二阶段:用户使用越多,越会觉得产品好用和有用,迁移成本变高&/li&&li&第三阶段:用户形成正向的反馈回路,更加忠诚&/li&&li&最终目标:基业长青的、十亿美金的生意&/li&&/ol&&h2&致谢&/h2&&p&感谢来自 Greylock Partners 的 &a href=&/?target=https%3A///greylock-perspectives/the-hierarchy-of-engagement-cfa& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&The Hierarchy of Engagement&i class=&icon-external&&&/i&&/a&,这个材料让我对创业企业的增长有了更深的理解。&/p&&h2&更多&/h2&&p&这个主题下的文章会逐渐形成一个系列。现在有了续集:&a href=&/p/& class=&internal&&你应该在什么时候跳上创业的火箭飞船?&/a&&/p&&p&欢迎关注我的微信公众号 platformed,虽然内容和这里是几乎同步的(因为知乎的编辑器更好用,所以知乎往往会是首发)。&/p&
教父级的风险投资家、顶级孵化器的创始人 Paul Graham 这样:Start-up = Growth. 创业公司即增长机器。A startup is a company designed to grow fast. Being newly founded does not in itself make a company a startup. Nor is it necessary for…
回信/明信片的时候要把信封上面的&b&自谦语&/b&改成&b&敬语&/b&。(多图)&br&&br&比如电力公司给你寄信,希望获得你的银行卡信息(就可以直接转账不用去银行缴费),那么你会收到一个大信封,里面装着一个填写个人信息的卡片和一个小信封。小信封是用来把填好的卡片寄回去的,不需要贴邮票,也已经写好了收信人地址(就是电力公司自己)。收信人地址最后会是&b&行&/b&这个字,意思是&b&xx收&/b&。这句话是&u&电力公司请顾客把信寄给自己&/u&,必须用&b&自谦语&/b&(即下对上说的话,比如寒舍、草民)。然而回信的时候,是&u&用户对公司的行为&/u&。为了表示对公司的&b&尊敬&/b&,必须说&b&敬语&/b&。直接用信封上写的&b&行&/b&是&b&很不礼貌&/b&的。所以就要把&b&行&/b&字改成敬语&b&御中&/b&,意思并没有变。&br&&br&比较常见的做法是两条线划掉在旁边写:&br&&img src=&/ed89d4c6d87e7b8b9a11925_b.jpg& data-rawwidth=&537& data-rawheight=&302& class=&origin_image zh-lightbox-thumb& width=&537& data-original=&/ed89d4c6d87e7b8b9a11925_r.jpg&&具体一点就是:&br&1. 文字纵向排版时候,两条线要从右上到左下。两条竖线也可以,但是不好看。&br&2. 横向排版时候斜线不好看,之所以要换成两条横线。&br&3. 要用尺子,徒手画的不好。。。&br&4. 御中在横着排版情况下写右边,竖着拍版的话写左下(不严格要求)。&br&例:&br&&img src=&/d5adf727cdeb2_b.jpg& data-rawwidth=&400& data-rawheight=&273& class=&content_image& width=&400&&当然还有这样的:&br&&img src=&/c3d552e6f3bd422e60f4_b.jpg& data-rawwidth=&320& data-rawheight=&298& class=&content_image& width=&320&&&img src=&/45f5d9cefb0f4c6fa35e3c9e3c89e13e_b.jpg& data-rawwidth=&640& data-rawheight=&298& class=&origin_image zh-lightbox-thumb& width=&640& data-original=&/45f5d9cefb0f4c6fa35e3c9e3c89e13e_r.jpg&&等等。规则详见&a href=&///?target=http%3A//u-note.me/note/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&往復はがきを返信する時の「行の消し方と御中の書き方」の正しいマナー|U-NOTE [ユーノート]&i class=&icon-external&&&/i&&/a&。&br&&br&当然这个还没完。遇到请帖怎么办?请帖一般长这样:&br&&img src=&/a5fa66aeeccb092b4035e_b.jpg& data-rawwidth=&480& data-rawheight=&469& class=&origin_image zh-lightbox-thumb& width=&480& data-original=&/a5fa66aeeccb092b4035e_r.jpg&&会有一张卡片让你&b&圈出来出席还是欠席&/b&,然后在空白位置&b&写一些祝福的话&/b&,然后&b&寄回去&/b&(上右)。可以看到,&b&御&/b&出席、&b&御&/b&欠席、&b&御&/b&住所、&b&御芳&/b&名都是敬语,需要&b&全部划掉&/b&。很多人会落掉那个&b&芳&/b&字。。。然后如果出席,要圈出来&b&出席&/b&二字,然后把&b&欠席&/b&划掉。最后如下:&br&&img src=&/8f1ac139d1fa3baed4c4ac_b.jpg& data-rawwidth=&500& data-rawheight=&360& class=&origin_image zh-lightbox-thumb& width=&500& data-original=&/8f1ac139d1fa3baed4c4ac_r.jpg&&不去的话这样:&br&&img src=&/f23bae16d058e2fc253a441_b.jpg& data-rawwidth=&378& data-rawheight=&234& class=&content_image& width=&378&&然后还可以用&b&寿&/b&这个字把那些&b&敬语&/b&划掉。。。如下:&br&&img src=&/4cb28f7cc0fd8f9e414768_b.png& data-rawwidth=&450& data-rawheight=&400& class=&origin_image zh-lightbox-thumb& width=&450& data-original=&/4cb28f7cc0fd8f9e414768_r.png&&一定要用朱红色的笔。(关键字:結婚式 返信)&br&&br&如此会玩的霓虹近是不会这样就完了的,于是会出现一些逗逼:&br&&img src=&/cbdb4bcdb64ed6_b.jpg& data-rawwidth=&1000& data-rawheight=&521& class=&origin_image zh-lightbox-thumb& width=&1000& data-original=&/cbdb4bcdb64ed6_r.jpg&&&img src=&/b2afbcfdd7630c_b.jpg& data-rawwidth=&406& data-rawheight=&1000& class=&content_image& width=&406&&&img src=&/886b3f0882a9decc5ce7_b.jpg& data-rawwidth=&600& data-rawheight=&398& class=&origin_image zh-lightbox-thumb& width=&600& data-original=&/886b3f0882a9decc5ce7_r.jpg&&&img src=&/b4d2cb2db2b3_b.png& data-rawwidth=&423& data-rawheight=&389& class=&origin_image zh-lightbox-thumb& width=&423& data-original=&/b4d2cb2db2b3_r.png&&等等。(关键词:結婚式 招待状 全力で出席)&br&&br&&blockquote&推主ToshihiroANZAI收到了一张结婚明信片,觉得好像很难选择“不去”这个选项,然后各路网友纷纷帮忙,脑洞也是蛮大的……(@秋田六千)&br&&img src=&/df37411cfdf8de_b.jpg& data-rawwidth=&440& data-rawheight=&492& class=&origin_image zh-lightbox-thumb& width=&440& data-original=&/df37411cfdf8de_r.jpg&&&img src=&/bbf728697dfd9da910fb19a2f7c1906a_b.jpg& data-rawwidth=&440& data-rawheight=&550& class=&origin_image zh-lightbox-thumb& width=&440& data-original=&/bbf728697dfd9da910fb19a2f7c1906a_r.jpg&&&img src=&/8b6a452ba4a4eb5315fe32a_b.jpg& data-rawwidth=&440& data-rawheight=&549& class=&origin_image zh-lightbox-thumb& width=&440& data-original=&/8b6a452ba4a4eb5315fe32a_r.jpg&&&img src=&/c9462f2caeeefd29da56d13_b.jpg& data-rawwidth=&440& data-rawheight=&549& class=&origin_image zh-lightbox-thumb& width=&440& data-original=&/c9462f2caeeefd29da56d13_r.jpg&&&/blockquote&来自新浪囧哥&a href=&///?target=http%3A///article/jionggeshuoshi/top/original-ifxqafha0336020.d.html%3Fvt%3D4%26mid%3Daxixtqq2785002& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&囧哥:中国点钞神功,震惊全球&i class=&icon-external&&&/i&&/a&。&br&&br&———————————————分割线———————————————&br&&br&再补两个:&br&1. 日本人坐着洗澡。一家人轮番洗完以后用同一锅水泡澡。“毕竟已经洗干净了嘛。”&br&2. 过年要写明信片(年贺状),比较认真的是手画,彩色复印几十张,留出一块空白,然后每张单给某个人再手写一两句祝福的话。一般给所有同学/同事写完要几个小时到十几个小时。如果12月25号之前寄出去,就能在过年当天收到。一开邮箱,一沓明信片,然后拿回屋里分。这个是爸爸的,这个是我的,这个是哥哥/姐姐的……有的孩子会拿一个小本记录同学里给谁寄了收到谁的了,特别详细。我说要是你给他寄了他没给你寄怎么办,回答是没什么事。然后经常过完年看到大家抱怨啊我年贺状还没来得及写呢。。。
回信/明信片的时候要把信封上面的自谦语改成敬语。(多图)比如电力公司给你寄信,希望获得你的银行卡信息(就可以直接转账不用去银行缴费),那么你会收到一个大信封,里面装着一个填写个人信息的卡片和一个小信封。小信封是用来把填好的卡片寄回去的,不…
数据说话。&br&&br&选取 manufacturing(制造业)、finance(金融)、banking(银行业)、consulting(咨询)、entrepreneurship(创业)、information technology(信息技术)、venture capital(风投)、private equity(私募) &br&&br&利用Google强大的Ngram来分析过去208年()这些行业的热度,唯有PE和entrepreneurship势头强劲啊。&br&&br&&img src=&/cfa655967faa8649_b.jpg& data-rawwidth=&1207& data-rawheight=&573& class=&origin_image zh-lightbox-thumb& width=&1207& data-original=&/cfa655967faa8649_r.jpg&&&br&&b&附:什么是Google Ngram?&/b&&br&&br&可参考我的另一个回答&a href=&/question//answer/& class=&internal&&Google(谷歌)有哪些逆天的黑科技? - Yumeng Guo 的回答&/a&&br&&br&2005年起,Google开始了一项宏大的项目,试图把自人类发明现代印刷术以来,全世界的书刊都扫描并数字化与数据化(&a href=&///?target=http%3A//en.wikipedia.org/wiki/Digitization& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Digitizing&i class=&icon-external&&&/i&&/a& and &a href=&///?target=http%3A//en.wikipedia.org/wiki/Datafication& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Datafication&i class=&icon-external&&&/i&&/a&)。至2008年已完成&b&5百万本书&/b&(5.2 million books),总共&b&5千亿&/b&&b&个单词&/b&(500 billion words)。&br&&br&而Ngram只是这项Big Data项目的一个小应用。以上图中manufacturing这根曲线为例,横坐标为1920年时,纵坐标是0.003%,其含义是:&b&在1920年出版的所有的书刊的所有单词中,manufacturing这个词出现的概率是0.003%&/b&&br&&br&这样我们就可以看到在历史长河中,某个单词的“命运”如何,是越来越受宠,还是逐渐被人遗忘。&br&&br&利用这个强大的工具,我们可以分析人类历史、文明,挖掘出很多不易被发现的现象。甚至已经出现了新的学科来研究它,就是&a href=&///?target=http%3A//en.wikipedia.org/wiki/Culturomics& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Culturomics&i class=&icon-external&&&/i&&/a&&br&&br&用《Big data》一书中所述观点,big data告诉我们的只是相关关系correlation,而不是因果关系causality。举个例子,google曾利用人们搜索flu等相关词汇的big data而成功预测流感在美国的传播方向与力度,为政府及时采取措施提供了有力帮助。但这里只是correlation,不是causality,搜flu的人一定得流感了吗?不一定。&br&&br&当然,Google也扫描了英文外的很多很多语言,包括中文。&br&&br&Ngram地址:&a href=&///?target=http%3A///ngrams& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&/ngrams&/span&&span class=&invisible&&&/span&&i class=&icon-external&&&/i&&/a&&br&(似乎需要翻墙)&br&&br&更多关于Google Ngram的介绍:&br&&br&Wiki: &a href=&///?target=http%3A//en.wikipedia.org/wiki/Google_Ngram_Viewer& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Google Ngram Viewer&i class=&icon-external&&&/i&&/a&&br&TED(力荐,让你瞬间迷上Ngram): &a href=&///?target=http%3A///movie/2014/5/S/D/M9PEG3P9U_M9PJF4ESD.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&我们从五百万本书里学到了什么&i class=&icon-external&&&/i&&/a&
数据说话。选取 manufacturing(制造业)、finance(金融)、banking(银行业)、consulting(咨询)、entrepreneurship(创业)、information technology(信息技术)、venture capital(风投)、private equity(私募) 利用Google强大的Ngram来分析过去208年()…
已有帐号?
社交帐号登录
无法登录?
社交帐号登录

我要回帖

更多关于 语文二年级上册 的文章

 

随机推荐