万万没想到!ModelArts与AppCube组CP了

时间:2022-09-03 22:49:02

摘要:嘘,华为云内部都不知道的秘密玩法,我悄悄告诉您!

双"魔"合璧庆双节

万万没想到!ModelArts与AppCube组CP了

↑开局一张图,故事全靠编

华为云的一站式开发平台ModelArts和应用魔方AppCube居然能玩到一起,这是可能是华为云官方自己也没想到的场景,而我,从8月份开始体验公测应用魔方AppCube以来,一路坎坷,从给AppCube提Bug,到等待新版本发布完毕,再一步一步摸着石头过河,一直在探索AppCube与ModelArts的结合,缘由很简单--我希望低门槛开发AI应用、低门槛落地AI应用,不过,差强人意的是我在使用低代码平台AppCube时,还是Copy了好些代码……但我还是坚持探索,今天赶在中秋国庆双节之际,终于跑通了我的第一个落地Demo--命名实体识别。可以说这是前所未有的体验!

缘起

应用魔方 AppCube(以下简称AppCube)是低代码应用开发平台,顾名思义就如同魔方一样,可以通过任意组合,排列各种模块化元素,创建功能各异的应用。AppCube是在线多租的应用开发和运行的aPaaS平台。

就是这么一个牛掰的低代码平台深深地吸引了我,之前有用她完成过口罩分配系统的Demo,那时候好像还不叫AppCube。之后,很荣幸地参与了应用魔方AppCube的公测体验,通过深度体验AppCube,我进一步熟悉了解了她,加上刚好也在学习一站式AI开发平台ModelArts,通过ModelArts学习了一些简单AI模型的训练和在线部署,然后也尝试将这些AI服务“落地”--完成前端开发部署,有幸产出了基于Koa.js的体验小Demo--今天,您存了吗?。尽管很有趣,但还是摆脱不了对*服务器的依赖,遇到应用魔方AppCube让我有了大胆的想法:结合ModelArts和AppCube实现AI在线服务的前端应用!于是,"JUST DO IT", 走上了一条无限踩坑的道路……

遇到的第一个坑,确是真·HW工程师给我挖的!调用过ModelArts在线服务的小伙伴都应该知道,我们在调用接口之前需要获取账号的AK和Sk,通过加密算法签名之后才能够正常获取调用的结果。整套流程本身是没有任务问题的,但是通过AppCube去调取ModelArts的在线服务,总是无法正常调通,一直是返回Incorrect IAM authentication information,也就是说无法正常认证,原因也无非两种,一是签名之后的token不正确,二是客户端(AppCube)的时间与服务端(ModelArts在线服务)的时间不一致且相差超过15分钟。

经过反复验证,我确认是后者,于是提了8月18日晚上就提了工单,到8月20日晚上基本确定是AppCube的signer加密算法写得有点问题,然后就是漫长的等待发版……到9月16日终于等来了新版本并修复了这个坑。

然后,我开始“三天打鱼两天晒网”,又踩到了第二个坑--AppCube的标准页面不支持匿名访问,于是我赶紧想法将标准页面转为高级页面,结果又遇到了第三个坑--由于我的标准页面含有多语言组件导致转化后的高级页面仍然无法匿名访问。于是,我开始了转向高级页面的开发……

然而,高级页面确不是我想象的那么高级,就好比等级高但是装备还是得自己打,是的,高级页面中没有基础的布局,需要自行开发组件;高级页面还需自行开发桥接器,因为AppCube的安全策略不允许前台页面直接调用后端服务。

9月的月末,基本在这些坑里折腾……

ModelArts侧的开发

对我来说,目前开(拷)发(贝)一个AI在线服务已经如探囊取物,毕竟ModelArts平台就提供了各种Copy的能力:您可以基于自动学习开发AI在线服务;您也可以基于预置算法或者订阅算法训练并部署AI模型;您还可以从AI市场直接订阅模型来开发AI在线服务,甚至还可以直接从OBS加载元模型。总之,也许您没有AI基础,通过一站式AI开发平台ModelArts就能开发并部署一个AI在线服务。为了更加简便,我采用的OBS元模型方式,分分钟部署一个Bert命名实体识别在线服务

万万没想到!ModelArts与AppCube组CP了

简单介绍一下操作流程:

0. 准备阶段

  • 注册华为云账号--这是一把金钥匙,开启了我的“云”世界。
  • 访问“我的凭证”获取“访问密钥”--也就是AK/SK,这还是一把金钥匙,是我通过开发工具访问华为云的身份凭证。
  • 开通OBS并新建桶和文件夹--这是40G容量的金桶,用来存放我Copy过来的数据、模型、算法……Y
  • 开通ModelArts--这是真金白银打造的一站式AI开发平台,我却挥霍着免费算力(学艺不精,不学无术,浪费资源)。

1. 开(拷)发(贝)阶段

从AI市场数据集下载model到OBS
请访问model-test:https://marketplace.huaweicloud.com/markets/aihub/datasets/detail/?content_id=23441bfe-8c6b-4d0c-8076-13252bde17c0, 点击页面的下载按钮,配置下OBS路径,点击下一步即可下载model到OBS

从OBS导入元模型
我们需要进入到ModelArts平台点击模型管理 - 模型 - 导入 - 从对象存储服务(OBS)中选择,这里记得选择元模型是选择model文件夹的父级,会自动识别到Tensorflow引擎。点击立即创建就会自动构建模型。

2. 部署阶段

部署是最简单的一步,等待模型构建完毕点击部署 - 在线服务一路 Next 进行模型部署上线操作。稍等片刻,部署成功之后就是熟悉的在线调试等步骤。

万万没想到!ModelArts与AppCube组CP了

AppCube侧开发

通过此次探索,我深刻地体会到AppCube的精妙之处--介是您没有玩过的船新版本。就像上文中提到的那些坑,主要还是自身技术不硬,没好好了解玩法和规则,然后就无限掉坑爬坑掉坑。不过,目标是明确的:一个页面,有输入框,有提交按钮,有结果显示,能调用AI服务。是不是超级简单?简单到我以为半个小时能搞定。结果……不说了,说多了都是泪!直接上手高级页面开发,我要做高级Copy攻城狮!

高级页面开发准备

  • 自定义UI库

在开发高级页面前,您需要学习Widget、库、桥接器、事件和动作等相关内容。没办法,摸着石头过河,如果光脚的话,容易划伤;先来一个MintUI(尽管已经过时了),如果高级页面要使用前端框架或组件库,例如流行的Vue、Bootstrap、ElementUI等,需要将其制作成Library资产,然后上传到环境中使用。本次高级页面为自定义的Widget,我想用MintUI来完成前端布局,那就需要将自定义库进行上传以及在Widget使用库。好在官方文档提供了教科书般的Demo:管理并使用库,步骤也简单:

  1. 下载MintUI并上传到高级页面 > 库
  2. 自定义Widget中引用MintUI:

packageinfo.json

"requires": [
{
"name": "global_Vue",
"version": "100.7"
},
{
"name":"bingobingotesthuaweicom_mintui", // 库文件名称和版本号在库详情页面获取 "version": "1.0" }]
  • 工具包下载

万万没想到!ModelArts与AppCube组CP了

开发高级页面比较狂拽炫酷的方式就是使用Scaffolding离线开发Widget。Scaffolding是AppCube系统提供的一个脚手架工程,方便创建本地资产工程,用于本地开发Widget、本地调测后上传至资产库,也可以通过该工具下载Widget至本地。

对了Widget的概念非常不错,玩出来Flutter的感觉,万物皆Widget!您在浏览器中看到的一个系统网页,即是一个页面。Widget是可复用的高级页面组成元素,一个高级页面由一个或多个Widget拼装而成。如果将一个高级页面看成拼图游戏的完整图案,那么Widget相当于拼图的每一小块。而我们想在本地开发Widget就需要用到工具,这个工具有点特别,其实是一个前端的NPM包,我特意查了下,这个包不是公开的,需要我们从官方文档中下载:https://obs-ap1-appengine.obs.cn-north-1.myhuaweicloud.com/usermanual/assets_starter.zip。 如果后续版权允许的话,它应该会出现在NPM公共包中。说是工具,其实是一堆代码,依赖storybook来开发组件。从代码结构和bin目录来看,工具包提供一个mango的命令行,我们可以通过mango ui开启一个本地的组件开发环境,方便后续的开发调试。当然,还需要设置并获取客户端ID和客户端密钥。

  • 项目准备

AppCube有开发环境和运行环境,我们通过AppCube的控制台进入到开发环境,新建一个空白的轻应用。从操作界面来看,应用魔方AppCube支持轻应用、行业应用、业务大屏以及移动小程序。目前构建的应用有四种发布渠道:AppCube仓库分发、Welink、讯盟以及下载到本地。关于项目的一些基本配置,这里不再赘述,具体查看官方文档的用户指南。

万万没想到!ModelArts与AppCube组CP了

高级页面开发概要

  • 在线开发脚本及服务流

理论上,我们的前端业务是不直接调用后端接口的,这次的探索,我们把调用AI在线服务交给APPCube的后端逻辑了来处理,由APPCube开发的前端业务调用后端业务,由AppCube的后端业务去调用AI在线服务,这样尽可能保障了我们传输过程中使用的敏感数据如AKSK不被泄露。于是,我们需要编写脚本,还需定义服务流、公共接口等,具体可查阅官方文档。如图中,我们定义了三个脚本:config--简单配置AKSK及AI在线服务地址;singer--签名用的,根据AKSK提供的Demo改写使之适应AppCube;getSinger--也就是调用服务的脚本,输入body,返回请求AI在线服务的响应。

万万没想到!ModelArts与AppCube组CP了

服务流也定义得十分简单,只是调用了getSinger脚本,然后在下边服务中定义基于服务流的公共接口,给到桥接器方便前端页面调用。

万万没想到!ModelArts与AppCube组CP了

  • 自定义Widget

万万没想到!ModelArts与AppCube组CP了

当我们使用上文工具时,执行mango ui能打开本地开发界面,如:http://localhost:8000/app/list。我们可以开发标准页面组件、高级页面组件以及Vue高级页面组件。通过设置,我们能直接连接到AppCube的在线环境,可以和在线环境进行交互,如组件上传下载、组件设置、组件编译等。

  • 自定义桥接器

有时候弯路走多了,路越走越弯。为什么要自定义桥接器?因为自定义高级页面中要调用服务可能就要用到桥接器!总之,从一开始的标准页面不支持匿名访问,我就走上了一条不断踩坑的不归之路。截止发稿,还有一个坑没填上,所以尽管Demo已经开发完毕,开发环境能正常调试,但是运行态还存在脚本不存在或者未激活的Bug,目前真·HW工程师正在全力技术支持中!说回怎么自定义桥接器,三步走:

1.获取Demo代码并修改

 // 核心代码
var widgetBridge = thisObj.getConnectorInstanceByName('BertDemo_getAKSK');
// ...
thisObj.callFlowConn("BertDemo_getAKSK", {
service: "/BertDemo__AKSK/0.0.1/getAKSKFlow"
},{},result =>{})

2.和自定义Widget一同发布

万万没想到!ModelArts与AppCube组CP了

3.在高级页面中使用

万万没想到!ModelArts与AppCube组CP了

发布

AppCube的发布流程就像是软件开发的发布流程:先编译,再发布。在AppCube开发环境进入应用开发页面,点击左下角编译按钮进行编译,编译成功之后,页面会显示“编译XXX成功”。关闭编译成功的窗口。再点击左下角发布按钮,在“发布应用”页面选择“我的仓库”。

发布成功后,页面显示“程序包已经被成功上传到我的仓库。”。在App开发页面左侧单击我的仓库,可在“已发布”下看到发布的应用。点击顶部首页按钮进入首页,在首页单击“管理”,选择“应用管理 > 我的仓库”可查看到发布的应用。

在AppCube开发环境右上角单击用户名,选择“运行环境”。在总览页面选择“我的仓库”进入“我的仓库”页面。单击“安装”,在弹出的确认框单击“确定”。安装该应用;在左侧菜单选择“总览”,进入“总览”页,单击“应用”,进入“应用程序列表”页面……
尽管步骤有些繁琐,不过文档中有详尽的示意图,一步一步跟着多走几遍就熟悉了。

万万没想到!ModelArts与AppCube组CP了

看来目前AppCube主要是面向企业开发者,Copy攻城狮看来需要放弃了!接下来,探索一下ModelArts和鸿蒙OS看看能不能也擦出点啥来。

点击关注,第一时间了解华为云新鲜技术~

摘要:嘘,华为云内部都不知道的秘密玩法,我悄悄告诉您!

双"魔"合璧庆双节

万万没想到!ModelArts与AppCube组CP了

↑开局一张图,故事全靠编

华为云的一站式开发平台ModelArts和应用魔方AppCube居然能玩到一起,这是可能是华为云官方自己也没想到的场景,而我,从8月份开始体验公测应用魔方AppCube以来,一路坎坷,从给AppCube提Bug,到等待新版本发布完毕,再一步一步摸着石头过河,一直在探索AppCube与ModelArts的结合,缘由很简单--我希望低门槛开发AI应用、低门槛落地AI应用,不过,差强人意的是我在使用低代码平台AppCube时,还是Copy了好些代码……但我还是坚持探索,今天赶在中秋国庆双节之际,终于跑通了我的第一个落地Demo--命名实体识别。可以说这是前所未有的体验!

缘起

应用魔方 AppCube(以下简称AppCube)是低代码应用开发平台,顾名思义就如同魔方一样,可以通过任意组合,排列各种模块化元素,创建功能各异的应用。AppCube是在线多租的应用开发和运行的aPaaS平台。

就是这么一个牛掰的低代码平台深深地吸引了我,之前有用她完成过口罩分配系统的Demo,那时候好像还不叫AppCube。之后,很荣幸地参与了应用魔方AppCube的公测体验,通过深度体验AppCube,我进一步熟悉了解了她,加上刚好也在学习一站式AI开发平台ModelArts,通过ModelArts学习了一些简单AI模型的训练和在线部署,然后也尝试将这些AI服务“落地”--完成前端开发部署,有幸产出了基于Koa.js的体验小Demo--今天,您存了吗?。尽管很有趣,但还是摆脱不了对*服务器的依赖,遇到应用魔方AppCube让我有了大胆的想法:结合ModelArts和AppCube实现AI在线服务的前端应用!于是,"JUST DO IT", 走上了一条无限踩坑的道路……

遇到的第一个坑,确是真·HW工程师给我挖的!调用过ModelArts在线服务的小伙伴都应该知道,我们在调用接口之前需要获取账号的AK和Sk,通过加密算法签名之后才能够正常获取调用的结果。整套流程本身是没有任务问题的,但是通过AppCube去调取ModelArts的在线服务,总是无法正常调通,一直是返回Incorrect IAM authentication information,也就是说无法正常认证,原因也无非两种,一是签名之后的token不正确,二是客户端(AppCube)的时间与服务端(ModelArts在线服务)的时间不一致且相差超过15分钟。

经过反复验证,我确认是后者,于是提了8月18日晚上就提了工单,到8月20日晚上基本确定是AppCube的signer加密算法写得有点问题,然后就是漫长的等待发版……到9月16日终于等来了新版本并修复了这个坑。

然后,我开始“三天打鱼两天晒网”,又踩到了第二个坑--AppCube的标准页面不支持匿名访问,于是我赶紧想法将标准页面转为高级页面,结果又遇到了第三个坑--由于我的标准页面含有多语言组件导致转化后的高级页面仍然无法匿名访问。于是,我开始了转向高级页面的开发……

然而,高级页面确不是我想象的那么高级,就好比等级高但是装备还是得自己打,是的,高级页面中没有基础的布局,需要自行开发组件;高级页面还需自行开发桥接器,因为AppCube的安全策略不允许前台页面直接调用后端服务。

9月的月末,基本在这些坑里折腾……

ModelArts侧的开发

对我来说,目前开(拷)发(贝)一个AI在线服务已经如探囊取物,毕竟ModelArts平台就提供了各种Copy的能力:您可以基于自动学习开发AI在线服务;您也可以基于预置算法或者订阅算法训练并部署AI模型;您还可以从AI市场直接订阅模型来开发AI在线服务,甚至还可以直接从OBS加载元模型。总之,也许您没有AI基础,通过一站式AI开发平台ModelArts就能开发并部署一个AI在线服务。为了更加简便,我采用的OBS元模型方式,分分钟部署一个Bert命名实体识别在线服务

万万没想到!ModelArts与AppCube组CP了

简单介绍一下操作流程:

0. 准备阶段

  • 注册华为云账号--这是一把金钥匙,开启了我的“云”世界。

  • 访问“我的凭证”获取“访问密钥”--也就是AK/SK,这还是一把金钥匙,是我通过开发工具访问华为云的身份凭证。

  • 开通OBS并新建桶和文件夹--这是40G容量的金桶,用来存放我Copy过来的数据、模型、算法……Y

  • 开通ModelArts--这是真金白银打造的一站式AI开发平台,我却挥霍着免费算力(学艺不精,不学无术,浪费资源)。

1. 开(拷)发(贝)阶段

从AI市场数据集下载model到OBS

请访问model-test:https://marketplace.huaweicloud.com/markets/aihub/datasets/detail/?content_id=23441bfe-8c6b-4d0c-8076-13252bde17c0, 点击页面的下载按钮,配置下OBS路径,点击下一步即可下载model到OBS

从OBS导入元模型

我们需要进入到ModelArts平台点击模型管理 - 模型 - 导入 - 从对象存储服务(OBS)中选择,这里记得选择元模型是选择model文件夹的父级,会自动识别到Tensorflow引擎。点击立即创建就会自动构建模型。

2. 部署阶段

部署是最简单的一步,等待模型构建完毕点击部署 - 在线服务一路 Next 进行模型部署上线操作。稍等片刻,部署成功之后就是熟悉的在线调试等步骤。

万万没想到!ModelArts与AppCube组CP了

AppCube侧开发

通过此次探索,我深刻地体会到AppCube的精妙之处--介是您没有玩过的船新版本。就像上文中提到的那些坑,主要还是自身技术不硬,没好好了解玩法和规则,然后就无限掉坑爬坑掉坑。不过,目标是明确的:一个页面,有输入框,有提交按钮,有结果显示,能调用AI服务。是不是超级简单?简单到我以为半个小时能搞定。结果……不说了,说多了都是泪!直接上手高级页面开发,我要做高级Copy攻城狮!

高级页面开发准备

  • 自定义UI库

在开发高级页面前,您需要学习Widget、库、桥接器、事件和动作等相关内容。没办法,摸着石头过河,如果光脚的话,容易划伤;先来一个MintUI(尽管已经过时了),如果高级页面要使用前端框架或组件库,例如流行的Vue、Bootstrap、ElementUI等,需要将其制作成Library资产,然后上传到环境中使用。本次高级页面为自定义的Widget,我想用MintUI来完成前端布局,那就需要将自定义库进行上传以及在Widget使用库。好在官方文档提供了教科书般的Demo:管理并使用库,步骤也简单:

  1. 下载MintUI并上传到高级页面 > 库

  2. 自定义Widget中引用MintUI:

packageinfo.json

Plain Text
 
 
 
 
1
"requires": [
2
  {
3
      "name": "global_Vue",
4
      "version": "100.7"
5
  },
6
  {
7
      "name":"bingobingotesthuaweicom_mintui", // 库文件名称和版本号在库详情页面获取      "version": "1.0"
8
9
  }]
 
 
  • 工具包下载

万万没想到!ModelArts与AppCube组CP了

开发高级页面比较狂拽炫酷的方式就是使用Scaffolding离线开发Widget。Scaffolding是AppCube系统提供的一个脚手架工程,方便创建本地资产工程,用于本地开发Widget、本地调测后上传至资产库,也可以通过该工具下载Widget至本地。

对了Widget的概念非常不错,玩出来Flutter的感觉,万物皆Widget!您在浏览器中看到的一个系统网页,即是一个页面。Widget是可复用的高级页面组成元素,一个高级页面由一个或多个Widget拼装而成。如果将一个高级页面看成拼图游戏的完整图案,那么Widget相当于拼图的每一小块。而我们想在本地开发Widget就需要用到工具,这个工具有点特别,其实是一个前端的NPM包,我特意查了下,这个包不是公开的,需要我们从官方文档中下载:https://obs-ap1-appengine.obs.cn-north-1.myhuaweicloud.com/usermanual/assets_starter.zip。 如果后续版权允许的话,它应该会出现在NPM公共包中。说是工具,其实是一堆代码,依赖storybook来开发组件。从代码结构和bin目录来看,工具包提供一个mango的命令行,我们可以通过mango ui开启一个本地的组件开发环境,方便后续的开发调试。当然,还需要设置并获取客户端ID和客户端密钥。

  • 项目准备

AppCube有开发环境和运行环境,我们通过AppCube的控制台进入到开发环境,新建一个空白的轻应用。从操作界面来看,应用魔方AppCube支持轻应用、行业应用、业务大屏以及移动小程序。目前构建的应用有四种发布渠道:AppCube仓库分发、Welink、讯盟以及下载到本地。关于项目的一些基本配置,这里不再赘述,具体查看官方文档的用户指南。

万万没想到!ModelArts与AppCube组CP了

高级页面开发概要

  • 在线开发脚本及服务流

理论上,我们的前端业务是不直接调用后端接口的,这次的探索,我们把调用AI在线服务交给APPCube的后端逻辑了来处理,由APPCube开发的前端业务调用后端业务,由AppCube的后端业务去调用AI在线服务,这样尽可能保障了我们传输过程中使用的敏感数据如AKSK不被泄露。于是,我们需要编写脚本,还需定义服务流、公共接口等,具体可查阅官方文档。如图中,我们定义了三个脚本:config--简单配置AKSK及AI在线服务地址;singer--签名用的,根据AKSK提供的Demo改写使之适应AppCube;getSinger--也就是调用服务的脚本,输入body,返回请求AI在线服务的响应。

万万没想到!ModelArts与AppCube组CP了

服务流也定义得十分简单,只是调用了getSinger脚本,然后在下边服务中定义基于服务流的公共接口,给到桥接器方便前端页面调用。

万万没想到!ModelArts与AppCube组CP了
  • 自定义Widget

万万没想到!ModelArts与AppCube组CP了

当我们使用上文工具时,执行mango ui能打开本地开发界面,如:http://localhost:8000/app/list。我们可以开发标准页面组件、高级页面组件以及Vue高级页面组件。通过设置,我们能直接连接到AppCube的在线环境,可以和在线环境进行交互,如组件上传下载、组件设置、组件编译等。

  • 自定义桥接器

有时候弯路走多了,路越走越弯。为什么要自定义桥接器?因为自定义高级页面中要调用服务可能就要用到桥接器!总之,从一开始的标准页面不支持匿名访问,我就走上了一条不断踩坑的不归之路。截止发稿,还有一个坑没填上,所以尽管Demo已经开发完毕,开发环境能正常调试,但是运行态还存在脚本不存在或者未激活的Bug,目前真·HW工程师正在全力技术支持中!说回怎么自定义桥接器,三步走:

1.获取Demo代码并修改

Plain Text
 
 
 
 
1
 // 核心代码
2
 var widgetBridge = thisObj.getConnectorInstanceByName('BertDemo_getAKSK');
3
 // ...
4
 thisObj.callFlowConn("BertDemo_getAKSK", {
5
           service: "/BertDemo__AKSK/0.0.1/getAKSKFlow"
6
         },{},result =>{})
 
 

2.和自定义Widget一同发布

万万没想到!ModelArts与AppCube组CP了

3.在高级页面中使用

万万没想到!ModelArts与AppCube组CP了

发布

AppCube的发布流程就像是软件开发的发布流程:先编译,再发布。在AppCube开发环境进入应用开发页面,点击左下角编译按钮进行编译,编译成功之后,页面会显示“编译XXX成功”。关闭编译成功的窗口。再点击左下角发布按钮,在“发布应用”页面选择“我的仓库”。

发布成功后,页面显示“程序包已经被成功上传到我的仓库。”。在App开发页面左侧单击我的仓库,可在“已发布”下看到发布的应用。点击顶部首页按钮进入首页,在首页单击“管理”,选择“应用管理 > 我的仓库”可查看到发布的应用。

在AppCube开发环境右上角单击用户名,选择“运行环境”。在总览页面选择“我的仓库”进入“我的仓库”页面。单击“安装”,在弹出的确认框单击“确定”。安装该应用;在左侧菜单选择“总览”,进入“总览”页,单击“应用”,进入“应用程序列表”页面……

尽管步骤有些繁琐,不过文档中有详尽的示意图,一步一步跟着多走几遍就熟悉了。

万万没想到!ModelArts与AppCube组CP了

看来目前AppCube主要是面向企业开发者,Copy攻城狮看来需要放弃了!接下来,探索一下ModelArts和鸿蒙OS看看能不能也擦出点啥来。

点击关注,第一时间了解华为云新鲜技术~

万万没想到!ModelArts与AppCube组CP了的更多相关文章

  1. 头条编程题 万万没想到之抓捕孔连顺 JavaScript

    [编程题] 万万没想到之抓捕孔连顺 时间限制:1秒 空间限制:131072K 我叫王大锤,是一名特工.我刚刚接到任务:在字节跳动大街进行埋伏,抓捕*孔连顺.和我一起行动的还有另外两名特工,我提议 ...

  2. 字节跳动:[编程题]万万没想到之聪明的编辑 Java

    时间限制:1秒 空间限制:32768K 我叫王大锤,是一家出版社的编辑.我负责校对投稿来的英文稿件,这份工作非常烦人,因为每天都要去修正无数的拼写错误.但是,优秀的人总能在平凡的工作中发现真理.我发现 ...

  3. 【问题总结】万万没想到,竟然栽在了List手里

    说明 昨天同事开发的时候遇到了一个奇怪的问题. 使用Guava做缓存,往里面存一个List,为了方便描述,称它为列表A,在另一个地方取出来,再跟列表B中的元素进行差集处理,简单来说,就像是下面这样: ...

  4. go 学习笔记之万万没想到宠物店竟然催生出面向接口编程?

    到底是要猫还是要狗 在上篇文章中,我们编撰了一则简短的小故事用于讲解了什么是面向对象的继承特性以及 Go 语言是如何实现这种继承语义的,这一节我们将继续探讨新的场景,希望能顺便讲解面向对象的接口概念. ...

  5. 万万没想到,面试中,连 ClassLoader类加载器 也能问出这么多问题…..

    1.类加载过程 类加载时机 「加载」 将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在内存上创建一个java.lang.Class对象用来封装类在方法区内的数据 ...

  6. 万万没想到,JVM内存区域的面试题也可以问的这么难?

    二.Java内存区域 1.Java内存结构 内存结构 程序计数器 当前线程所执行字节码的行号指示器.若当前方法是native的,那么程序计数器的值就是undefined. 线程私有,Java内存区域中 ...

  7. N皇后求解。万万没想到,只用一个一维数组就搞定了。还体现了回溯。

    一.啥是N皇后?先从四皇后入手 给定一个4x4的棋盘,要在棋盘上放置4个皇后.他们的位置有这样的要求,每一列,每一行,每一对角线都能有一个皇后. 你可能会对这个对角线有疑惑,其实就是每一个小正方形的对 ...

  8. 万万没想到,3D打印居然可以做这些逆天设计

    3D打印一直被冠以“高科技”头衔,似乎离我们的日常生活还很遥远.其实不然,随着技术的创新,3D打印技术逐渐深入各个领域,工业生产.商业.医学.建筑.艺术等领域都能看到3D打印技术的影子.它将会改变我们 ...

  9. 万万没想到,JVM内存结构的面试题可以问的这么难?

    在我的博客中,之前有很多文章介绍过JVM内存结构,相信很多看多我文章的朋友对这部分知识都有一定的了解了. 那么,请大家尝试着回答一下以下问题: 1.JVM管理的内存结构是怎样的? 2.不同的虚拟机在实 ...

随机推荐

  1. Hadoop技巧(01):插件,终端权限

    阅读目录 序 HDFS权限 系列索引 本文版权归mephisto和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作. 文章是哥(mephisto)写的,SourceLink 序 在ha ...

  2. Linux 下安装JRuby

    安装ruby cd git clone https://github.com/rbenv/rbenv.git ~/.rbenv echo 'export PATH="$HOME/.rbenv ...

  3. ubuntu-12.10-server中打开终端的方式

    ubuntu-12.10-server系统在图形界面的任务栏上找不到终端的踪影,可以使用以下两种方式调出 1.在图形界面中点击Dash Home 点击后搜索terminal即可 2.可以通过快捷键CT ...

  4. GDI+中发生一般性错误之文件被占用

    有多种原因可能导致这个异常出现,比如创建文件的权限不足.文件被占用等. 这里提供一个使用Stream读取图片避免文件被占用的方法. public Image GetImageFromStream(st ...

  5. 【JS】Beginner9:Arrays

    1.Lists of any kind of data 2.Index to retreve an element from the array 0 3.[] .length; .pop()/push ...

  6. Linux之Vim编辑器使用

    vim文本编辑器用于建立 编辑 显示文本文件,vim没有菜单,只有命令 在windows 平台下可使用gvim进行编写 Vim三种工作模式: 常有命令: 1.INSERT插入命令 i 在光标前插入 I ...

  7. 【点击模型学习笔记】Predicting Clicks_Estimating the Click-Through Rate for New Ads_MS_www2007

    概要: 微软研究院的人写的文章,提出用逻辑回归来解决ctr预估问题,是以后ctr的经典解决方式,经典文章. 详细内容: 名词: CPC -- cost per click CTR -- click t ...

  8. Output\TEST.sct(7): error: L6236E: No section matches selector - no section to be FIRST/LAST.

    点击错误信息,跳转到了一个.sct文件:*.o (RESET, +First) 按照如下操作,也不能解决问题.对比别的工程,也没找出问题. "操作是: Options for Target ...

  9. [js高手之路]Node.js模板引擎教程-jade速学与实战1

    环境准备: 全局安装jade: npm install jade -g 初始化项目package.json: npm init --yes 安装完成之后,可以使用 jade --help 查看jade ...

  10. Ex 6_2 假设您准备一次长途旅行..._第五次作业

    假设n个旅馆距离原点的距离存放在数组arr[0. . .n-1]中,punish[0. . .n-1]表示在某个旅馆停留时所受的的惩罚的最小值.当然在第一个旅馆停留时所受到的惩罚为0,即punish[ ...