《冒号课堂》

  • 框架与工具包最大的差别在截然相反的设计理念上: 库和工具包是为程序员带来自由的,框架是为程序员带来约束的。具体地说,库和工具包是为程序员提供武器装备的,框架则利用控制反转(IoC)机制实现对各模块的统一调度,从而剥夺了程序员对全局的掌控权,使他们成为手执编程武器、 随时听候调遣的士兵。

  • 框架是在语言的语法规则之外施加于程序员的又一层枷锁,但没有规矩不成方圆。正如行军打仗,讲究排兵布阵,程序员就是那兵,框架就是那阵。

  • 离开 IDE 就无法编写、编译或调试的程序员,如同卸盔下马后便失去战斗力 的武士,是残缺和孱弱的。

  • 追星族倾向于盲目追捧,唯恐落伍,他们信奉新潮的、流行的就是好的;守旧派倾向于本能 抗拒,回避求新,他们认为经典的、传统的才是好的。

  • 抽象是前提,分解是方式,模块化是结果。

  • 单靠记忆只能触及知识之表,单靠练习只能深入知识之里,唯有培养方能渗透知识之根。

  • 学会适度地容忍无知。请注意,容忍无知不是放任无知,而是一种学习的技巧,让无知成为求知的动力而不是障碍。容忍无知能是我们既不沮丧气馁,也不急于求成。在学习时不妨略过一些细节或难点,先概览全貌以获取感性认识,然后逐步积累中升华为理性认识。

  • 不仅需要强调钻劲和深度的“钉子精神”,还需要强调磨功和广度的“刨子精神”。

  • 编程语言的语法、语义等都是编程范式的树根衍生而出的枝叶,把握了这种脉络和节奏,代码才会如音乐舞蹈般韵律有致。

  • 每种范式擅长的问题领域不尽相同,只有博闻广识,方可扬长避短,程序才会如行云流水般流畅自然。

  • 程序员更习惯机器风格的过程式思维和现实风格的 OOP 思维,不容易接纳数学风格的函数式思维。

  • 学习如打仗,除了要有直线式的纵深攻击,还要有曲线式的迂回包抄。

  • 每种范式都代表着一套独特而有效地解决问题的思想和方法。

  • 武功练至化境,一定是博采众长,就像杨过融合了东邪、西毒、南帝、北丐、中神通等各派武功,才能随心所欲地打出黯然销魂掌来。

  • 过程式与函数式的差别同时也是机器思维与数学思维的差别。

  • 没有副作用的函数是引用透明的(referential transparency),即一个表达式随时可以用它的值来替换,正如数学中的函数一样,保证了数学思维的贯彻和运用。

  • 函数式编程不仅有许多独特的概念和方法,还有很深的数学背景--lambda-演算(lambda calculus)。(lambda演算,被证明是图灵完备的。)

  • 评价代码的复杂度,长短只是一个因素。程序员不是打字员,花在思考上的时间和精力远远超过花在键盘上。

  • 算法=逻辑+控制。其中逻辑是算法的核心,控制主要用于改进算法的效率。在逻辑式编程中,程序员只需表达逻辑,而控制交给编程语言的解释器或编译器去管理。

  • 用数学逻辑的话来说,事实与规则是公理,查询就是特证的定理。

  • 相对于命令式,逻辑式更简洁、更抽象、更少副作用,不仅能提高生产效率,还能用于快速原型开发。但在运行效率、可掌控性、语言成熟度等方面有所欠缺。另外,因其思维方式独特而鲜为人用,适合基于规则而非基于状态的应用。

  • 设计模式好比组合套路,能在一些特定场合下克敌制胜;编程范式则好比武功门派,博大精深而自成体系。
    因其长而容己,因其短而容他,此万物之理也。

  • 语言为形,范式为神。若能以神导形、以形传神,则看似平白无趣的程序也能写出诗画般的意境。

  • 同样的思想用在整体系统的结构设计上,则称为架构模式;用在局部模块的细节实现上,则称为设计模式;用在引导编程实践上,则称为编程范式。

  • 一种编程范式之所以能独树一帜,关键在于它突破了原有的编程方式的某些限制,带来革命性的新思维和新方法,进一步解放了程序员的劳动力。这便是范式的核心价值所在。

  • 理论是认生的孩童,多陪他玩玩,自会活泼起来。

  • 可以这么理解(闭包):所谓包,指函数与其周围的环境变量捆绑打包;所谓闭,指这些变量是封闭的,只能为该函数所专用。
    合理地使用闭包能使代码更加简洁清晰,散发出函数式特有的优雅气质。

  • 每种编程范式都能在生活中找到它的应用,它们本来就是人类思维方式的投影。

  • 编程水平的提升之道是:在实战中演练招法,在招法中领会心法,心法反过来提升招法,进而提高实战水平,如此循环往复呈螺旋式上升。正所谓熟能生巧,巧能生通。

  • 无论干哪一行,要想胜任愉快,离不开四样东西:才能、兴趣、方法和努力。没有才能则难以胜任,没有兴趣则难以愉快,没有方法则事倍功半,没有努力则一事无成。我相信你好的方法最终能激发人的才能、兴趣和努力。

  • 编程范式绝非中看不中用的屠龙之书,它有助于我们更快速地掌握、更深刻地理解、更纯熟地运用编程语言,故有心法之谓。其次,心法只有通过招法才能落到实处,也只有通过招法才能融会贯通。

  • 迭代学习法:即在具体知识与抽象理论之间进行折返式学习。

  • 网页的迷人之处就在于,能够用精美的画皮来包裹冗长低效的代码。

  • 规则如裤带,过于宽松和过于束缚都不好。

  • 数据类型包含两个要素:一个是允许取值的集合,一个是允许参与的运算。

  • 数据类型既有针对机器的物理意义,又有针对人的逻辑意义。前者用于进行底层的内存分配和数值运算等,后者用于表达高层的逻辑概念。既然类型如此重要,类型检查就必不可少了。所谓动态类型语言,正是指类型检查发生在运行期间的语言。静态类型语言是类型检查发生在运行之前(将“编译期间”改为“运行之前”,否则容易让人误解为静态类型语言一定是编译型语言)的语言。

  • Duck类型的哲学:名义不重要,重要的是能力。

  • 静态类型检查类似“疑罪从有”的有罪推定制——在被证明合法之前是非法的,动态类型检查类似“疑罪从无”的无罪推定制——在被证明非法之前是合法的。

  • ‘Static Typing Where Possible, Dynamic Typing When Needed’

  • 尽可能守规则,必要时求变通。

  • 类型的动静以类型的绑定时间来划分,类型的强弱以类型的约束强度来划分,它们之间没有必然联系。

  • 动态语言秉承的一个理念是:优化人的时间而不是机器的时间。为提高人的生产率,宁肯牺牲部分的程序性能或者购买更高配置的硬件。由于硬件相对于人件一直在贬值,该理念便有了合理的现实基础。

  • A script is what you give the actors, a program is what you give the audience.

  • 换言之,程序是为终端用户服务的,而脚本是为程序员服务的。

  • 不妨这么理解,脚本语言以语言的实际用途为标志,动态语言以语言的语法特征为标志。

  • 程序员本就是双重人格的。

  • 待静态语言披盔戴甲、备马抬抢之际,动态语言已衣袂飘飘,长剑出手了。不过,如果是应付强敌的长期大规模作战,静态语言还是有优势的。

  • 程序员只要保持严谨的作风和开放的心态,既有稳如泰山的马步,又有一跃凌空的飞腿,静如处子,动如脱兔,如履平地般游走于高高的梅花桩上,绝无跌落之虞。

  • 如果说编程范式是一种文化,那么编程语言更像是一种宗教——尽管它本不该是。每种流行的语言都有大批忠实的信徒,随时可能与其他的信徒发生宗教战争。

  • 对待一门语言的态度应该是:与其抱怨争执,不如扬长避短。

  • 架构师并没有多么神秘,他们也是从程序员过来的。也不要以为架构师就不关心语言了,相反需要对语言有更广博、更深刻的认识。理想的架构师应当如文学大师,既有恢弘大气的构思,又有细腻深刻的笔法;应当如统军大帅,既有运筹帷幄的韬略,又有冲锋陷阵的武功。那些在语言与低级之间、设计与高级之间毫不犹豫地划等号的人,多半高不成低不就,既不懂语言,也不懂设计。

  • 从心理学上分析,一个人的某种观点形成后,会通过自我的暗示和倾向性的证据不断地强化这种观点,并对其他观点本能地选择性失明。这背后折射的其实是一种懒人心态——认定自己掌握的语言是最好的,便不必费事再学其他语言了;这更是一种弱者心态——无论是耿耿忠心的铁杆卫士,还是振振有词的辩护律师,一旦丧失自我批判的勇气和精神,声嘶力竭的挞伐只能反证他们的偏狭浅薄与自信缺失。

  • 每种语言都有天然设计上的不同,当你用得很别扭时,恰恰说明没有真正掌握。正如刀法以劈为主,枪法以扎为主,你若反其道而行之,刀扎枪劈,能不别扭吗?如果愣拿双节棍当单节棍使,恐怕没砸到别人倒先砸晕自己了。可见不是兵器问题,而是招法问题。

  • There are only two kinds of languages: the ones people complain about and the ones nobody uses.

  • 从另一个角度看,发明一种语言也是对先前语言的一种最高赞美。C++之于C,Java之于C++,C#之于Java,都是后者对前者的一种承认,哪怕是极不情愿的承认。批判与赞美,继承与发展,谓之扬弃。
    过分拔高一种语言与抹煞语言之间的差别是两种极端,皆为秕言谬说。

  • 对一个程序员而言,编程语言乃立身之本。(这里谈的语言,自然不是孤立的语法和用法,也包括背后的编程范式和设计思想。)

  • 程序员这门职业,你选择,你担当。

  • 《The C Programming Language》

  • 如果你因为是他的粉丝而后悔学C++,那就是为他人的偏执买单,不管那人名气有多大。

  • 一种语言不够复杂是因为它还不够成熟。

  • 能力越大,责任越大,风险越大。

  • 既然系统语言主要为底层系统的开发服务,这就决定了它们的理念是:优化机器的时间而不是人的时间,优化机器的记忆而不是人的记忆;假设编译器是愚蠢的而程序员是聪明的,因此赋予程序员更多的权利、义务和责任。

  • 学好C一本书足矣,学好C++即使推荐十本仍有遗珠之憾。可以说C++是苦了编程者,填了著书人。开个小书单:初级——《C++ Primer》和《Thinking in C++》;中级——《The C++ Programming Language》和《Effective C++》系列;高级——《The C++ In-Depth》系列。这里还要特别推荐一下《The Design and Evolution of C++》,从中你可以看到C++的设计和演变的来龙去脉,极具启发性。其他的C++精品书籍还有不少,恕不一一列举了。C++是匹无鞍的野马,看似桀骜不驯,若能顺性而御,必能足踏飞燕,行千里而不劳。

  • 程序的性能和效率永远是重要的。

  • 编程语言绝非象牙塔中之物,实乃技术和商业合力推动的结果。

  • Java的目的是让一种语言在多种平台上运行,而C#(.NET)的目的是让多种语言在一种平台上运行。Java重在语言,让语言向平台扩散;C#重在平台,让平台来凝聚语言。

  • 其实JavaScript作为一门动态语言,集过程式、对象式、函数式、事件驱动式、元编程等于一身,其强大和优雅绝对是超乎想象的。它宛如一只神奇的魔袋,乍看平淡无奇,却总能变出意想不到的宝贝。

  • 待友之道,贵在放大其优点而缩小其缺点,对待语言亦当如是。这既是一种态度,也是一种境界。
    得道者化腐朽为神奇,离道者化神奇为腐朽。凡事皆然。

  • VB最大的优点就是易学易用、上手快开发快,对非计算机专业人士尤其具有吸引力。当然简单易用不是没有代价的,随便拖放一个控件,就生成了一大堆代码,程序员的发挥余地自然受限,代码效率也难以保证。不过VB多用于前台的可视化开发,对运行效率要求相对较低,因此还是很有市场的。另外,VB进化到VB.NET后,从单纯的事件驱动式的编程范式发展为对象式、泛型式和函数式等多种范式,越来越强大、越来越严格,也越来越复杂,不再是人们戏称的‘玩具语言’了。

  • Delphi又称 Object Pascal,前身是教学语言 Pascal,VB的前身是入门语言 BASIC(Beginner’s All-purpose Symbolic Instruction Code),故而均具有易学易用的特点。

  • 引用Computerworld的评论:‘Delphi让复杂的事情变得简单,VB让简单的事情变得更简单’。
    然大道相通,难者亦易,易者亦难。

  • JavaScript本身是一门功能齐全、强大而优美的语言,只要严肃地对待它,它就是一门严肃的语言。
    语言的发展趋势一定是动静结合、刚柔并济。

  • Perl凝练晦涩,Python优雅明晰,Ruby精巧灵动,PHP简明单纯。

  • 或许优雅正是来自对细节和规范的重视吧。

  • Ruby背后最具特色的理念是:关注程序员使用语言时的感受超过语言本身的功能。通俗地说,兵器的称手比锋利更重要;文雅地说,应给予程序员更多的人文关怀。

  • 我们看到,每种编程语言都有其独特的惯例用法和哲学理念,它们与编程范式一道形成了语言的编程风格。体悟愈深者编程预感愈强,思维与语言愈交融无碍,渐从必然王国走向自由王国。

  • (抽象)不妨概括为:去粗取精以化繁为简;由表及里以异中求同。再精简些是作减法和除法。

  • 没有文档的 API 如同没有说明书的产品,除了实现者本人,其他用户是不敢轻易调用的。

  • 防御性编程采取的是“先小人后君子”的策略;契约式设计采取的是“先君子后小人”的策略。

  • 过滤缺点,抽取优点,西施就是这样炼成的。

  • 首先,抽象有角度之分。相同的实体(entity)经过不同的角度抽象,得到的模型(model)也会不同。就拿人这个实体来说,在拓扑学家眼里是三维连通集合,在理论力学家眼里是质点,在化学家眼里是碳水化合物。其次,抽象还有程度之别。抽象程度越高,细节越少,普适性越强。典型的例子如:从矩形到多边形,从多边形到一般形状。

  • 模型是抽象的结晶。

  • 它们看起来很基本很普通,但平淡之中见真功。

  • 抽象本身并不能解决问题,但却是解决问题的必经之路。通过抽象能简化和分解问题,使之更容易理解和控制,相应的解法也更具稳定性、普适性、重用性和可维护性。

  • 我感觉你在把程序当烟抽——光有烟嘴的接口,没有香烟的实现,的确不太过瘾。

  • 接口是纲,实现是目。纲若不举,目无以张。

  • Programming to an Interface, not an Implementation.

  • 接口与实现的分离,有利于开发时间的分离及开发人员的分离。

  • 抽象——尤其是数据抽象——才是OOP的核心和起源,尽管它们并非OOP的专利。没有抽象作基础,封装、继承和多态尽皆无本之木。只有贯彻ADT思想,设计出来的类才会是‘万人迷’:有优雅的外形——抽象,有丰富的内涵——数据,有鲜明的个性——类型。

  • 分析阶段(OOA)以对象(而不是过程)为中心,设计阶段(OOD)以接口(而不是实现)为中心,实现阶段(OOP)以数据(而不是算法)为中心。

  • 信息隐藏是一种原则,而封装是实现这种原则的一种方式。

  • 在融会贯通者的眼里,知识是大同小异的;在一知半解者的眼里,知识是小同大异的。此所谓:通,则大处圆融合一而小处各具其妙;不通,则大处千变万化而小处无所分别。

  • 访问控制不仅是一种语法限制,也是一种语义限制,也是一种语义规范——标有public的是接口,标有private的是实现,泾渭分明。

  • 如果一个方法返回了一个可变(mutable)域对象(field object)的引用,无异于前门紧闭而后门洞开。如何解决这个问题呢?这就需要用到前面提到的防御性编程,更具体地说是防御性复制(defensive copying),即返回对象的一个复制品,以免授人以柄(handle)。

  • 首先,普通的做法不代表是正确的。事实上,恕我直言:普通的程序员是不合格的,合格的程序员是不普通的。

  • 第一:设计很重要也很不容易——需要研究精神;第二,任何人都会犯错误,包括权威在内——需要批判精神。

  • 软件之软,体现在适应变化的能力。

  • 外行人常以为数学定理最重要,其实数学思想才是数学的精髓。

  • 编程的难点有两个主要方面:逻辑的复杂性和需求的变化性。

  • 过度设计会带来不必要的复杂和效率损失。

  • 应变能力强不等于代码不改变。能保证代码永远不变的软件有更好的归宿:要么退化为硬件,要么进化为人件——看看你的脑袋,有谁修改过它的源代码啊?不照样能随机应变吗?

  • 开闭原则(open/closed principle,简称 OCP),所谓开,指对扩展开放;所谓闭,指对修改封闭。也就是说,软件应该在模块的基础上进行扩展而不是修改。换言之,严格遵循开闭原则的软件,不应该修改老代码,只能增加新代码。

  • 软件的变化主要来自两个方面:一个以改善软件质量为目的的内在结构性变化;一个是以满足客户需要为目的的外在功能性变化。

  • 初级程序员的理想是为所欲为——能用编程解决一切问题;中级程序员的理想是尽善而为——追求最佳解决方案;高级程序员的理想是有所为有所不为——重在整体设计的选择,能抵制局部技巧的诱惑;最高理想是无为而无不为——无论宏观设计还是微观实战,均非刻意选择,却自然合度。

  • 敢于怀疑权威是可贵的,但如果没有研究精神作为基础,批判精神只会沦为牢骚“精神”。

  • 客户意识对一个程序员的重要性,丝毫不亚于对一个企业的重要性。

  • 千万不要为追求廉价的重用而轻易扩大接口范围,莫以自身之便而致客户之不便,莫以一时之便而致长期之不便。

  • 没有足够应变力的模块,不够资格被重用。

  • 如果意识到访问控制是对静态代码的控制,而不是对动态对象的控制,就不难理解它应该是以代码而非对象为边界的了。

  • 谨记一点:轻诺者,必寡信。每一个 public 类、每一个非 private 成员,都是一份承诺。在没有明确职责、没有准备承担变更后果之前,请采用最严格的访问控制。有了客户意识,才有接口责任感。

  • 作为服务的提供者,最重要的是讲诚信。首先,服务要有可靠性,不能阳奉阴违——即接口必须履行它的承诺;其次,服务要有稳定性,不能朝令夕改——即接口一经公开,不得随意变更。

  • 作为服务的享受者,最重要的是守规矩。

  • Unix有一个哲学:‘一个程序只做一件事,但要做好’。用在 OOP 上,则是:‘一个类只提供一套服务,但要完善’。

  • 编程毕竟是门实践活儿,完美无缺的设计如梦中佳人,可以追求却难以企及。

  • 访问控制只是个玻璃罩,能防止乱动的双手,却防止不了偷窥的双眼。它至多只能维护语法上的封装和信息隐藏,而语义上的封装只有靠规范来维护。对程序员而言,前者是一种须要学习的知识,后者是一种须要培养的素质。

  • OOP 系统是对现实社会的模拟,这不仅反映在表现形式上,还反映在行为准则上。它们都是由一些相互交流、相互作用的个体对象组成,个体的品性、行为、能力等参差不齐。为实现合作共赢,所有个体都应恪守‘严以律己、宽以待人’的原则:作为服务的主题,应保证服务的信誉和品质;作为服务的客体,应遵守服务的规则和规范。唯其如此,无论个体对象还是整体系统,方能保持和谐而不失活力、稳定而不惧变化。

  • 不要问系统能为你做什么,而要问你能为系统做些什么。

  • 要求只能更少,承诺只能更多。

  • 知识是水,越近源头越是鲜活。

  • 编程是这样一种游戏,既要进攻得力——保证有意而为之的正面效应,又要防守得当——控制无意而随之的负面效应。

  • 软件设计的四字要诀:外静内动。

  • 外静指保持外部的接口不变,内动指允许内部的实现变动。大到库、框架、架构等的设计,小到具体的函数、类等的实现,概莫能外。在规范抽象中,静的是功能规范,动的是实现细节;在数据抽象中,静的是 API 接口,动的是接口实现;在多态抽象中,静的是 interface 接口,动的是实现类;在非虚接口模式中,静的是非多态的对外接口,动的是多态的对内挂钩。(挂钩就是 hook,也就是 callback 回调。借助多态,处于底层的父类调用了处于高层的子类的方法,不正是一种回调么?)

  • 关于继承的用法,可概括为十二字方针:‘提倡接口继承,慎用实现继承’。

  • 实现继承至少有3处用武之地:希望访问基础类的 protected 成员;希望覆盖基础类的方法,并且难以用合成来变通;希望成为基础类的子类型。

  • 更实际的建议是,每当为继承与否而举棋不定之时,问自己两个问题:采用合成是否会遇到无法克服的困难?基础类是否专门为继承而设计?

  • 继承是一种静态、显性的关系,合成是一种动态、隐形的关系。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,951评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,606评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,601评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,478评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,565评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,587评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,590评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,337评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,785评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,096评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,273评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,935评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,578评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,199评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,440评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,163评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,133评论 2 352

推荐阅读更多精彩内容