首页 >>  正文

c++case

来源:baiyundou.net   日期:2024-07-09

鞭牛士 4月16日消息,大部分互联网产品的版本更新周期为1个月,更新较为频繁的产品如Facebook,在部分海外市场可以做到每周更新一版。很难想象,有一款产品在过去两年时间,发布了上千版,平均每天发布1.4 次,这款产品就是Motiff。


随着人机界面交互的演进,UI 设计工具的时代也在悄然更迭。Photoshop 曾是网页设计师人手必备的像素时代设计工具;后来,Sketch 结合矢量设计,取代 Photoshop 成为专用界面设计工具;而后,Figma 横空出世,将设计工具带入协同时代。而 Motiff 期待成为下一个时代——AI 时代的界面设计引领者。


 界面设计曾经历三个时代变迁,如今进入 AI 时代

 

Motiff 是一款 AI 时代的专业界面设计工具,其核心功能之一是在线编辑器。与其他同类工具不同,Motiff 的在线编辑器一方面要保证基础编辑器的性能,满足设计师日常精细化的设计需求、团队的协作需求,另一方面要融入 AI 能力,为设计师和设计团队提效。


可以说,Motiff 团队正在打造的是全世界最复杂的高性能编辑器,而两年发版上千次背后的技术实践就是主干开发。


Motiff 为什么选择了主干开发?主干开发为 Motiff 带来哪些关键成果?4月13日,在Qcon 全球软件开发大会上,Motiff 研发负责人张宇辰对此进行了解答。


张宇辰演讲现场


主干开发:在多重不确定性中高频发布且保证质量


张宇辰介绍,Motiff 作为一款 AI 时代设计工具,在开发过程中存在非常多的特殊性:首先,Motiff 需要进行测试的 Case 空间非常大,设计师需要在 Motiff 的画布上随意发挥,这意味着用户的操作路径和数据都无法穷举;其次,Motiff 的在线协同功能要求它必须能接受来自数据驱动的变更;此外,Motiff 是一个具备多个 AI 功能的生产力工具,AI 的加入也为产品带来更多的复杂和不确定性。


因此,如若采用传统的“分支开发+精细化发布”模式,则容易导致 Bug 集中出现,造成资源浪费并降低整体开发效能。


 Motiff 编辑器界面


为了解决这一难题,Motiff团队最终采用了“主干开发 + 自动化测试”的方案,保证了 Motiff 在实现高频发布的情况下,仍然很好地保证了软件质量:


性能高:设计师在编辑器上的日常操作不卡顿,画布渲染流畅快速,Motiff 的大部分常用操作性能甚至好于 Figma;


稳定性强:在每周使用 1000 分钟编辑器的情况下,年平均崩溃次数不超过 1 次;


基础功能全:仅两年,Motiff 就完成了组件实例、原型、研发模式、矢量网络等编辑器的核心功能开发;

AI 能力强大:编辑器的各种编辑能力都对 AI 开放,上线了 AI 设计系统、AI 布局、AI 魔法框等功能,未来还将有 AI 复制等新功能上线,为设计流程提效。


“Motiff试图比 Figma 做得更好”


据了解,Motiff 团队用主干开发驱动了自动化测试、高频提交、部署发布分离、特性开关等多种持续集成/持续交付实践,这一系列实践起到了重要作用。在自动化测试过程中,工程师有机会提前发现质量问题、避免返工,提高团队效率。由于 Motiff 有大量的自动化测试 Case,每次合并代码前,这些 Case 会在不同的特性开关组合下被执行,从而确保有效覆盖用户的各种场景。


在做自动化测试的过程中,Motiff 团队走过不少弯路,实验过数种方法,例如尝试从最小粒度的单元测试开始写代码。但这一实践失败了,因为单元测试经常难以抵抗重构。为了提升编辑器的性能,Motiff 曾数次进行代码的大规模重构,到如今,有些大规模的重构还在 Motiff 内部进行中。


 为提升编辑器性能,Motiff 进行多次大规模代码重构


如果希望测试变得稳定,就需要寻找一些稳定的接缝。对于 Motiff 来说,这些接缝是用户的操作场景。“这些场景是如此的稳定,以至于我们第一个用户测试中被成功创建的矩形测试 Case,在经历了两年的时间,无数次的大大小小重构后,仍然存活着,为工程师团队默默守护着发布质量”,张宇辰介绍道。


Motiff 的项目中存在三种不同的接缝,因此有三种不同的测试框架,其中包括 C++ 的单元测试、TypeScript 的单元测试,以及 Cypress 进行的端到端(E2E)测试。而尽管 E2E 测试看似美好,可以模拟真实用户的操作和环境,但它的成本高昂。E2E 测试不仅每次运行也会消耗大量的 CI 机器时间,而且通常不稳定,很容易因为网络抖动、服务端问题或浏览器问题而失败——因此,Motiff 团队采取了一套治理策略,包括讨论是否能把 E2E 测试转移到 C++ 或者 TypeScript 测试,以及标记不稳定的测试并防止它们阻塞流水线的运行。


在自动化测试的实践下,Motiff 完成了数次大规模代码重构,并且在设计师常用的文件加载、页面切换、文件导入导出等操作场景中,实现了对 Figma 的超越。


 在设计师常用操作中,Motiff 编辑器的性能表现基本超越 Figma

 

同时,Motiff 还在持续自研渲染引擎,期待将设计师在画布区的操作体验提升至更高水平。“Figma 开创了全球最高性能的在线编辑器,Motiff 试图在这件事上做得更好”,张宇辰说道。


特性开关,让功能开发更高效


自动化测试并非万用灵药,任何测试手段都无法保证 100% 发现所有问题。为了进一步降低线上问题的风险,Motiff 在自动化测试的基础上,引入了特性开关这一实践。


通过特性开关隔离代码路径,Motiff 让未成熟的变更可以提交到主干上,而不必担心会影响到线上的正常运行——特性开关是基于代码逻辑执行的调整,可以在运行时动态修改。


结合 Feature Switch 开关,Motiff 完成了研发模式(Dev Mode)的开发上线。张宇辰介绍说,“研发模式基本上对于所有编辑器的用户交互都做了重新定义,在传统的多分支开发模式下,这样大的功能发布,往往要经历非常痛苦的合并过程。而在 Motiff,我们通过 Feature Switch 隔离了不稳定代码,提升了集成频率,降低了单次合并的风险,在两个月时间开发完了整个功能,同时对用户没有产品体验的影响,在过往的实践中是很难想象的”。


 Motiff 的研发模式的开发对所有编辑器的用户交互做了重新定义

 

研发模式的上线,将完善 Motiff 产品在工作流程中不同工种之间的协作问题,使之不仅是一个为设计师提效的产品界面设计工具,还能便利设计师与前端工程师的协作,真正成为提升团队效能的生产力工具。

自动化测试和特性开关这两种实践,使得 Motiff 的开发流程更为高效、有序,而且在确保代码质量的同时,还大幅降低了应对缺陷的成本和风险。


虽然已取得众多成果,但对于 Motiff 团队来讲,打造一个全世界最复杂的高性能编辑器的路还很长。除了在自研渲染引擎上的努力,在将 AI 能力融入编辑器的同时,克服 AI 的加入带来的新的不确定性,对 Motiff 团队来讲依然是要持续攻克的难题——在原先的自动化测试中,工程师往往是给定一个确定的输入,系统会据此产生一个确定的输出。但设计师在使用 AI 功能后得到的结果是不确定的,这对自动化测试同样是挑战。


目前,软件行业进入了全新的 AI 时代,Motiff 将 AI 能力融入产品中,开发出了 AI 设计系统、AI 布局、AI 魔法框等 AI 功能,引起行业内外众多人的关注与讨论。未来,Motiff 团队还将结合设计师的实际使用场景为用户带来更多 AI 功能。

","gnid":"994732f170e0e3a5f","img_data":[{"flag":"2","img":[{"desc":"","height":"467","title":"","url":"https://p0.ssl.img.360kuai.com/t01e3529ca123e1da14.jpg","width":"830"},{"desc":"","height":"467","title":"","url":"https://p0.ssl.img.360kuai.com/t0101273bce9b36b24c.jpg","width":"830"},{"desc":"","height":"467","title":"","url":"https://p0.ssl.img.360kuai.com/t0187109225c09018d0.jpg","width":"830"},{"desc":"","height":"467","title":"","url":"https://p0.ssl.img.360kuai.com/t015efd932d35eabebc.jpg","width":"830"},{"desc":"","height":"467","title":"","url":"https://p0.ssl.img.360kuai.com/t0112329f89a1a0f18f.jpg","width":"830"},{"desc":"","height":"554","title":"","url":"https://p0.ssl.img.360kuai.com/t01d3131f39027366c9.jpg","width":"831"}]}],"original":0,"pat":"zzc,art_src_1,sexf,sex4,sexc,fts0,sts0","powerby":"pika","pub_time":1713250076000,"pure":"","rawurl":"http://zm.news.so.com/1f4c895f5fb2833e90d6b7c77a2e359e","redirect":0,"rptid":"8e214e8425ab735b","rss_ext":[],"s":"t","src":"鞭牛士","tag":[],"title":"Motiff:AI时代,打造全世界最复杂的高性能编辑器

苏逸晴2640c++ switch case 的用法 -
臧霄砌15933764733 ______ switch (x/1000) { case 0: cout << x << endl; break; case 1: cout << x * 0.9 << endl; break; } 说明: switch语句的执行 1,对switch中的控制表达式进行求值.这里是对x/1000求值,如果0<=x<1000,求值结果为0,如果1000<=x<2000,结果为...

苏逸晴2640C++怎么使用case中给出的数值 -
臧霄砌15933764733 ______ main(){ int a; printf("input integer number: "); scanf("%d",&a); switch (a){ case 1:printf("Monday\n"); case 2:printf("Tuesday\n"); case 3:printf("Wednesday\n"); case 4:printf("Thursday\n"); case 5:printf("Friday\n"); case 6:printf("...

苏逸晴2640c++中case语句中能用什么语句? -
臧霄砌15933764733 ______ switch(变量){case 1;case 2;case 3;}变量 与case后面相同就会跳到那里. 其实 一两句说不清楚.你找个全面的书,或电子书.

苏逸晴2640C语言 c++ 运行程序后 输出的结果是什么 case do while -
臧霄砌15933764733 ______ case 如果没有break,那么就会从当前case执行遇到break或者switch循环结束.比如以此题为例,当循环到c=e时,循环从case 'e':case 'E';开始执行,直到default结束.当c=i时,循环从case 'i':case 'I';开始执行,直到default结束.

苏逸晴2640c++ case语句的问题 -
臧霄砌15933764733 ______ 实际上CASE1啥也不干,但是由于CASE1后面没有break语句执行完CASE1会继续执行CASE2,直到遇到break语句,同理如果显示X,那就说明执行了CASE2因为CASE2后面没有break语句所以程序会执行CASE3和CASE4,直到遇到break,哪里还不明白可以hi我

苏逸晴2640单片机C语言case是什么意思? -
臧霄砌15933764733 ______ 单片机中C语言的case就是经典C语言中的switch.......case语句.基本用法如下:switch(a){case xxx1: // 如果a=xxx1,那么执行该case下面的语句{ ......break;}case xxx1: // 如果a=xxx2,那么执行该case下面的语句{......break;}default : // 如果a跟上面所以case后面的值都不相等,那么执行该case下面的语句...... }

苏逸晴2640C/C++中的switch case 语句是怎样的一个执行过程 -
臧霄砌15933764733 ______ 你理解的是正确的,switch case语句完全可以用if else语句来替换掉;但是当比较较多 或者很多其他控制流程的时候,switch语句 的可读性比if else语句高的多;另外注意的就是 一般情况下每一个case 之后都要跟一个break; 其目的是为了跳出...

苏逸晴2640c语言case -
臧霄砌15933764733 ______ case 1 case 2 ...case 10000000...确实有无穷多个,那你为什么要写这样的代码呢?补充,这种情况就不要用case,用if就行了 if设定一个范围

苏逸晴2640c++如何令case适用于字符串 -
臧霄砌15933764733 ______ 把代码贴出来看看 本质是对一个列表的遍历 用循环即可 没必要牵扯山switch-case void ItemQ::calculateReputationOnce(char *qualityFun) { char *array[3] = {"YZLM", "dKVD", "Correlation"};//指针数组 int i; for(i=0;i<3;i++) { if(!strcmp(...

苏逸晴2640c++关于switch case 中case问题 -
臧霄砌15933764733 ______ 》对本程序来说:不可以》》:》原因(不懂hi我,随时恭候)》》: 对于有些程序可以倒过来,比如,课本上常见的根据成绩来判断成绩等级的那一串代码就可以倒过来.但对这一个程序来说,不可以. 在课本上我们都学过,一个程序一般...

(编辑:自媒体)
关于我们 | 客户服务 | 服务条款 | 联系我们 | 免责声明 | 网站地图 @ 白云都 2024