OpenHarmony南向开发实例:【游戏手柄】

news2024/11/24 20:01:03

 介绍

基于TS扩展的声明式开发范式编程语言,以及OpenHarmony的分布式能力实现的一个手柄游戏。

完成本篇Codelab需要两台开发板,一台开发板作为游戏端,一台开发板作为手柄端,实现如下功能:

  • 游戏端呈现飞机移动、发射子弹等效果。
  • 游戏端分布式拉起手柄端FA。
  • 手柄端与游戏端建立连接,发送指令给游戏端,比如移动飞机,发射子弹和释放技能等。

最终效果图如下:

搭建OpenHarmony环境

完成本篇Codelab我们首先要完成开发环境的搭建,本示例以RK3568开发板为例,参照以下步骤进行:

  1. [获取OpenHarmony系统版本]:标准系统解决方案(二进制)。

    以3.1版本为例:

  2. 搭建烧录环境。

    1. [完成DevEco Device Tool的安装]
    2. [完成RK3568开发板的烧录]
    3. 鸿蒙开发指导:qr23.cn/AKFP8k参考前往复制转到。
  3. 搭建开发环境。

    1. 开始前请参考[工具准备],完成DevEco Studio的安装和开发环境配置。
    2. 开发环境配置完成后,请参考[使用工程向导]创建工程(模板选择“Empty Ability”),选择JS或者eTS语言开发。
    3. 工程创建完成后,选择使用[真机进行调测]。 2.鸿蒙next文档籽料+mau123789直接去v拿取

搜狗高速浏览器截图20240326151547.png

分布式组网

本章节以系统自带的音乐播放器为例(具体以实际的应用为准),介绍如何完成两台设备的分布式组网。

  1. 硬件准备:准备两台烧录相同的版本系统的RK3568开发板A、B。

  2. 开发板A、B连接同一个WiFi网络。

    打开设置-->WLAN-->点击右侧WiFi开关-->点击目标WiFi并输入密码。

  3. 将设备A,B设置为互相信任的设备。

    • 找到系统应用“音乐”。

    • 设备A打开音乐,点击左下角流转按钮,弹出列表框,在列表中会展示远端设备的id。

    • 选择远端设备B的id,另一台开发板(设备B)会弹出验证的选项框。

    • 设备B点击允许,设备B将会弹出随机PIN码,将设备B的PIN码输入到设备A的PIN码填入框中。

    配网完毕。

代码结构解读

  • [HandleEtsOpenHarmony]
  • [GameEtsOpenHarmony]

本篇Codelab只对核心代码进行讲解,对于完整代码,我们会在参考章节中提供下载方式,首先介绍一下整个工程的代码结构:

└── HandleGameApplication
	│── GameEtsOpenHarmony
	│  
	└── HandleEtsOpenHarmony

其中HandleEtsOpenHarmony为手柄端工程代码,GameEtsOpenHarmony为游戏端工程代码。

HandleEtsOpenHarmony

  • MainAbility:存放应用主页面。

    • pages/index.ets:应用主页面。
    • common/images:存放图片资源的目录。
  • ServiceAbility:存放ServiceAbility相关文件。

    • service.ts:service服务,用于跨设备连接后通讯。

GameEtsOpenHarmony

  • MainAbility:存放应用主页面。

    • pages/index.ets:应用主页面。
    • common/images:存放图片资源。
  • model:存放获取组网内的设备列表相关文件。

    • RemoteDeviceModel.ets:获取组网内的设备列表。
    • GameElement.ets:游戏端界面元素的实体类,用于封装子弹、飞机等元素的属性。
  • ServiceAbility:存放ServiceAbility相关文件。

    • service.ts:service服务,用于跨设备连接后通讯。

实现手柄端功能

  1. 实现布局和样式。

    手柄端有两个功能:向游戏端发送指令和实时获取游戏端得分数据。界面上有三个功能组件:蓝色图形组件用于控制游戏端飞机移动方向,黄色图形组件用于发射子弹,绿色图形组件用于释放技能,效果图如下:

    主要代码如下:

    @Entry
    @Component
    struct Index {
    ...
      build() {
        Stack() {
    	...
    		Text('score:' + this.score)
    		...
          Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Start, justifyContent: FlexAlign.SpaceBetween }) {
            Stack() {
              Image('/common/images/bigcircle.png')
                .width(300)
                .height(300)
              Image('/common/images/smallcircle.png')
                .width(140)
                .height(140)
                .position({ x: this.smallPosX, y: this.smallPosY }) // 30+75-35
            }
           ...
            Row() {
              Image('/common/images/a.png')
                .width(160)
                .height(160)
                .margin({ right: 20, bottom: 80 })
              Image('/common/images/b.png')
                .width(200)
                .height(200)
            }.alignItems(VerticalAlign.Bottom)
    		...
        }
      }
    }

  2. 实现摇杆功能。

    给摇杆(蓝色小圆图形)添加TouchEvent,动态改变摇杆position属性使摇杆跟随手指移动,主要代码如下:

    onTouchEvent(event: TouchEvent) {
      switch (event.type) {
        case TouchType.Down:
          this.startX = event.touches[0].screenX;
          this.startY = event.touches[0].screenY;
          break;
        case TouchType.Move:
          this.curX = event.touches[0].screenX;
          this.curY = event.touches[0].screenY;
          this.getSmallCurrentPos(this.curX - this.smallR - 60, this.curY - this.smallR - 60)
          angle = Math.round(this.calculateAngle());
          break;
        default:
          break;
      }
    }
    

  3. 计算摇杆偏移角度。

    主要代码如下:

    calculateAngle() {
      var angle = 0
      var degree = Math.atan(this.getDisAbsY() / this.getDisAbsX()) * 180 / Math.PI
      var quadrant = this.quadrant();
      switch (quadrant) {
        case this.QUADRANT_1:
        // 向右上移动
          angle = degree;
          break;
        case this.QUADRANT_2:
        // 向左上移动
          angle = 180 - degree;
          break;
        case this.QUADRANT_3:
        // 向左下移动
          angle = -180 + degree;
          break;
        case this.QUADRANT_4:
        // 向右下移动
          angle = -degree;
          break;
        default:
          angle = 0;
          break;
      }
      return angle;
    }

  4. 连接游戏端Service。

    当手柄端被游戏端拉起时,获取游戏端传递的数据:游戏端deviceId和分数score。然后通过deviceId连接游戏端Service,主要代码如下:

    aboutToAppear() {
      // 当被拉起时,通过want传递的参数同步对端界面UI
      await featureAbility.getWant((error, want) => {
        // 远端被拉起后,连接游戏端的service
        if (want.parameters.deviceId) {
          let remoteDeviceId = want.parameters.deviceId
          connectRemoteService(remoteDeviceId)
        }
      });
    }
    
    async function connectRemoteService(deviceId) {
    ...
      await featureAbility.connectAbility(
        {
          'deviceId': deviceId,
          'bundleName': "com.huawei.cookbook",
          'abilityName': "com.huawei.cookbook.ServiceAbility",
        },
        {
          onConnect: onConnectCallback,
          onDisconnect: onDisconnectCallback,
          onFailed: onFailedCallback,
        },
      );
    }

  5. 通过RPC发送数据到游戏端。

    连接游戏端Service之后,摇杆角度angle和操作类型actionType(1为发射子弹,2为释放技能)发送给游戏端,主要代码如下:

    async function sendMessageToRemoteService() {
    ...
      let option = new rpc.MessageOption();
      let data = new rpc.MessageParcel();
      let reply = new rpc.MessageParcel();
      data.writeInt(actionType);
      data.writeInt(angle);
      await mRemote.sendRequest(1, data, reply, option);
    }

实现游戏端功能

  1. 实现布局和样式。

    游戏界面主要由玩家飞机、敌机、子弹和道具(降落伞)等组成,由于敌机和子弹都是多个的,所以使用ForEach来实现,主要代码如下:

    @Entry
    @Component
    struct Index {
    
      build() {
        Stack() {
        ... 
    
          ForEach(this.bullets, item => {
            Image(item.imgSrc)
              .width(item.imgWidth)
              .height(item.imgHeight)
              .position({ x: item.positionX, y: item.positionY })
          }, item => item.timestamp.toString())
    
          ForEach(this.enemyPlanes, item => {
            Image(item.imgSrc)
              .width(item.imgWidth)
              .height(item.imgHeight)
              .position({ x: item.positionX, y: item.positionY })
          }, item => item.timestamp.toString())
    
          Image('/common/images/planeOne.png')
            .width(this.planeSize)
            .height(this.planeSize)
            .position({ x: this.planePosX, y: this.planePosY })
            .onTouch((event: TouchEvent) => {
              this.onTouchEvent(event)
            })
    
          Image('/common/images/props.png')
            .width(this.propsSize)
            .height(this.propsSize)
            .position({ x: this.propsPosX, y: this.propsPosY })
        ...
        }
        .height('100%')
        .width('100%')
      }
    }

  2. 实现游戏端元素动画效果。

    飞机、子弹和道具等元素的移动是通过动态改变Image的position属性来实现的。使用定时器setInterval每隔16ms重新设置界面元素position属性的值,主要实现代码如下:

     startGame() {
        var that = this
        setInterval(function () {   
          // 每60*16ms创建一个敌机
          if (that.num % 60 == 0) {
            that.createEnemyPlane()
          }
          // 移动子弹
          var bulletsTemp: GameElement[] = []
          for (var i = 0; i < that.bullets.length; i++) {
            var bullet = that.bullets[i]
            bullet.positionY -= 8
            // 当子弹移除屏幕外的时候,释放掉
            if (bullet.positionY > 0) {
              bulletsTemp.push(bullet)
            }
          }
          that.bullets = bulletsTemp
          // 移动飞机
          var enemyPlanesTemp: GameElement[] = []
          for (var j = 0; j < that.enemyPlanes.length; j++) {
            var enemyPlane = that.enemyPlanes[j]
            enemyPlane.positionY += 6
    
            // 当飞机移除屏幕外的时候,释放掉
            if (enemyPlane.positionY < that.screenHeight) {
              enemyPlanesTemp.push(enemyPlane)
            }
          }
          that.enemyPlanes = enemyPlanesTemp
          // 每隔 500*16ms显示降落伞
          if (that.num % 500 == 0) {
            that.getPropsFlag = true
            that.propsPosY = -that.propsSize
            that.propsPosX = Math.round((Math.random() * (that.screenWidth - that.propsSize)))
          }
          // 刷新道具位置
          if (that.propsPosY < that.screenHeight) {
            that.propsPosY += 6
          }
          that.checkCollision()
        }, 16);
      }

  3. 判断元素是否发生碰撞。

    在setInterval中改变元素位置的时候同时检测元素之间是否发生碰撞,子弹和敌机发生碰撞则分数值改变(摧毁小飞机加50分,摧毁大飞机加100分),玩家飞机和道具发生碰撞则道具加1,主要实现代码如下:

    checkCollision() {
     ...
        for (var i = 0; i < this.enemyPlanes.length; i++) {
          var enemy = this.enemyPlanes[i];
          for (var j = 0; j < this.bullets.length; j++) {
            var bullet = this.bullets[j];
            var inside = this.isInside(bullet, enemy);
            // 发生碰撞
            if (inside) {
              enemy.imgSrc = '/common/images/boom.png'
              if (enemy.flag == 1) {
                this.score += 50
                sendMessageToRemoteService(that.score)
              } else if (enemy.flag == 2) {
                this.score += 100
                sendMessageToRemoteService(that.score)
              }
              // 清除子弹
              this.enemyPlanes.splice(i, 1);
              i--;
              enemy.flag = 3
              // 清除被子弹打中敌机
              that.bullets.splice(j, 1);
              j--;
            }
          }
        }
        // 飞机和降落伞是否发生碰撞
        var isGetProps = this.isInside(myPlane, props);
        if (isGetProps && this.getPropsFlag) {
          this.getPropsFlag = false
          this.bombNum++
          this.propsPosY = 2000
        }
      }

  4. 获取设备列表。

    点击界面右上角的“电脑”图标,调用registerDeviceListCallback()发现设备列表,并弹出设备列表选择框DeviceListDialog ,选择设备后拉起远端FA。DeviceListDialog 主要代码如下:

    @CustomDialog
    export struct DeviceListDialog {
      controller: CustomDialogController
    
      build() {
        Column() {
          Text("选择设备")
            .fontWeight(FontWeight.Bold)
            .fontSize(20)
            .margin({ top: 20, bottom: 10 })
    
          List() {
            ForEach(deviceList, item => {
              ListItem() {
                Stack() {
                  Text(item)
                    .fontSize(12)
                    .margin({ top: 10 })
                }
                .onClick(() => {
                  startRemoteAbility(item)
                  this.controller.close();
                })
                .padding({ left: 30, right: 30 })
              }
            }, item => item.toString())
          }
          .height("30%")
          .align(Alignment.TopStart)
    ...
        }
      }
    }

  5. 拉起手柄端FA。

    点击设备列表获取远程设备id后,拉起手柄端FA,代码如下:

    function startRemoteAbility(deviceId) {
      var params = {
        deviceId: localDeviceId
      }
      var wantValue = {
        bundleName: 'com.huawei.cookbook',
        abilityName: 'com.huawei.cookbook.MainAbility',
        deviceId: deviceId,
        parameters: params
      };
      featureAbility.startAbility({
        want: wantValue
      }).then((data) => {
        console.info('[game] featureAbility.startAbility finished, localDeviceId=' + localDeviceId + '----deviceId:' + deviceId);
        // 拉起远端后,连接远端service
        connectRemoteService(deviceId)
      });
    }

  6. 连接手柄端Service。

    拉起手柄端FA后,连接手柄端Service,代码如下:

    async function connectRemoteService(deviceId) {
      // 连接成功的回调
      async function onConnectCallback(element, remote) {
        mRemote = remote;
      }
    ...
      if (remoteDeviceModel.deviceList.length === 0) {
        return;
      }
      await featureAbility.connectAbility(
        {
          'deviceId': deviceId,
          'bundleName': "com.huawei.cookbook",
          'abilityName': "com.huawei.cookbook.ServiceAbility",
        },
        {
          onConnect: onConnectCallback,
          onDisconnect: onDisconnectCallback,
          onFailed: onFailedCallback,
        },
      );
    }

  7. 通过RPC发送数据到手柄端。

    通过RPC将游戏分数发送给手柄端,主要代码如下:

    async function sendMessageToRemoteService(score) {
      console.log('[game]connectRemoteService sendMessageToRemoteService:')
      if (mRemote == null) {
        return;
      }
      let option = new rpc.MessageOption();
      let data = new rpc.MessageParcel();
      let reply = new rpc.MessageParcel();
      data.writeInt(score);
      await mRemote.sendRequest(1, data, reply, option);
    }
    

  8. Service发布公共事件。

    通过Service接收手柄端数据,然后使用CommonEvent模块将数据发送给FA,主要代码如下:

    class GameServiceAbilityStub extends rpc.RemoteObject {
    ...
        onRemoteRequest(code, data, reply, option) {
            console.log('[game]Service onRemoteRequest');
            var publishCallBack;
            if (code === 1) {
                // 读取手柄端发送的数据
                let actionType = data.readInt();
                let angle = data.readInt();
                reply.writeInt(100);
                var params = {
                    actionType: actionType,
                    angle: angle,
                }
                var options = {
                    code: 1,
                    data: 'init data',
                    isOrdered: true,
                    bundleName: 'com.huawei.cookbook',
                    parameters: params
                }
                publishCallBack = function () {}
                // 发布公共事件
                commonEvent.publish("publish_action", options, publishCallBack);
            } 
            return true;
        }
    }

  9. FA订阅公共事件。

    订阅公共事件,接收从Service发送的公共事件数据,actionType 为操作类型(1表示发送子弹指令,2表示释放技能指令),angle 为飞机移动的角度。接收到数据后执行手柄端发送的指令:移动玩家飞机、发射子弹和释放技能摧毁所有敌机,主要代码如下:

    subscribeEvent() {
    ...
      // 订阅公共事件回调
      function SubscribeCallBack(err, data) {
        let msgData = data.data;
        let code = data.code;
    ...
        // 处理接收到的数据data
        that.actionType = data.parameters.actionType;
        that.angle = data.parameters.angle;
    
        if (that.actionType == 1) {
          that.createBullet()
        }
        if (that.actionType == 2) {
          if (that.bombNum > 0) {
            that.bombNum--
            that.destroyAllEnemy()
          }
        }
        if (that.angle != 0) {
          that.movePlaneByHandle()
        }
      }
      //创建订阅者回调
      function CreateSubscriberCallBack(err, data) {
        subscriber = data;
        //订阅公共事件
        commonEvent.subscribe(subscriber, SubscribeCallBack);
      }
      //创建订阅者
      commonEvent.createSubscriber(subscribeInfo, CreateSubscriberCallBack);
    }

鸿蒙开发岗位需要掌握那些核心要领?

目前还有很多小伙伴不知道要学习哪些鸿蒙技术?不知道重点掌握哪些?为了避免学习时频繁踩坑,最终浪费大量时间的。

自己学习时必须要有一份实用的鸿蒙(Harmony NEXT)资料非常有必要。 这里我推荐,根据鸿蒙开发官网梳理与华为内部人员的分享总结出的开发文档。内容包含了:【ArkTS、ArkUI、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战】等技术知识点。

废话就不多说了,接下来好好看下这份资料。

如果你是一名Android、Java、前端等等开发人员,想要转入鸿蒙方向发展。可以直接领取这份资料辅助你的学习。鸿蒙OpenHarmony知识←前往。下面是鸿蒙开发的学习路线图。

针对鸿蒙成长路线打造的鸿蒙学习文档。鸿蒙(OpenHarmony )学习手册(共计1236页)与鸿蒙(OpenHarmony )开发入门教学视频,帮助大家在技术的道路上更进一步。

其中内容包含:

《鸿蒙开发基础》鸿蒙OpenHarmony知识←前往

  1. ArkTS语言
  2. 安装DevEco Studio
  3. 运用你的第一个ArkTS应用
  4. ArkUI声明式UI开发
  5. .……

《鸿蒙开发进阶》鸿蒙OpenHarmony知识←前往

  1. Stage模型入门
  2. 网络管理
  3. 数据管理
  4. 电话服务
  5. 分布式应用开发
  6. 通知与窗口管理
  7. 多媒体技术
  8. 安全技能
  9. 任务管理
  10. WebGL
  11. 国际化开发
  12. 应用测试
  13. DFX面向未来设计
  14. 鸿蒙系统移植和裁剪定制
  15. ……

《鸿蒙开发实战》鸿蒙OpenHarmony知识←前往

  1. ArkTS实践
  2. UIAbility应用
  3. 网络案例
  4. ……

最后

鸿蒙是完全具备无与伦比的机遇和潜力的;预计到年底将有 5,000 款的应用完成原生鸿蒙开发,这么多的应用需要开发,也就意味着需要有更多的鸿蒙人才。鸿蒙开发工程师也将会迎来爆发式的增长,学习鸿蒙势在必行!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1600663.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机视觉——OpenCV Python基于颜色识别的目标检测

1. 计算机视觉中的颜色空间 颜色空间在计算机视觉领域的应用非常广泛&#xff0c;它们在图像和视频处理、物体检测等任务中扮演着重要角色。颜色空间的主要作用是将颜色以数值形式表示出来&#xff0c;这样计算机算法就能够对其进行处理和分析。不同的颜色空间有着不同的特点和…

Web3D智慧医院平台(HTML5+Threejs)

智慧医院的建设将借助物联网、云计算、大数据、数字孪生等技术&#xff0c;以轻量化渲染、极简架构、三维可视化“一张屏”的形式&#xff0c;让医院各大子系统管理既独立又链接&#xff0c;数据相互融合及联动。 建设医院物联网应用的目标对象&#xff08;人、物&#xff09;都…

基于afx透明视频的视觉增强前端方案

作者 | 青玉 导读 本文介绍了增长前端团队自研的Webview框架下透明视频视觉增强方案&#xff0c;该方案在保证对视觉进行高度还原的同时可投入更少的开发成本&#xff0c;还能获得更优的前端性能表现。文章首先分析了市面上动画方案的优缺点&#xff0c;然后详细介绍了透明视频…

CentOS下GitLab的安装部署_centos 安装部署 gitlab,2024年最新软件测试开发岗还不会这些问题

先自我介绍一下&#xff0c;小编浙江大学毕业&#xff0c;去过华为、字节跳动等大厂&#xff0c;目前阿里P7 深知大多数程序员&#xff0c;想要提升技能&#xff0c;往往是自己摸索成长&#xff0c;但自己不成体系的自学效果低效又漫长&#xff0c;而且极易碰到天花板技术停滞…

HTML段落标签、换行标签、文本格式化标签与水平线标签

目录 HTML段落标签 HTML换行标签 HTML格式化标签 加粗标签 倾斜标签 删除线标签 下划线标签 HTML水平线标签 HTML段落标签 在网页中&#xff0c;要把文字有条理地显示出来&#xff0c;就需要将这些文字分段显示。在 HTML 标签中&#xff0c;<p>标签用于定义段落…

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之十二 简单人脸识别

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之十二 简单人脸识别 目录 Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之十二 简单人脸识别 一、简单介绍 二、简单人脸识别实现原理 三、简单人脸识别案例实现简…

基于小程序实现的餐饮外卖系统

作者主页&#xff1a;Java码库 主营内容&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app等设计与开发。 收藏点赞不迷路 关注作者有好处 文末获取源码 技术选型 【后端】&#xff1a;Java 【框架】&#xff1a;spring…

如何在PPT中获得网页般的互动效果

如何在PPT中获得网页般的互动效果 效果可以看视频 PPT中插入网页有互动效果 当然了&#xff0c;获得网页般的互动效果&#xff0c;最简单的方法就是在 PPT 中插入网页呀。 那么如何插入呢&#xff1f; 接下来为你讲解如何获得&#xff08;此方法在 PowerPoint中行得通&#…

华为配置静态ARP示例

华为配置静态ARP示例 组网图形 图1 配置静态ARP组网图 静态ARP简介配置注意事项组网需求配置思路操作步骤配置文件相关信息 静态ARP简介 静态ARP表项是指网络管理员手工建立IP地址和MAC地址之间固定的映射关系。 正常情况下网络中设备可以通过ARP协议进行ARP表项的动态学习&…

差速机器人模型LQR 控制仿真——路径模拟

LQR路径跟踪要求路径中带角度&#xff0c;即坐标&#xff08;x,y,yaw&#xff09;&#xff0c;而一般我们的规划出来的路径不带角度。这里通过总结相关方法&#xff0c;并提供一个案例。 将点路径拟合成一条完整的线路径算法 将点路径拟合成一条完整的线路径是一个常见的问题…

C#语法知识之变量

2.变量 一、知识点 1、折叠代码 //#region按Tab键#region MyRegion(描述)#endregion //本质是编译器提供给我们的预处理指令&#xff0c;发布代码是会被自动删除2、声明变量和变量类型 ​ 变量就是可以变化的容器&#xff0c;用来存储各种不同类型数值的一个容器&#xff1b…

jenkins从节点配置说明

目的 打包构建时使用从节点&#xff0c;从节点所在服务器配置4C8G5000G&#xff08;服务器2&#xff09; 前提 首先在服务器1上部署jenkins服务&#xff0c;即主节点&#xff0c;默认节点名称为master 步骤 1&#xff09;登录进入jenkins平台&#xff0c;在系统设置中&…

KT-105小动物人工呼吸机

咳咳&#xff0c;请各位小伙伴们注意啦&#xff01;我们要聊的主题可是相当高大上——小动物呼吸机&#xff01; 我们得先了解一下什么是小动物呼吸机。这可不是一般的机器哦&#xff0c;它是一种实验设备&#xff0c;主要用于各种各样的科学研究实验中。比如&#xff0c;在基…

ICV:《中美量子产业融资比较分析》

近日&#xff0c;全球前沿科技咨询公司ICV发布了A Comparative Analysis of Quantum Industry Financing in the U.S and China&#xff08;美国和中国量子产业融资比较分析&#xff09;报告。该报告旨在对中美两国在量子技术领域的投融资情况进行比较分析&#xff0c;探讨其差…

python解释器安装路径查询以及版本查询

查询安装路径 1、利用脚本&#xff1a; 路径: import sys import osprint(当前 Python 解释器路径&#xff1a;) print(sys.executable)运行结果&#xff1a; 目录: print(当前 Python 解释器目录&#xff1a;) print(os.path.dirname(sys.executable))运行结果&#xff1a…

十大排序——11.十大排序的比较汇总及Java中自带的排序算法

这篇文章对排序算法进行一个汇总比较&#xff01; 目录 0.十大排序汇总 0.1概述 0.2比较和非比较的区别 0.3基本术语 0.4排序算法的复杂度及稳定性 1.冒泡排序 算法简介 动图演示 代码演示 应用场景 算法分析 2.快速排序 算法简介 动图演示 代码演示 应用场景…

AGI的智力有可能在两年内超过人类水平

特斯拉CEO埃隆马斯克近日与挪威银行投资管理基金CEO坦根的访谈中表示&#xff0c;AGI的智力将在两年内可能超过人类智力&#xff0c;在未来五年内&#xff0c;AI的能力很可能超过所有人类。 马斯克透漏&#xff0c;去年人工智能发展过程中的主要制约因素是缺少高性能芯片&#…

信息集成:打通数据、深化业务协同与生产调度,降本增效第一步 | 创新场景...

ITValue 痛点 对于三一集团这样生产线复杂的大型组织&#xff0c;一辆重卡的生产由底盘、动力、车身、座舱、智驾网联等多个不同区域组成&#xff0c;各自使用工具与业务系统&#xff0c;彼此之间的数据各自孤立。如何打通业务部门的信息传递&#xff0c;深化业务协同与生产调度…

第11章 数据仓库和数据智能知识点梳理

第11章 数据仓库和数据智能知识点梳理&#xff08;附带页码&#xff09; ◼ 数据仓库&#xff08;Data Warehouse&#xff0c;DW&#xff09;&#xff1a;始于 20 世纪 80 年代&#xff0c;发展于 20 世纪 90 年代&#xff0c;后与商务智能&#xff08;Business Inteligence,BI…

【前后端的那些事】SpringBoot 基于内存的ip访问频率限制切面(RateLimiter)

文章目录 1. 什么是限流2. 常见的限流策略2.1 漏斗算法2.2 令牌桶算法2.3 次数统计 3. 令牌桶代码编写4. 接口测试5. 测试结果 1. 什么是限流 限流就是在用户访问次数庞大时&#xff0c;对系统资源的一种保护手段。高峰期&#xff0c;用户可能对某个接口的访问频率急剧升高&am…