干货 | 携程后台低代码平台的探究与实践

如何设计一个低代码平台 近些年来,低代码发展火热,各种低代码平台如雨后春笋纷纷崛起,这些平台各定位不同,优劣不同,用户的选择空间很大。那么,如果用户想从零开始设计一个低代码平台,该如何做呢? 阅读详情

作者简介

ck,携程后端开发专家,关注技术架构、高并发、性能调优等领域;

Geralt,携程前端开发专家,关注前端框架及性能优化;

Kaoru,携程资深前端开发工程师,关注前端性能及开发工具;

概述

PGClowcode平台是携程市场内容PGC团队搭建的主要用于后台页面开发的低代码平台,第一版于23年3月上线,截至10月平台已经拥有100+用户,在平台上开发了130+个应用和180+个页面。本文将主要介绍团队采用低代码平台的背景、方案调研、落地过程中遇到的问题以及解决方案,同时也大致介绍了该低代码平台提供的能力。

一、研究背景

1.1 为什么需要低代码平台

软件产品通常由客户端(App、小程序、网页)和运营后台组成,其整个生命周期需要不断地更新迭代,而在实际的迭代开发中经常会出现以下问题:

  • 后台需求优先级低,排期经常被延期,通常使用配置中心等简易数据操作平台替代,不仅对运营人员不友好,而且产生了极大的生产风险

  • 迭代需求涉及的前后端开发工作量不均衡,经常面临后台需求较多,但前端资源不足,服务端资源即便有空闲也没法帮忙支持后台的需求

  • 不同业务间后台技术和组件大同小异,各业务反复造轮子,浪费时间和资源

  • 开发人员开发工具类站点时,页面部分的工作需要付出较大的代价

针对这些问题我们也尝试了很多的解决方案,如要求开发人员全栈、剥离公共组件等,但结果都不太理想,经过充分的了解和分析,搭建低代码或零代码平台能在很大程度上解决这些问题。

1.2 需要什么样的低代码平台

低代码平台分为很多种,我们究竟需要哪种呢?经过将以上问题拆分细化和充分调研后,我们的低代码平台应该满足以下要求:

页面搭建方面:

  • 界面友好、可视化,可以让研发和相关人员能通过拖拽的简单方式快速搭建UI

  • 页面逻辑仅需写少量简单的代码或无需代码

  • 支持满足日常需求的组件库

部署运维方面:

具有开发、部署、运维等完整的持续交付功能,最好能一键或自动化完成

安全合规方面:

  • 支持权限管理机制,保证系统安全

  • 具备完善的发布审批机制,能严格保证开发质量和生产安全

兼容性方面:

能嵌入已有后台页面,已有后台尽量少改动的嵌入其开发的页面

可扩展性方面:

支持用户自助化组件开发,并且能在平台上推广

二、现状分析

2.1 行业现状

目前国内外低代码或零代码产品不下百种,既有商业平台,也有开源项目,它们在企业内部用于各种运营后台、数据面板、办公系统等内部系统的开发,在B端提供商品管理、广告投放、商铺搭建等企业服务,在C端广泛用于活动页面、促销频道、广告频道等类型产品的搭建,不仅为企业节省了大量的开发成本、产生巨大的商业价值,同时也为用户提供了丰富多彩的软件产品。

虽然低代码种类繁多,但是每类低代码项目往往具有特定的业务属性,在不同的行业,不同的公司可能需要定制不同的组件,不同的流程,因此市场上很少有能适用于所有场景的平台,也很少有企业愿意去做通用平台。下面分析了目前比较流行的产品:

2.2 产品分析

阿里低代码引擎

LowCodeEngine(阿里低代码引擎)是国内最知名的低代码类产品之一,其完整的实现了《低代码引擎搭建协议规范》和《低代码引擎物料协议规范》,它通过完整的协议栈约定了各种物料的开发、使用、扩展、流通,并且提炼了企业级低代码平台的特性,遵循面向扩展设计的理念,奉行最小内核、最强生态的设计原则而设计的内核引擎。

目前其生态已经相当完备,并且提供了非常详细的文档和使用案例,也有大量的demo开源,其使用起来相对比较便捷。但它并没有提供完整的平台代码,使用者需要在其内核的基础上搭建面向用户的平台和服务系统,具有相当的开发成本。

腾讯低代码平台

腾讯的低代码产品包括搭建生成移动端H5页面的tmagic-editor开源项目和搭建管理端页面的无极低代码商业平台,其中tmagic-editor提供了完整的平台代码,使用者可以在开源社区将整个项目pull到本地部署使用,它具备自定义组件、插件、编辑器等扩展能力,内置了丰富的组件,提供了友好的可视化界面,通过拖拽+配置的方式开发页面。

但其限定于移动端H5页面的搭建,无法适用pc端页面开发的需求,大大限制了使用范围。无极低代码平台是商业化的面向企业付费使用的产品,具备管理端强大的开发能力,甚至结合了AI能力,能供面向企业丰富的解决方案,但它目前并没有开源。

开源低代码平台

在github上搜索lowcode关键词可以看到非常多的项目,他们所使用的技术、项目的形态、star数量、活跃的层度、使用场景各不相同,有些提供了完整的可视化界面,有些则需要通过配置文件或调用接口的方式生成页面或项目,总之需要花费较多的时间对比分析才能找到符合自身需求的项目。

总结

综上所述,我们最终决定选择一款开源程度比较高的项目(appsmith)作为蓝本,然后经过改造、开发搭建了PGClowcode平台。 

三、平台功能介绍

PGClowcode平台功能主要包含页面搭建、组件开发平台两大部分。

d8639ff777d0e501140bee4123e1e629.png

页面搭建包含开发、预览、测试、发布、回滚、备份、恢复等常用功能。在这些功能的基础上,增加了"可视化拖拽"、"多用户协同开发"、"导入导出"、"多数据源"、"通知"等功能,形成了一个相当完善的开发体系。搭建的产物可以通过将平台上的应用或页面嵌入到已有的后台,或者反过来将已有的后台页面嵌入到平台,实现组合使用。

组件开发平台是对页面搭建能力的扩展,支持通过CLI构建本地项目,自定义开发新的组件以满足更复杂的业务需求。(此功能正在开发中,将在不久之后开放)

由于篇幅有限,下面将介绍几个主要功能。

3.1 用户和权限管理

平台拥有自己的用户管理体系,为了与携程的账号体系打通,接入了OIDC域账号认证,使用者无需额外注册账号,只需要使用携程域账号登录即可。

用户的权限做了充分的拆分,平台的所有功能对每个用户开放,只是对于用户私有的数据做了权限控制,权限定义的最小单位是工作空间(workspace),用户可以拥有多个workspace,每个workspace 定义了管理员(admin)、开发者(developer)、使用者(viewer)、测试者(tester)、审核者(reviewer)五个权限组。其中每个权限组对workspace下面的资源拥有不同的管理权限,这些资源包括数据源、应用、页面等,admin可以对workspace内的用户分配不同的权限组,从而对应用的开发、发布等流程上进行管理。具体各权限组的权限分配参考下表:

69f335da8f45f364a1ce8aac47336d93.png

 3.2 可视化应用开发

传统后台开发与采用低代码平台进行后台开发的流程区别如下图所示:

9521c8bb474b76a0649755c2bc67b3bf.png

传统后台开发过程中需要开发者自身搭建开发环境,引入前端组件库如Ant Design,相同的功能需要自己提取组件,开发效率低效。

PGClowcode低代码平台提供了可视化拖拽的面板,支持页面复杂布局。组件栏支持40+种通用组件,并可以组合使用。

在页面绘制方面,通过将其拖入画板,调整位置布局,简单几步完成界面的设计,做到了所见即所得。相同功能可以在画布中复制粘贴,应用本身也支持导入导出功能,方便项目复制。开发变得灵活高效,避免了一些基本构建所产生的bug,达到了降本增效的效果。

在组件的属性值设定方面,可以通过可视化的输入或者通过自定义JS代码的方式进行复杂的逻辑绑定,并且也支持编写js代码完成复杂的交互逻辑。平台内置了多种js库,可以将数据绑定到组件上,在开发状态下能立即看到数据渲染的效果,使得在预览状态下可以边开发边自测。

ac72c9ef2aeba3c37721493e8e7ff8f2.png

3.3 流程管理

应用从开发态->测试态->发布态的流转十分便利。平台设计了不同角色,将测试、审核的流程精简化,各角色登录后可以看到应用的不同状态,应用在开发和审批后自动流转至下一状态,只需要简单几个流程即可完成。

1)开发人员(开发态):根据需求搭建、开发页面,然后发布到测试环境;

2c51835ce4100dbbf8b8c830efa7e268.png 

2)测试人员(测试态):在页面测试,保证其能满足需求,且不存在质量问题后点击Publish提交发布申请;

236a973e4883bf3865053bf74436610d.png 

3)审核人员(发布态):在“待我审核”列表中找到审核申请。审批通过,应用自动完成发布。

5eb33cc4382774e583a9d7955c8ed928.png

3.4 备份与还原

开发平台支持了应用数据的备份和历史版本数据的还原。在开发状态下平台采用了自动保存的设计方案,由于多人同时开发时容易出现相互覆盖或操作冲突的情况,为了减少这种问题导致的返工成本,我们设计了备份和还原的功能。

和正常普通的应用一样,用户可以将每个稳定版本的开发态备份到系统,在之后的操作中需要回到某个稳定版本则直接选中目标版本还原即可。

下图展示了备份还原的操作界面。

cb75caf0d0ba2aa849742e7a186d11a4.png

四、架构和技术

PGClowcode平台采用了前后端分离架构。前端使用了react技术栈,并且集成了携程的多种公共框架和组件,依托于携程的CI/CD平台,实现了持续开发和交付的能力。服务端采用spring webflux框架,集成了cat、clog(携程日志系统)、mongo、credis(携程redis client)、qconfig(携程配置中心中间件,下文简称QC)、qmq(携程MQ中间件)等技术框架,完全融入了携程的服务技术栈,可以通过gitlab自动化编译打包,在captain(携程发布平台)上发布。

4.1 架构

57a93b8156f0b5dc9a4a4bd119d64633.jpeg

如上图所示,PGClowcode平台的整体架构分为应用层、基础设施、服务层、数据层。

应用层是终端的两套平台系统,主要包括面向用户的低代码开发平台和面向开发人员的组件开发平台。

基础设施主要包含前端的基础框架、数据流控制以及抽象出来的前端可视的组件、页面和编辑器等概念。基础框架主要依托于React App和canvas技术通过axios库和服务端进行数据交互,通过Redux及相关插件来控制整个平台的数据流,最终展示成用户可见的组件、页面、编辑器等UI模块。

服务层主要由web层、service层和数据访问层组成,主要提供权限验证、流程管控、插件管理、消息通知、数据访问等服务。服务采用了微服务架构的设计,按照不同的领域和功能拆分成领域服务、通知服务和插件服务。

领域服务又根据不同的model细分为不同的模块,各自完成独立单一的功能;通知服务主要用于email、trippal、sms等消息通知;插件服务主要提供插件的加载、初始化、调用、卸载等相关功能的服务。数据访问在核心服务的下层,实现了针对多种数据源的访问和数据处理、校验的功能。 

数据层主要用于存储元数据、应用数据、插件数据等,应用的备份数据存储于QC,并且通过QC实现跨环境发布。

下面两节主要对平台“组件的可视化拖拽实现”和“应用的开发-部署实现”两项比较核心的技术详细阐述。

4.2 组件的可视化拖拽实现

cc437bfc72b30e778964f64e942eee35.gif

可视化拖拽组件是低代码平台的基本功能,在本平台中,用户可以在左侧组件库里选择任意组件拖拽到中间的编辑区域,并更改其大小。

在实现上述的拖拽功能时,我们会面临几个问题:

1)拖拽组件的过程中,组件的位置会实时变更,大量嵌套在一起的dom元素同时变更位置,会频繁触发浏览器的重绘制,导致性能的消耗。

2)人为的拖拽排布,很难保证组件之间的对齐和排版,页面最终效果难以达到代码实现页面的规整程度。

对于上述的问题1,平台的解决方案是依托canvas技术,在组件变更位置或者大小时,隐藏实际渲染在页面上的组件,并在编辑区域最上层渲染一层canvas,在原组件位置画出一个同等大小的色块来代替原组件,并用以示意用户,利用canvas画布的特性来处理组件位置及大小的变更,在用户结束拖拽动作后,根据色块在canvas中的最终位置及大小,重绘制一次组件,并隐藏canvas,展示出组件的最终效果。

在上述描述中可以看到,利用canvas可以极大程度的削减浏览器重绘制的次数,达到减少性能消耗的目的;选择色块来作为绘制对象而非原组件,既降低了技术实现的难度,又进一步降低了canvas绘制图形的性能消耗。

对于问题2,平台的解决方案是阵点系统,当用户拖拽组件到编辑区域触发渲染canvas的同时,页面上会绘制一层阵点并均匀的平铺在canvas上,当用户在canvas上拖拽色块变更其位置或者大小时,在色块的周边会绘制出同等大小的虚线边框,边框会根据色块当前的位置及大小动态的定位到合适的临近阵点上。阵点系统中,横向及纵向两个相邻阵点的间隔即为组件长宽的最小单位,组件的四角位置只能定位在阵点上。由此可见,在拖拽过程中,组件的位置及大小都在一定的限制之内,这可以保证最终绘制出来的页面的规整性。

以下为一次完整的组件拖拽流程示意图:

9dedba9a1b9f476e514fea69a13bcbc7.jpeg 

1)页面无拖拽操作,主编辑区域仅展示组件的静态状态,此时为展示态。

2)当用户开始拖拽组件以期改变其位置及大小的动态状态,为操作态。操作态又可以细化为拖拽开始、拖拽中、拖拽结束,三个状态。

当用户开始拖拽组件时,页面会从展示态变更为操作态。拖拽开始时,编辑区域内绘制canvas并铺设阵点,原组件变为不可见,在canvas内原组件的相同位置绘制同等大小的色块以及虚线边框;在拖拽过程中,色块会随着鼠标移动变更位置或者大小,其外部虚线边框也会随色块移动或变更大小,并实时定位在色块当前位置的最相邻阵点上;拖拽结束时,根据当前边框的最终大小及位置,重新绘制原组件,并隐藏canvas、阵点系统、色块以及虚线边框;页面由操作态变更为展示态,展示出组件的最新状态。

4.3 应用的开发-部署实现

应用的开发和部署的技术实现主要分为应用的数据结构、数据流转和多种角色协同三个部分,最后针对应用的数据备份与还原也做了简单的介绍。

4.3.1 数据结构

当前大多数主流的低代码平台最终的产物可能是代码,但PGClowcode平台最终的产物是数据,包括应用信息、页面信息、组件、组件之间的关系、action、数据源等都是以数据的形式存储在db上,由于页面的布局、组件嵌套、函数的绑定等各种实体间关系非常复杂,使用传统的关系型数据库无法保证数据结构稳定,因此采用了mongodb作为数据库。应用相关的collection主要包括了plugin、workspace、datasource、application、page、action、actioncollection,它们通过下图的关系构成了整个应用体系。

63feb1932b2be742615f44f473305a27.jpeg

plugin主要用于定义平台支持插件的元数据信息,包括类型、插件包路径、参数、状态等属性。

workspace是应用开发的工作空间,它定义了空间内的用户组成、用户权限、数据源以及支持的插件集合。

application定义了应用的名称、主题、icon、状态等基本信息,另外为了查询便捷,也冗余了部分页面的信息。

page定义了页面的名称、布局、组件、组件的关系、组件与函数的绑定关系等。

datasource定义了外部数据访问的基础信息,如restapi、es、mongodb等外部数据访问的必要属性,为了避免重复配置,它的作用范围是workspace级别。

action定义了外部数据访问的具体配置数据,它必须依托于datasource,如restapi接口调用,datasource配置了服务的域名和是否需要实时鉴权,而action则配置路径、参数、运行方式,与datasouce不同的是它的作用范围是页面。

actionCollection是action或js函数的集合。

4.3.2 数据流转

应用数据主要是在不同的存储介质和不同的环境间流转,平台目前设计了三套环境FAT、UAT、PRO,平台通过QC的跨环境机制实现数据流转。

18ca590a5203f2af280a7324dfba140b.jpeg

如上图所示,开发者在FAT上开发应用,应用数据以草稿态存储于DB,开发完成后将草稿态数据导出到QC的FAT环境,服务监听到QC的数据变更将草稿态copy到发布态,测试则可以在测试页面上看到开发提交的应用,测试完成后提交UAT发布申请,服务将发布态的数据导出到QC的UAT环境,此时审核者将收到待审核通知。

进入平台将待发布申请审核通过后,UAT环境的服务监听到QC数据变更将数据导入到DB,并且将应用数据状态置为发布态,然后可以在UAT的测试页面看到发布态的应用,当UAT测试完成后申请发布到生产(PRO),UAT服务将发布态应用数据导出到QC PRO环境,当审核者通过申请后则QC PRO的应用文件被发布,PRO服务监听到数据变更就将应用数据导入到DB,并置为发布态,此时应用的开发-部署流程结束,用户可以在生产环境的用户平台正常使用了。

4.3.3 多角色协同

对于应用的开发、测试、交付平台设计了多个角色,在整个需求开发的过程中每个角色能各司其责,保证应用能持续、稳定、高效迭代交付,如下图所示。

691275aed4cf14f01670e95532f884a8.jpeg

平台通过定义多个权限组来区分每个角色,当workspace被创建时这些权限组就会被创建出来,每个权限组定义了各自的权限,在每个受权限管理的资源中都有policies字段,它存储了能被操作的类型和权限组id的集合,当用户查询和操作时都会经过权限校验。

ab764bfcaaa9d3c6fd15ad3c01420def.png 

有了角色的定义,应用开发人员的协同就变得简单多了,如当应用发布测试时可以自动通知测试人员介入,提交发布生产申请时可以自动通知审核人员参与审核。

4.3.4 备份与还原

为了方便开发过程中多人同时开发,平台设计了备份还原功能,当用户点击备份时,服务将当前草稿态数据导出到QC,点击还原则将QC的数据导入到服务,覆盖当前DB中草稿态数据,得益于QC的版本管理功能,每次备份的数据都将存储起来,因此用户可以还原到历史的任意版本。

ff66168bb56ac7f9c69e79cc12ff0f00.jpeg

如上图所示,T1时刻新增一个备份v1,T2时刻QC中存在v1版本的备份数据,如果T2时刻再增加一个备份v2,到T3时刻QC存在v1和v2两个版本,如果在T3时刻将DB中的版本还原成v1,则DB中的数据会被还原成v1,与此同时会上传一个v3版本到QC,实际上v3和v1数据是一样的,相当于将当前数据的基准切换到了最新版本,之后的操作都是在这个版本的基础上做的,如果再需要还原到这个基准就可以快速完成。

五、规划与展望

目前PGC低代码平台已经具备了非常完整的功能,基本上完成了预期的目标,也产生较大的价值,但我们对于它的期望绝非只限于此,并且组建了稳定的支持团队,制定了明确规划,在之后的迭代开发中会不断地完善已有的功能和流程,而且会根据实际的需求和业内平台的调研继续增加更强大、便捷的功能。

5.1 搭建组件扩展平台

平台原有的组件是比较基本的组件库,未来会难以满足日渐复杂的业务需求,因此自定义组件的需求就会逐渐凸显出来,本平台基于Appsmith框架是支持自定义组件的,但是原有的自定义功能有如下几个问题:

1)原有的自定义组件功能,需要依托于完整的平台项目,在其widget文件夹下开发新组件,项目代码体量大,启动慢,且以开发组件为目的频繁更改提交平台项目并不利于平台项目的发布及管理。

2)原有的自定义组件功能并不适合多部门自定义组件的场景,没有相关的权限管理系统,所有自定义组件都会展示在页面上,随着时间的推移会造成组件库的臃肿以及增加编辑页面时查找使用组件的费力度。

为了解决以上问题,我们会从主项目中抽离出相关代码,搭建一套独立的组件开发项目,以达到和平台主项目分离、代码纯净、项目快速启动的目的。同时也会构建一套自定义组件的权限管理系统以便更好的管理各部门开发的自定义组件。

5.2 建立模板库

Ctrl+C和Ctrl+V可能是开发人员使用频率最高的按键组合,致使一些键盘不是“面目全非”就是“半身不遂”,试想一下,如果我们拿出来一键生成部署页面的功能,是否能让“久经磨难”的键盘依然“历久弥新”呢?没错,这是我们接下来的目标。

低代码平台的模板是指根据长期积累的经验,总结一些具有共性的通用方案,并且提炼成所有用户都能直接使用的页面或应用,收录到模板库中,当平台上的其他用户需要使用类似应用或页面时,只需要找到合适的模板,一键即可生成页面或应用,甚至能拿来即可用,无需做任何修改。后期可以允许建立团队自己的模板库,各成员可以搭建自己的模板专门供团队使用。

【推荐阅读】

f18bcb64e24e3c1d510505b3105fc5dd.jpeg

 “携程技术”公众号

  分享,交流,成长

一种关于低代码平台(LCDP)建设实践与设计思路 业务线特别多,每个业务线对同一个页面都有个性化布局和不同的字段需求,在资源有限的情况下如何支撑好呢?本文就降本的情况下,如何低成本构建产品能力去支撑多条业务线、多租户。 阅读详情

相关推荐

国内常见的14款低代码平台介绍

今天给大家分享国内常见的14款低代码平台,欢迎收藏!

IT技术分享社区 7万+

带你一步步实现低代码开发平台——概述、实现模式、整体框架

当下,低代码与无代码的概念正炙手可热,市面上涌现了众多相关平台。客观而言,低代码开发平台确实通过配置化的方式显著提升了开发效率,降低了成本,并缩短了项目周期。同时,这种开发方式也降低了对开发人员的技能要求,所生成的代码更为标准化,有效减少了低级错误,间接提升了软件质量。然而,低代码开发并非是一个全新的概念,其历史可追溯至较早时期。在一个软件系统中,许多功能具有共性,这些功能可以通过抽象建模和标准化来简化开发流程。例如,单实体(如计量单位)对应单张数据表,展示和操作方式相对简单;

学海无涯,行者无疆 2万+

2023年11月数据月报

2023年11月数据月报,为您准备了阿里、字节、百度等大厂160多篇实践案例:

SmartSi 2926

带你一步步实现低代码开发平台——低代码配置模块视图功能总体设计

上一篇介绍了整合接口平台,架构优化,使用低代码配置模块、实体、模型,今天接着上篇继续写,重点介绍下视图整体的设计。 视图,实际上也就是前端web页面,这部分超级复杂。根据用途不同,将视图进行了分类,建模产生以下类型的视图 - 列表视图 - 新增视图 - 修改视图 - 查看视图 - 树视图 - 树表视图 - 参照视图 - 树参照视图 - 树表参照视图 - 主从视图(待实现) - 自定义视图(待实现)

学海无涯,行者无疆 4410

QMT与通达信代码实战:从预警到交易的自动化实现

本文详细介绍了如何利用QMT量化交易平台与通达信软件实现从预警到交易的全自动化。通过读取通达信预警生成的板块文件,QMT策略可自动执行买卖指令,有效解决手动交易滞后问题。文章提供了完整的代码框架、核心原理拆解及实盘注意事项,帮助投资者构建高效、纪律性的自动化交易系统。

ansible6ops的博客 648

计算机视觉——SIFT特征匹配

文章目录一、SIFT特征检测原理1.1基本思想1.2二、SIFT特征检测图片兴趣点三、SIFT特征检测描述子匹配四、输入图片检测与之 一、SIFT特征检测原理 1.1基本思想 1.2 二、SIFT特征检测图片兴趣点 代码: 检测结果: 三、SIFT特征检测描述子匹配 四、输入图片检测与之 ...

weixin_43869874的博客 3855

如何设计一个低代码平台?

低代码平台至少包含表单建模、流程设计、报表可视化、代码生成器、系统管理、前端UI等组件,我们没必要重新造轮子,市场上已经有大量的成熟组件,选择合适的组件进行集成和二次开发,即可自主开发一个低代码平台。以下是以Java+Vue为开发技术的选型参考。

xuxian的博客 2169

OV5640调试大坑,关于binning、RES分辨率与EV曝光

OV5640在使用binning模式时,必须考虑使用场景,分辨率下降叠加动态范围压缩,会使目标对象细节在高光环境下大量丢失,2x2的binning模式,分辨率会远低于感光面积的1/4。

chongyun_的专栏 1824

一个思想超前的低代码平台主要实现思路

本文给出了一个思想超前的低代码平台主要实现思路,包括纵向数据存储引擎构建思路、自定义脚本引擎构建思路、数据详细设计、平台商业模式及低代码平台现状分析等。

bossfriday - 个人博客 6747

GD32F450以太网(1):ETH 外设接口简介

GD32F450以太网ETH MAC外设接口简介

Zhichao_Zhang的博客 1万+

手把手教你用WKT文件在Petrel中创建自定义坐标系统(附CGCS2000转换模板)

本文详细介绍了如何在Petrel软件中利用WKT文件创建自定义坐标系统,并重点提供了CGCS2000坐标系的完整转换模板与实战步骤。通过解析坐标系统的三大支柱(大地坐标系、投影坐标系、基准转换)和WKT文件结构,指导用户从零开始构建适用于本土化项目的坐标系统,确保地质建模与空间数据处理的精度与一致性。

gpt4scribbler的博客 277

带你一步步实现低代码开发平台——低代码配置模块、实体、模型设计

今天我们通过一个实际案例来辅助说明下低代码平台的设计。之前开源了一套通用接口平台,详见专栏。我们将其迁移整合一下,使其成为开发平台的一个功能模块。接口平台自身基础数据的维护,如应用、接口服务、消息主题等,需要实现相应的管理功能。

学海无涯,行者无疆 6736

python数据处理与分析案例,python如何进行数据处理

大家好,本文将围绕基于python的数据处理案例展开说明,python数据处理与分析案例是一个很多人都想弄明白的事情,想搞清楚python如何进行数据处理需要先了解以下几个事情。大家好,小编来为大家解答以下问题,python数据处理案例步骤及其代码,python数据处理与分析教程,今天让我们一起来看看吧!哈喽~今天学习记录的是数据分析实训小案例。就用这个案例来好好巩固一下 python 数据分析三剑客。

a17348的博客 1238

低代码平台的设计与实现

​ 低代码平台是一种强大的开发工具,可以帮助企业快速开发应用程序,无需深入的编程知识。它将开发过程中的大部分繁琐和重复的任务抽象出来,让开发人员能够专注于业务逻辑和创新。

weixin_52213728的博客 824

C#上位机之海康相机开发(SDK)实战教程

SDK的接口设计遵循“句柄-操作-释放”模式,掌握→→→的流程,就能完成基础开发;工业场景需重点关注稳定性:断连重连、内存管理、抗干扰(网口相机的IP设置、触发信号的可靠性);进阶功能(如图像处理、多相机同步)需结合视觉库(EmguCV)和硬件特性(GPIO触发),但前提是保证基础采集的稳定。建议新手先跑通SDK自带的C#示例,理解每个函数的作用,再逐步替换为自己的代码。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 2192

计算机专业保研攻略(一):个人定位与院校推荐(必看干货)

写在最前 又是一年保研季,作为过来人,我深知保研就是一场信息战。在保研过程中,需要注意的信息太多了,最初我也因为经验不足,走了不少弯路。我写下这篇博客,希望能帮助更多有需要的同学。 怎样做好保研信息分析 我想举几个发生在我身边真实的例子: A同学推免排名不如B同学,但A保研去向比B同学好很多; C同学在年级里成绩并不算突出,但他拿到了最好的offer; D、E同学纷纷圆梦北大、浙大等名校,但是他们的成绩似乎并不突出; F同学取得了目标院校夏令营offer,但没有拿到本校推免资格; G同学认为自己拿不到推免

乔卿的博客 8388

1.携程架构实践 --- 携程整体技术架构

第1 章 携程整体技术架构 架构的意义在于确定"主绳"的位置。架构实际代表的是一个方法论,这个方法论的核心思想在于构建目标的主要环节,主要环节一方面可以带动次要环节, 另外一方面还可以对次要环节的作用范围进行限制。 技术架构大体上可以划分为业务架构和整体技术架构两部分: 1.业务架构更加关注业务流程的技术实现,比如用户下单流程的制定,以及各个环节需要用到的支撑系统; 2.整体技术架构更加关注全局的技术解决方案,比如业务系统之间的通信方式,以及实时观测业务系统的运行状态。 1.1 携程技.

enlyhua的专栏 4911

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

讲讲我做低代码平台的建设过程,希望可以帮到正在工作的你

最近这几年低代码这个词很火我想对于大多数程序员来说都不算陌生,从百度搜索指数也可以看出,其搜索量从21年开始有了一个明显的增长。截屏2023-06-27 15.24.50.png那低代码或者无代码技术目前有哪些应用场景呢?其底层的技术是什么样的?其如何与当今大火的 AIGC 结合呢?正好在过去一年的工作中我作为项目的核心技术负责人从 0 到 1 经历了我们公司内部低代码平台的建设过程,在这其中也有...

frontend_frank的博客 2660

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

带你一步步实现低代码开发平台——低代码配置模块视图配置功能详解

对于大多数业务实体管理,在系统中有个功能菜单对应,最常见的情况就是一个列表页面,如接口平台模块下的应用管理功能,如下图所示该页面对应着列表视图,包括了常见的查询、新增、修改、查看页面(删除功能不是一个页面,而仅是一个功能按钮,位于列表页面),对应着新增视图、修改视图和查看视图。列表视图是最常用,也是最复杂的,下面具体来说一下。对于自关联的实体,如组织机构,实际数据是有层次,会展示为一棵树。该视图通过实体模型属性中的是否上级就可以自动处理,无需额外配置。

学海无涯,行者无疆 3632

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

面向中后台复杂场景的低代码实践思路

现实中,业务场景多,迭代频繁,变化快到跟不上,规则可能由多人掌握,无法通过一个人了解全貌; 还有业务所在行业固有的复杂度和历史包袱,这些问题都会让我们感到痛苦。 除了逻辑问题,我们还关注易用性交互开发的问题。

数据库技术 2533

低代码是开发的未来吗?浅谈低代码开发平台的发展现状及未来趋势

这篇主要来谈谈低代码是怎么一步步影响着我们的生活,以及在将来有哪些新的变化和突破。由于现在低代码&零代码产品在宣传过程中着重强调。因此,外行人就会想当然推出以下结论:人人都是开发者=人人都能写代码=程序员将被低代码产品替代=搞噱头=胡扯。要知道,即使非常专业的开发者,在的趋势下(前端/后端/算法/运维)企业也很难做到。而低代码可以通过统一语言来减少业务和技术人员的沟通成本,使得这才是。...

BeWorkingMan的博客 3317

低代码平台介绍(国内常见的)

低代码市场,早在几年前,亚马逊、微软、阿里、腾讯等国内外巨头公司就已纷纷入局。随着钉钉发布会的推出,2021年开年“低代码”再一次被推向了风口,“低代码”市场又重新火爆起来。

DreamSun的博客 2152

一种面向后端的微服务低代码平台架构设计

近期参加公司组织的极客中餐厅训练营,我们所在的小组接到的课题是微服务的低代码平台架构设计。目标是:结合京东业务研发实际情况,针对后端研发人员,设计一个微服务低代码平台,助力更高效低交付业务需求。现已结业,将我在本次项目中沉淀设计出的设计文档整理成文,期待与大家有进一步的碰撞沟通

京东科技开发者 1251

天画项目-低代码平台-总体设计与实现

一、背景&需求 1.1 总体背景 我在业余时间构建了一个租房平台,采用springboot微服务的架构模式,同时结合服务化思想进行代码实践,但是由于存在很多重复且低效的变更导致业余时间对这个租房平台的进度产生影响。作为开发人员长期维护一个业余项目产生了很多进度延迟和效率问题会导致项目项目被遗弃的概率增大,对开发者来说也是一个非常沮丧的事情。为了避免这种事情发生,我一方面鼓励自己尽量每天贡献代码,并在合适的时间构建提高开发效率的使用平台。另一方面也是为了借助这个租房平台进行微服务+分库分表+DDD

程序男的专栏 5957

原来低代码平台可以这样设计!

大厂技术高级前端Node进阶点击上方程序员成长指北,关注公众号回复1,加入高级Node交流群本文会主要分享自己对低代码平台的理解,从多个角度和问题去看低代码平台的设计。我觉得「低代码平台的核心在于模型设计,包括控件模型、组件模型、画布模型等等」。希望看完本文,你能知道:低代码平台核心的底层逻辑是什么?为何常见低代码平台都包含“控件区”、“布局区”和“属性编辑区”...

程序员成长指北 3363

带你一步步实现低代码开发平台——提升配置效率,面向对象的继承,原型拷贝

背景 低代码配置功能实现得好,能大幅提升开发效率。但是不得不说,在平台里按照规范和约定一步步来操作,在某些情况下确实不如源码开发灵活和方便,存在类似的配置工作重复执行繁琐枯燥的情况。这时候,就需要平台进一步提升操作的便捷性,来提升配置效率。 如何提升呢? 核心思路有两个,一是基于面向对象的继承思路;二是来源于原型设计模式的原型拷贝思路。面向对象的继承机制 基于平台的顶层设计,实体建立了统一的基类,在基类里定义了标识、创建人、创建时间、修改人、修改时间、版本号(乐观锁)、逻辑删除标志位。这几个字段,主要是技

学海无涯,行者无疆 1380
上一篇: 干货 | 深度多元时序模型在携程关键指标预测场景下的探索应用
下一篇: 干货 | 移动端使用OpenGL转场特效的音视频合成应用
携程技术
博客等级 码龄10年 3716粉丝 324原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值