👋 Welcome to my blog

Hi, I’m Mark. A software development engineer living in Shenzhen, China, focused on building AI-enabled projects. I believe in learning by doing and building in public.

Spring Boot:从开发到远程部署指南

项目环境 操作系统:Mac OSX Catalina 10.15.1 IDE: IntelliJ IDEA CE(社区版) JDK版本:推荐JDK 8或JDK 11(LTS版本) Maven版本:3.6+(IDEA自带,通常无需单独安装) 注意: IDEA社区版不包含Spring Initializr集成和企业版的Spring支持,但我们可以通过Spring Assistant插件获得类似体验! 创建项目 安装Spring Assistant插件 为什么需要这个插件? IDEA社区版本默认不支持Spring Initializr,而Spring Assistant插件可以让社区版用户也能享受到快速创建Spring Boot项目的便利,功能几乎与企业版一致! 在官方插件市场搜索Spring Assistant并下载 在Preferences > Plugins设置中,选择**Install Plugin from Disk…**安装下载好的插件zip包 安装完成后重启IDEA,插件就生效了! Tips: 如果网络不好下载失败,可以使用IDEA的HTTP代理设置(Preferences > Appearance & Behavior > System Settings > HTTP Proxy)配置代理。 使用插件新建Maven项目 选择Spring Assistant按步骤新建项目,这个过程和使用Spring Initializr官网基本一致。 Step 1: 选择项目类型和Spring Boot版本 Type: 选择Maven Project(也可以选Gradle,看个人喜好) Language: Java Packaging: Jar(推荐,方便部署) Java Version: 8或11(根据你安装的JDK版本选择) Spring Boot Version: 选择稳定版本,避免SNAPSHOT版本 Step 2: 配置项目元数据 ...

January 28, 2020

孵化Twitter:一个关于友情、创业与背叛的故事

Twitter创始人Jack Dorsey的第一条推文 雨夜故事 像往常一样,杰克·多西带着醉意钻进友人诺阿的车里,安静地坐在那儿。 诺阿的播客公司Odeo在当天乔布斯宣布新版iTunes将加入播客功能便被判了死刑。这就是创业的残酷:一个巨头的产品发布会,就能让你数年的心血瞬间归零。诺阿知道,在科技的世界里,没有什么是永恒的,只有不断的变化和被颠覆。 跟以往醉酒的夜晚不太一样的是,那晚下着大雨,大街上空无一人。整个世界仿佛只剩下诺阿和杰克·多西,诺阿想起了艾琳和自己失败的婚姻,想到与埃文破碎的友谊,孤独感让他感觉到窒息。人到中年的创业者,常常在这样的夜晚感受到双重的失败——事业和生活都在崩塌,而你不知道该向谁诉说。 诺阿开始跟杰克·多西倾述过去的种种失意,询问杰克·多西想做什么,渴望从杰克·多西的想法中找到挽救公司的点子。绝境中的人,总是会抓住任何一根稻草。 杰克·多西提到6年前自己想到的"状态"的概念:你可以告诉朋友自己正在听什么音乐或者告诉大家你正在工作。两个人就这样围绕"状态"的概念聊来聊去,突然诺阿像被什么击中了一样,大喊一声:“有了!“诺阿觉得杰克·多西关于"状态"的创意,能够把那些不在身边的人和自己联结在一起,让人们相互联系而不再感觉孤独。两个人越聊越兴奋,后来决定第二天把这个创意告诉公司其他人。 这个雨夜,成为了互联网历史上最重要的夜晚之一。一个失败者的绝望,一个梦想家的执念,在酒精和雨水的催化下,碰撞出了改变世界的火花。Twitter的诞生,源于人类最本质的需求——连接与被看见。 第二天诺阿一到公司便把昨晚跟杰克两个人关于"状态"的想法告诉了埃文和比兹,眼看着Odeo公司一步步走向死亡,埃文终于下决心要尝试杰克·多西"状态"的创意。诺阿一直想着为这个新项目取一个好听的名字,诺阿翻弄着词典,突然一个词让他会心一笑,当他把这个名字发给埃文、比兹和杰克·多西时,大家都觉得这个名字是最好的,这个名字就是Twitter。 创立Twitter 在埃文的授意下,杰克·多西成为新项目的负责人,他们很快开发出第一个初级的版本。2006年3月21日上午11:50,杰克·多西发布了第一条推文:刚刚创建了我的Twitter。Twitter终于从一个关于"状态"的创意变成了现实。 这条看似平淡无奇的推文,开启了人类表达方式的一次革命。140个字符的限制,反而激发了人们更精炼、更即时的表达欲望。 2007年2月Twitter独立成公司,杰克·多西成为公司的领导,由于他之前只是一个低级别的程序员,没有管理经验,Twitter内部一片混乱。埃文和杰克·多西的产品理念也发生了分歧,埃文认为Twitter是一个告诉人们这里正在发生什么的信息网络,而杰克·多西坚持Twitter是一个告诉他人自己正在做什么的社交网络。 这个分歧看似微妙,实则关乎产品的本质和未来。一个关注"此时此地”,一个关注"我与世界”。最终,Twitter的演化证明了两者都是对的——它既是社交网络,也是信息网络,这种双重属性正是Twitter的独特价值所在。但在创业早期,理念的分歧往往成为权力斗争的导火索。 2007年3月11日,在西南偏南音乐节上,Twitter入围了最佳创业公司。埃文、比兹、杰克·多西在走廊上设置一块51寸的等离子屏幕,向大家展示Twitter,并在上面刷新推文和评论,人们成群结队地过来围观,看着自己的头像名字评论出现在大屏幕上,西南偏南音乐节之后,Twitter开始大受欢迎。 那个屏幕前的场景,体现了Twitter最核心的魔力:每个人都渴望被看见,被听见。当你的声音出现在大屏幕上,当你意识到自己的话语可以传播到整个世界,那种感觉是无与伦比的。这不仅仅是技术的胜利,更是对人性深层需求的洞察。 埃文一直在用自己的钱维持Twitter的日常运营,当他开始考虑外部融资时,他任命杰克·多西为Twitter的CEO,拥有公司20%的股份,自己则保留70%的股份,比兹和古德曼分获3%。Twitter开始变得炙手可热,雅虎、Facebook等巨头都对这个新生公司抛来橄榄枝,渴望收购Twitter,最后都被埃文拒绝了。埃文、比兹,他们都希望Twitter保持独立,维护他们关于人们拥有发布新闻自由和保护个人隐私的理念。 这个决定需要巨大的勇气。在硅谷,很多创业者梦想的就是被巨头收购,套现离场。但埃文选择了一条更艰难的路——为了理想,拒绝诱惑。这种选择,在后来的故事中也变得讽刺:当你为理想放弃金钱,最终却被那些更看重权力的人挤走。 然而,随着越来越多的人涌入网站,Twitter的服务器开始脆弱不堪,杰克·多西在解决服务稳定性和公司管理方面显得无能为力。在下一轮融资后,新成立的董事会决定让杰克·多西走人,以挽救内部杂乱无章的Twitter,埃文成为了新一任CEO。埃文连续创业者的经历,让他把Twitter带上了正轨,然而Twitter的盈利收入却一直是零。埃文也有自己的问题,喜欢招朋友到自己的公司。后来在众人的圈套中被排挤出Twitter,而埃文招进来的好友迪克却成了公司的第三任CEO,在迪克的带领下,Twitter开始产生收入,2013年11月7日,Twitter在纽交所敲钟,当日市值245亿美金。 这个过程充满了创业公司的典型困境:创意者未必是好的管理者,理想主义者未必懂得商业化,而善良的人往往斗不过有心机的人。Twitter的成功是集体智慧的结晶,但荣耀和财富的分配,却从来不是按贡献来的。 友情与背叛 《孵化Twitter》整本书都贯穿着讲述几个朋友之间友情与背叛的故事。 埃文与诺阿的友情让Odeo得以诞生,后来又因为公司主导权的问题,作为投资人的埃文与创始人诺阿友情破碎;诺阿、杰克·多西的友情,让那个雨夜带来了一场改变世界的谈话,而后杰克·多西又暗地里让埃文把诺阿排挤出公司。埃文、比兹、杰克·多西的友情,让Twitter从一个创意变成一个网站,到后面成为一个广受欢迎的产品。然而,公司的理念和控制权最终还是让埃文和杰克·多西走向决裂。 在利益面前,友情是脆弱的。更准确地说,当权力、金钱和理念产生冲突时,人性中自私、贪婪、虚荣的一面就会暴露无遗。那些曾经并肩作战的战友,会因为股权分配、CEO位置、媒体报道中谁是"真正的创始人"而反目成仇。 当埃文取代杰克·多西成为公司CEO,杰克·多西一直对埃文耿耿于怀,到处对媒体宣称自己是Twitter唯一的创始人,后面甚至联合众人把埃文从CEO的位置拉下来,而埃文的好友迪克取代了他。说实话,看到这里,之前对杰克·多西的好感降了几分,杰克·多西的一些行为让人觉得有点心机boy,但最终杰克·多西还是"复仇"成功。 这种"复仇",是对友情最大的讽刺。杰克·多西后来重返Twitter担任CEO,在公众场合被塑造成Twitter的唯一创始人和救世主,而那些真正推动Twitter诞生和发展的人——诺阿、埃文、比兹——要么被遗忘,要么被边缘化。历史是由胜利者书写的,商业史更是如此。 书中有一个细节让我印象深刻:当Twitter即将上市时,杰克·多西坚持要在招股书中把自己列为唯一的创始人,而埃文和诺阿的名字则被排在次要位置。这不仅仅是虚荣心,更是对历史的篡改。但在资本市场上,没有人在乎真相,大家只在乎故事是否足够动听,CEO是否足够有个人魅力。 创业维艰,且行且珍惜。但更艰难的是,当你和朋友一起创业,如何在利益面前保持初心,如何在权力斗争中守住良知。大部分时候,我们做不到。 主要人物评价 埃文:一个近乎乌托邦的理想主义者,不管是blogger还是Twitter,到后来创立medium,埃文一直在改变媒体行业,因为他一直在践行内心关于新闻自由、个人隐私的信念。与信念相比,金钱没有那么重要。这是一个了不起的连续创业者,内心纯净,渴望用自己的理念改变这个世界。 埃文是那种在硅谷越来越稀缺的创业者——他不是为了IPO而创业,不是为了站在聚光灯下而创业,他是真正相信技术可以让世界变得更好。但他的悲剧在于,他太善良了,善良到不适合这个残酷的商业世界。他信任朋友,却被朋友背叛;他坚持理想,却被投资人和董事会抛弃。当他离开Twitter时,没有愤怒,没有反击,只是平静地离开,然后继续创立Medium,继续追求他的理想。这种人格,让人既敬佩又心疼。 比兹:善良、朴实、有情有义,无论是杰克·多西还是埃文被人排挤,都是第一个站出来维护好友。在维护新闻自由、个人隐私方面有着跟埃文一样的价值观。这样的人值得深交一辈子。 比兹是整个故事中最令人尊敬的人。他没有杰克·多西的野心,没有埃文的理想主义,他只是一个踏实做事、对朋友忠诚的人。在硅谷这个充满背叛和权谋的地方,比兹像一股清流。当杰克·多西和埃文争夺公司控制权时,比兹选择站在埃文一边,因为他知道谁是对的。当埃文被排挤出局时,比兹也选择离开。他用行动证明,有些东西比金钱和权力更重要——那就是原则和友情。 诺阿:本书中一个悲剧的人物,推动了Twitter的立项,想出Twitter这个名字,然后早早被排挤出局,后面被完全抹掉Twitter创始人的身份和早期的贡献。我个人觉得,诺阿是一个有想法、有执行力的人,为人过于耿直,脾气暴躁,性格决定命运吧。 诺阿的故事是最让人唏嘘的。如果没有那个雨夜,没有他和杰克·多西的谈话,Twitter可能根本不会诞生。但最终,他什么都没有得到——没有股份,没有荣誉,甚至连历史的一个脚注都算不上。他的悲剧在于,他是一个想法的催化剂,但不是一个好的执行者和政治家。在创业公司里,有想法是不够的,你还需要懂得如何保护自己的利益,如何在权力斗争中站稳脚跟。诺阿不懂这些,所以他成了第一个被牺牲的人。 杰克·多西:自由散漫的文青,创意迸发,因为朋友一次糟糕的支付经历而产生创办Square移动支付的想法。情商高,擅于个人品牌经营。不过看完本书,不那么喜欢他了。 杰克·多西是一个复杂的人物。他无疑是有才华的——Twitter的核心创意来自他,Square的成功也证明了他的商业能力。但他也是有野心和心机的。他精心打造自己的公众形象,把自己塑造成一个禅意十足、追求极简主义的科技领袖。他懂得如何在媒体面前讲故事,如何让自己成为Twitter的唯一代言人。但在这个过程中,他抹去了其他人的贡献,背叛了曾经的朋友。 这让我想起一句话:成功者不一定是最有才华的人,而是最懂得如何运用权力和叙事的人。杰克·多西深谙此道。 对创业的一些思考 Alan Kay说过:预测未来最好的方式就是去实现它。每个人年轻的时候都多多少少抱着改变世界的想法,而创业是一个很好的实现方式。如今创业大环境良好,尤其是处在互联网这种不断涌现创业公司的行业,特别能感受到那种激情。自己也经常会有一些自认为很棒的想法,和朋友同事一起yy,想要做一点不一样的事情出来,当然也会因为生活压力幻想着做一款能被收购或者赚钱的产品。 但《孵化Twitter》这本书让我重新思考创业的本质。创业不仅仅是关于技术、产品、商业模式,更是关于人性、权力、欲望。当你和朋友一起创业,你们在车库里熬夜写代码时,你们觉得自己是在改变世界。但当公司有了第一笔融资,当媒体开始报道,当投资人进入董事会,一切都变了。 你开始发现,朋友之间对公司未来方向有分歧,对股权分配有不满,对谁应该当CEO有争执。那些曾经一起喝酒聊天的兄弟,开始在董事会上争吵,在媒体面前互相攻击。你开始质疑,这还是当初那个纯粹的梦想吗? 但内心觉得更重要的还是为社会创造价值,而不是开一家公司赚钱,就像埃文一样,创业者应该内心纯净,不要对金钱抱有太多想法,人应该为自己的认知和价值观而活着,创业也是为了用自己的理念让世界变得更好。而当你坚持做有价值的事情,金钱会随之而来。商业价值是你创造的价值的一部分。 但现实往往比理想残酷。埃文坚持理想,却被扫地出门;杰克·多西玩弄权术,却成为最大赢家。这个世界真的奖励理想主义者吗?还是奖励那些最懂得如何获取权力的人? 我想,答案可能是:在不同的时间维度上,奖励的对象不同。短期来看,权术和野心可能让你赢得一城一池;但长期来看,真正有价值的创造才能经得起时间的检验。Medium可能没有Twitter那么耀眼,但它代表了埃文始终如一的理想。这种坚持,本身就是一种胜利。 Twitter的故事还告诉我们:创业公司的创始人团队,一定要在早期就建立清晰的股权结构和决策机制。很多创业公司的失败,不是因为产品不好,不是因为市场不对,而是因为创始人内讧。当友情和利益冲突时,只有明确的规则才能保护每个人。 同时,我也意识到,选择创业伙伴,比选择创业方向更重要。比兹和埃文的友谊,能经受住权力和金钱的考验,这种友谊比任何成功都珍贵。而那些在困难时并肩作战,在成功时背后捅刀的人,即使赢得了全世界,也输掉了自己的灵魂。 创业维艰,但更难的是,在这个过程中保持初心,守住良知,善待那些曾经和你一起战斗的人。Twitter改变了世界,但它诞生和发展的故事,也让我们看到了人性最光辉和最阴暗的一面。 尾声 合上这本书,我在想,如果时光倒流,诺阿、埃文、比兹、杰克·多西能否做出不同的选择?如果他们能够坦诚相待,如果他们能够在利益面前保持理智,Twitter的故事会不会有一个更完美的结局? 但这些假设没有意义。因为人性就是人性,欲望就是欲望。当足够的金钱和权力摆在面前时,很少有人能够保持清醒。我们能做的,只是从这些故事中学习,反思,然后在自己的人生中做出更好的选择。 Twitter依然是伟大的,它确实改变了世界。但那些被遗忘的人,那些被背叛的友谊,那些破碎的理想,也值得被记住。因为只有记住这些,我们才能明白,真正的成功不仅仅是市值多少,不仅仅是你站在多高的位置,而是你用什么样的方式到达那里,你在这个过程中是否守住了自己的原则,是否善待了那些陪你一起走过黑暗的人。 创业如此,人生亦如此。 -- 写于台风苗柏肆虐的凌晨

June 13, 2017

LLVM探究

iOSer都知道LLVM(Low Level Virtual Machine)是Xcode自带的编译器,而在LLVM诞生之前,Apple一直依赖另一个开源编译器GCC。随着Apple收购乔布斯的创业公司NextStep,面向对象语言Objective-C正式成为Apple官方的开发语言。由于当时GCC社区开发者未能及时支持OC的新语言特性,加上GCC开发者与Apple在编译器支持模块化调用方面存在分歧,最终让Apple选择分道扬镳,并转头拥抱了另一个开源项目LLVM。 这场"分手"的深层原因其实更加复杂:GCC的GPL许可证要求任何基于GCC的修改都必须开源,这对于Apple这样重视知识产权的公司来说是难以接受的。而且GCC的代码库经过20多年的发展,已经变成了一个高度耦合、难以扩展的庞然大物。Apple需要的是一个能够快速迭代、支持新语言特性、并且可以深度集成到IDE中的现代化编译器。 LLVM起源于2000年,是由美国UIUC大学的Chris Lattner博士发起,Chris Lattner也是后来的Swift之父。最初LLVM是Chris Lattner的硕士论文项目,旨在构建一个"终身代码优化系统"(Lifelong Program Analysis & Transformation),可以在编译时、链接时、运行时甚至闲置时对代码进行持续优化。这个大胆的想法吸引了Apple的注意。 在Apple的资助下,LLVM得到了飞速的发展。2005年,Apple雇用了Chris Lattner,并组建了专门的LLVM开发团队。同时始于2007开发的Clang,因编译速度快、占内存少、错误诊断信息友好、代码质量高,最终替代笨重的GCC成为LLVM的新前端。Clang的编译速度比GCC快3倍,内存占用减少5倍,这对于大型项目的编译体验提升是巨大的。更重要的是,Clang从设计之初就考虑了IDE集成,提供了丰富的API供开发工具调用,这为Xcode的代码补全、实时错误检测、重构等功能提供了基础。 LLVM和Clang不断完善功能的同时,也在Apple的MacOS和Xcode IDE中得到工业级的应用和推广。2013年,Apple正式宣布废弃GCC,LLVM/Clang成为Xcode的默认编译器。在与Apple的相互成就中,LLVM一跃成为了最领先的开源编译器之一,目前已被Google(用于Android NDK)、Intel、AMD、NVIDIA等科技巨头广泛采用。 LLVM设计理念 与GCC不同,LLVM设计之初就注重模块化和可扩展性,这是一种设计哲学的根本性差异。比如LLVM的优化器,它支持开发者选择Pass的类型和执行顺序,提供基于模块或库的可组装能力。每个Pass都是一个独立的转换单元,可以单独测试、单独优化、单独替换。相对之下,GCC的优化器则是由大量高度耦合的代码组成,很难进行拆分和选择性使用。GCC的优化passes之间存在隐式依赖,修改一个pass可能影响其他多个pass的行为。 模块化的设计理念还体现在LLVM的三段式架构设计中:LLVM通过Libraries collection完美实现了传统编译器想要的编译前端、编译优化器和编译后端三个核心部件,并且通过中间表示(IR)作为各个部件之间的接口。这种设计带来了几个关键优势: 编译前端(Frontend):负责将各种高级语言源代码转换为LLVM中间表示(IR)。不同的语言可以有不同的前端实现,比如Clang处理C/C++/Objective-C,Swift前端处理Swift语言,Rust前端处理Rust语言。前端的主要任务包括词法分析、语法分析、语义分析、类型检查,最终生成抽象语法树(AST)并将其降低(Lower)为LLVM IR。 编译优化器(Optimizer):对中间表示进行各种优化,以提高代码性能。LLVM的优化器采用Pass-based架构,每个Pass负责一种特定的优化。优化可以分为多个层次:函数内优化(Intra-procedural)、过程间优化(Inter-procedural)、全局优化(Whole Program)。LLVM提供了超过100个内置Pass,并且支持用户自定义Pass。 编译后端(Backend):将优化后的中间表示转换为目标机器的代码。后端需要完成指令选择(Instruction Selection)、寄存器分配(Register Allocation)、指令调度(Instruction Scheduling)等任务。LLVM通过TableGen工具和目标描述文件(.td)来描述不同架构的特性,使得添加新的目标平台变得相对容易。 通过三段式的架构设计,LLVM可以通过灵活切换不同编程语言的前端实现,转化成通用的中间表示,并通过编译后端进行本机编译或者交叉编译适配成目标机器代码,从而实现了高可扩展性。LLVM能够快速支持各种新的编程语言,主要得益于三段式架构的高可扩展性。 这种架构的数学模型可以表示为:如果有M种源语言和N种目标架构,传统编译器需要M×N个编译器实现,而LLVM只需要M个前端+N个后端。这种O(M+N)的复杂度远低于O(M×N),大大降低了开发和维护成本。 更重要的是,LLVM IR作为中间层,提供了一个稳定的契约接口。前端开发者不需要了解后端的实现细节,后端开发者也不需要了解各种语言的语法特性。这种解耦使得编译器的各个部分可以并行开发和演进。 LLVM架构 传统编译器的三段式架构: 编译前端(Frontend)通过词法、语法、语义一系列分析,构建抽象语法树(AST),AST可以转换成某种中间表示(IR),作为编译优化器(Optimizer)的输入。编译优化器负责对中间代码进行优化,比如无用代码消除(Dead Code Elimination)、冗余指令合并(Common Subexpression Elimination)、函数内联(Function Inlining)等,以提升代码运行时性能。编译优化器输入IR,最终输出是优化过的IR。经过编译优化器(Optimizer)优化后的IR经过编译后端(Backend)转换成目标平台的机器码。 这个过程中,词法分析(Lexical Analysis)将源代码转换为token流,语法分析(Syntax Analysis)根据语言的文法规则构建语法树,语义分析(Semantic Analysis)进行类型检查、作用域解析等工作。这些步骤在编译原理中被称为编译器的"前端工作"。 通过这种组件化的设计,任何编程语言的编译器只要实现了上述3个部件,就能够把对应语言编写的源代码编译成目标平台可运行的机器代码。 于是支持多语言多平台的新架构被提出: 上述新架构支持不同的编程语言生成统一的中间表示(IR),新语言只用实现一个新的编译前端(Frontend),编译优化器(Optimizer)和编译后端(Backend)则可以复用。这种架构的核心思想是"一次编写,多次复用"(Write Once, Reuse Many Times)。 在现存的编译器中,JVM、.Net虚拟机提供了定义良好的中间表示字节码,理论上任意语言只要实现编译前端,支持把源代码转成字节码就可以使用JVM或者.Net虚拟机。但是运行时强制JIT编译、GC等机制并不适合像C这样的系统级编程语言。JVM和.Net的设计目标是托管环境(Managed Environment),它们假设有一个运行时系统来管理内存、处理异常、提供安全检查。这对于C/C++这种需要手动管理内存、直接操作硬件的语言来说是不合适的。 而另一个新架构的代表GCC,则因为早期设计中存在的耦合问题比如编译后端(Backend)需要遍历编译前端(Frontend)的AST生成调试信息,编译前端(Frontend)生成编译后端(Backend)的数据结构,以及全局变量和数据结构的滥用,导致三大编译组件耦合,代码复用性较差。GCC的这些设计缺陷是历史包袱,很难通过重构来解决,因为数百万行的代码已经基于这些假设编写。 LLVM在实现三段式架构中,汲取了GCC的教训,在设计中采用了严格的模块化设计,整个编译器由一系列可复用的库组成。这些库包括: libLLVMCore:核心IR和基础数据结构 libLLVMAnalysis:各种分析pass(控制流分析、数据流分析、别名分析等) libLLVMTransform:各种优化pass(常量折叠、循环优化、内联等) libLLVMCodeGen:代码生成框架 libLLVMTarget:目标机器描述 libLLVMSupport:通用工具和基础设施 每个库都有清晰的接口定义和职责划分,库之间的依赖关系是单向的、非循环的。这种设计使得开发者可以只链接需要的库,减少最终可执行文件的大小。例如,如果你只需要分析LLVM IR而不需要生成机器码,就可以只链接分析相关的库。 LLVM的架构体现了软件工程中的几个重要原则: 关注点分离(Separation of Concerns):每个组件只关注自己的职责 接口与实现分离:通过IR作为稳定的接口,隔离前端和后端 开放封闭原则:对扩展开放(可以添加新的Pass、新的前端、新的后端),对修改封闭(不需要修改核心代码) LLVM IR LLVM IR(Intermediate Representation)是LLVM整个架构的核心,它是一种强类型的、SSA(Static Single Assignment)形式的低级虚拟指令集。LLVM IR有三种等价的表示形式: ...

September 22, 2016 · Mark