Unity 封装一个依赖于MonoBehaviour的计时器(下) 链式调用

news2025/3/14 21:52:57

[Unity] 封装一个依赖于MonoBehaviour的计时器(上)-CSDN博客

目录

1.加入等待间隔时间"永远'执行方法

   2.修改为支持链式调用

实现链式调用

管理"链式"调度顺序

  3.测试       

        即时方法​编辑

        "永久"方法 

        链式调用 

​4.总结


1.加入等待间隔时间"永远'执行方法

      我将这个计时器修改为了支持链式调用,不过我还是发现了一个问题,有些地方的计时器要求是这样子的

using UnityEngine;

public class RegularTimer : MonoBehaviour
{
    private float timer = 0f;
    public float targetTime = 5f;

    private void Update()
    {
        timer += Time.deltaTime;
        if (timer >= targetTime)
        {
            // 达到目标时间,执行相应操作
            Debug.Log("Timer reached!");
            timer = 0f;
        }
    }
}

        但是我的协程计时器之中并没有随游戏"无限"进行的间隔计时器

        所以添加了一个无限循环执行的函数

 #region 无限循环执行
    /// <summary>
    /// 按固定时间间隔无限循环执行回调
    /// </summary>
    /// <param name="spacing">时间间隔(秒)</param>
    /// <param name="callback">回调函数</param>
    public void LoopForever(float spacing, Action callback)
    {
        if (CheckTime(spacing))
        {
            StartCoroutine(LoopForeverHandle(spacing, () => callback?.Invoke()));
        }
    }

    public void LoopForever<T>(float spacing, T param, Action<T> callback)
    {
        if (CheckTime(spacing))
        {
            StartCoroutine(LoopForeverHandle(spacing, () => callback?.Invoke(param)));
        }
    }

    public void LoopForever<T, K>(float spacing, T param1, K param2, Action<T, K> callback)
    {
        if (CheckTime(spacing))
        {
            StartCoroutine(LoopForeverHandle(spacing, () => callback?.Invoke(param1, param2)));
        }
    }

    private IEnumerator LoopForeverHandle(float spacing, Action action)
    {
        while (true)
        {
            yield return new WaitForSeconds(spacing);
            action?.Invoke();
        }
    }
    #endregion

   2.修改为支持链式调用

       有两个要点:

       实现链式调用

        先别管怎么去写 看看怎么使用

     TimeManager.Instance.BeginChain().WaitTime().WaitRealTime();

        如果想要每一次"点"出后面的方法 要求是Instance一致

        所以要是方法的返回值是本身不就行了

    public TimeManager BeginChain()
    {
        enumeratorQ.Clear();//别管这一句
        return this;
    }

        完美解决问题 

        管理"链式"调度顺序

         因为链式调用是多个且有序的,所以一定要有个容器去存储,我画个图

         所以有没有想起什么? 先进先出 队列不就是这样的吗?

        en造数据结构与算法 c#语言 数组实现队列很难???看我一击破之!!!-CSDN博客

  // 链式调用的队列
  private Queue<IEnumerator> enumeratorQ = new Queue<IEnumerator>();
  private bool isChaining; // 是否正在执行队列

        然后就是自己解决如何去跑了 ,很简单,有调用就入队,跑起来就出队,全权由该队列管理即可

   

  public TimeManager BeginChain()
  {
      enumeratorQ.Clear();
      return this;
  }

  /// <summary>
  /// 开始执行链式调用
  /// </summary>
  private void ExecuteChain()
  {
      if (!isChaining && enumeratorQ.Count > 0)
      {
          StartCoroutine(RunChain());
      }
  }
  /// <summary>
  /// 出队跑
  /// </summary>
  /// <returns></returns>
  private IEnumerator RunChain()
  {
      isChaining = true;
      while (enumeratorQ.Count > 0)
      {
           yield return StartCoroutine(enumeratorQ.Dequeue());
      }
      isChaining = false;
  }
 public TimeManager WaitTime(float waitTime, Action callback)
 {
     if (CheckTime(waitTime))
     {
         enumeratorQ.Enqueue(WaitTimeHandle(waitTime, () => callback?.Invoke()));
         ExecuteChain();
     }
     return this;
 }

  3.测试       

        即时方法

        

"永久"方法 

   private void Start()
   {
       //1秒后执行
       TimeManager.Instance.LoopForever(1,Callback);

    
   }

   private void Callback() { 
       Debug.Log("我是哈基咩");
   }

链式调用 

using System;
using UnityEngine;

public class Test : MonoBehaviour
{
    private void Start()
    {
        // 链式调用测试
        TimeManager.Instance.BeginChain()
            // 1秒后执行 Callback
            .WaitTime(1f, Callback)
            // 等待120帧后执行 Callback1,并传递字符串参数
            .WaitFrame<string>(120, "在120帧后执行", Callback1)
            // 本帧结束时执行 Callback2,传递int和string参数
            .WaitForEndOfFrame<int, string>(520, "在本帧调的最后执行", Callback2)
            // 等待5秒,过程中反馈进度(Progress),完成后执行 Callback
            .WaitTimeWithProgress(5f, Progress, Callback);
    }

    private void Callback()
    {
        Debug.Log("我是哈基咩");
    }

    private void Callback1(string param1)
    {
        Debug.Log($"帧:{Time.frameCount},我是哈基咩: {param1}");
    }

    private void Callback2(int param1, string param2)
    {
        Debug.Log($"帧:{Time.frameCount},我是哈基咩: {param1} 我是咩咩 {param2}");
    }

    private void Progress(float param1)
    {
        Debug.Log($"我是哈基咩: {param1}");
    }
}

 4.总结

         这是一次很好的体验 我从来没写过链式调用的代码 原来是这么一回事

        同时也做好了一个计时器以后就不用在每一个需要的地方进行update里面手搓辣

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TimeManager : MonoBehaviour
{
    private static TimeManager instance;
    public static TimeManager Instance => instance;

    // 链式调用的队列
    private Queue<IEnumerator> enumeratorQ = new Queue<IEnumerator>();
    private bool isChaining; // 是否正在执行队列

    private void Awake()
    {
        if (instance == null)
        {
            instance = this;
        }
    }

    public TimeManager BeginChain()
    {
        enumeratorQ.Clear();
        return this;
    }

    /// <summary>
    /// 开始执行链式调用
    /// </summary>
    private void ExecuteChain()
    {
        if (!isChaining && enumeratorQ.Count > 0)
        {
            StartCoroutine(RunChain());
        }
    }
    /// <summary>
    /// 出队跑
    /// </summary>
    /// <returns></returns>
    private IEnumerator RunChain()
    {
        isChaining = true;
        while (enumeratorQ.Count > 0)
        {
             yield return StartCoroutine(enumeratorQ.Dequeue());
        }
        isChaining = false;
    }

    #region 检查合法
    private bool CheckCount(int count)
    {
        if (count < 0)
        {
            Debug.LogError("循环次数不能为负数!");
            return false;
        }
        return true;
    }

    private bool CheckTime(float time)
    {
        if (time < 0)
        {
            Debug.LogError("等待时间不能为负数!");
            return false;
        }
        return true;
    }

    #endregion

    #region 等待固定时间秒
    public TimeManager WaitTime(float waitTime, Action callback)
    {
        if (CheckTime(waitTime))
        {
            enumeratorQ.Enqueue(WaitTimeHandle(waitTime, () => callback?.Invoke()));
            ExecuteChain();
        }
        return this;
    }

    public TimeManager WaitTime<T>(float waitTime, T param, Action<T> callback)
    {
        if (CheckTime(waitTime))
        {
            enumeratorQ.Enqueue(WaitTimeHandle(waitTime, () => callback?.Invoke(param)));
            ExecuteChain();
        }
        return this;
    }

    public TimeManager WaitTime<T, K>(float waitTime, T param1, K param2, Action<T, K> callback)
    {
        if (CheckTime(waitTime))
        {
            enumeratorQ.Enqueue(WaitTimeHandle(waitTime, () => callback?.Invoke(param1, param2)));
            ExecuteChain();
        }
        return this;
    }

    private IEnumerator WaitTimeHandle(float waitTime, Action action)
    {
        yield return new WaitForSeconds(waitTime);
        action?.Invoke();
    }
    #endregion

    #region 等待固定时间秒(不受缩放影响)
    public TimeManager WaitRealTime(float waitTime, Action callback)
    {
        if (CheckTime(waitTime))
        {
            enumeratorQ.Enqueue(WaitRealTimeHandle(waitTime, () => callback?.Invoke()));
            ExecuteChain();
        }
        return this;
    }

    public TimeManager WaitRealTime<T>(float waitTime, T param, Action<T> callback)
    {
        if (CheckTime(waitTime))
        {
            enumeratorQ.Enqueue(WaitRealTimeHandle(waitTime, () => callback?.Invoke(param)));
            ExecuteChain();
        }
        return this;
    }

    public TimeManager WaitRealTime<T, K>(float waitTime, T param1, K param2, Action<T, K> callback)
    {
        if (CheckTime(waitTime))
        {
            enumeratorQ.Enqueue(WaitRealTimeHandle(waitTime, () => callback?.Invoke(param1, param2)));
            ExecuteChain();
        }
        return this;
    }

    private IEnumerator WaitRealTimeHandle(float waitTime, Action action)
    {
        yield return new WaitForSecondsRealtime(waitTime);
        action?.Invoke();
    }
    #endregion

    #region 按固定时间间隔循环执行
    /// <summary>
    /// 按固定时间间隔循环执行
    /// </summary>
    /// <param name="spacing"></param>
    /// <param name="overNumber"></param>
    /// <param name="callback"></param>
    /// <returns></returns>
    public TimeManager LoopTime(float spacing, int overNumber, Action callback)
    {
        if (CheckTime(spacing) && CheckCount(overNumber))
        {
            enumeratorQ.Enqueue(LoopTimeHandle(spacing, overNumber, () => callback?.Invoke()));
            ExecuteChain();
        }
        return this;
    }

    public TimeManager LoopTime<T>(float spacing, int overNumber, T param, Action<T> callback)
    {
        if (CheckTime(spacing) && CheckCount(overNumber))
        {
            enumeratorQ.Enqueue(LoopTimeHandle(spacing, overNumber, () => callback?.Invoke(param)));
            ExecuteChain();
        }
        return this;
    }

    public TimeManager LoopTime<T, K>(float spacing, int overNumber, T param1, K param2, Action<T, K> callback)
    {
        if (CheckTime(spacing) && CheckCount(overNumber))
        {
            enumeratorQ.Enqueue(LoopTimeHandle(spacing, overNumber, () => callback?.Invoke(param1, param2)));
            ExecuteChain();
        }
        return this;
    }

    private IEnumerator LoopTimeHandle(float spacing, int overNumber, Action action)
    {
        for (int i = 0; i < overNumber; i++)
        {
            yield return new WaitForSeconds(spacing);
            action?.Invoke();
        }
    }
    #endregion

    #region 等待固定帧执行一次
    /// <summary>
    /// 等待固定帧执行一次
    /// </summary>
    /// <param name="frameCount"></param>
    /// <param name="callback"></param>
    /// <returns></returns>
    public TimeManager WaitFrame(int frameCount, Action callback)
    {
        if (CheckCount(frameCount))
        {
            enumeratorQ.Enqueue(WaitFrameHandle(frameCount, () => callback?.Invoke()));
            ExecuteChain();
        }
        return this;
    }

    public TimeManager WaitFrame<T>(int frameCount, T param, Action<T> callback)
    {
        if (CheckCount(frameCount))
        {
            enumeratorQ.Enqueue(WaitFrameHandle(frameCount, () => callback?.Invoke(param)));
            ExecuteChain();
        }
        return this;
    }

    public TimeManager WaitFrame<T, K>(int frameCount, T param1, K param2, Action<T, K> callback)
    {
        if (CheckCount(frameCount))
        {
            enumeratorQ.Enqueue(WaitFrameHandle(frameCount, () => callback?.Invoke(param1, param2)));
            ExecuteChain();
        }
        return this;
    }

    private IEnumerator WaitFrameHandle(int frameCount, Action action)
    {
        for (int i = 0; i < frameCount; i++)
        {
            yield return null;
        }
        action?.Invoke();
    }
    #endregion

    #region 进度反馈
    /// <summary>
    /// 进度反馈
    /// </summary>
    /// <param name="waitTime"></param>
    /// <param name="progressCallback"></param>
    /// <param name="completeCallback"></param>
    /// <returns></returns>
    public TimeManager WaitTimeWithProgress(float waitTime, Action<float> progressCallback, Action completeCallback)
    {
        if (CheckTime(waitTime))
        {
            enumeratorQ.Enqueue(ProgressTimer(waitTime, progressCallback, completeCallback));
            ExecuteChain();
        }
        return this;
    }

    public TimeManager WaitTimeWithProgress<T>(float waitTime, T param, Action<float, T> progressCallback, Action<T> completeCallback)
    {
        if (CheckTime(waitTime))
        {
            enumeratorQ.Enqueue(ProgressTimer(waitTime, param, progressCallback, completeCallback));
            ExecuteChain();
        }
        return this;
    }

    public TimeManager WaitTimeWithProgress<T, K>(float waitTime, T param1, K param2, Action<float, T, K> progressCallback, Action<T, K> completeCallback)
    {
        if (CheckTime(waitTime))
        {
            enumeratorQ.Enqueue(ProgressTimer(waitTime, param1, param2, progressCallback, completeCallback));
            ExecuteChain();
        }
        return this;
    }

    private IEnumerator ProgressTimer(float duration, Action<float> progress, Action complete)
    {
        float startTime = Time.time;
        while (Time.time - startTime < duration)
        {
            progress?.Invoke((Time.time - startTime) / duration);
            yield return null;
        }
        complete?.Invoke();
    }

    private IEnumerator ProgressTimer<T>(float duration, T param, Action<float, T> progress, Action<T> complete)
    {
        float startTime = Time.time;
        while (Time.time - startTime < duration)
        {
            progress?.Invoke((Time.time - startTime) / duration, param);
            yield return null;
        }
        complete?.Invoke(param);
    }

    private IEnumerator ProgressTimer<T, K>(float duration, T param1, K param2, Action<float, T, K> progress, Action<T, K> complete)
    {
        float startTime = Time.time;
        while (Time.time - startTime < duration)
        {
        
            progress?.Invoke((Time.time - startTime) / duration, param1, param2);
            yield return null;
        }
        complete?.Invoke(param1, param2);
    }
    #endregion

    #region 等待当前帧结束执行回调
    /// <summary>
    /// 等待当前帧结束执行回调
    /// </summary>
    /// <param name="callback"></param>
    /// <returns></returns>
    public TimeManager WaitForEndOfFrame(Action callback)
    {
        enumeratorQ.Enqueue(WaitForEndOfFrameHandle(callback));
        ExecuteChain();
        return this;
    }

    public TimeManager WaitForEndOfFrame<T>(T param, Action<T> callback)
    {
        enumeratorQ.Enqueue(WaitForEndOfFrameHandle(param, callback));
        ExecuteChain();
        return this;
    }

    public TimeManager WaitForEndOfFrame<T, K>(T param1, K param2, Action<T, K> callback)
    {
        enumeratorQ.Enqueue(WaitForEndOfFrameHandle(param1, param2, callback));
        ExecuteChain();
        return this;
    }

    private IEnumerator WaitForEndOfFrameHandle(Action callback)
    {
        yield return new WaitForEndOfFrame();
        callback?.Invoke();
    }

    private IEnumerator WaitForEndOfFrameHandle<T>(T param, Action<T> callback)
    {
        yield return new WaitForEndOfFrame();
        callback?.Invoke(param);
    }

    private IEnumerator WaitForEndOfFrameHandle<T, K>(T param1, K param2, Action<T, K> callback)
    {
        yield return new WaitForEndOfFrame();
        callback?.Invoke(param1, param2);
    }
    #endregion

    #region 无限循环执行 
    /// <summary>
    /// 放在链式的最后!
    /// </summary>
    /// <param name="spacing"></param>
    /// <param name="callback"></param>
    /// <returns></returns>
    public TimeManager LoopForever(float spacing, Action callback)
    {
        if (CheckTime(spacing))
        {
            enumeratorQ.Enqueue(LoopForeverHandle(spacing, () => callback?.Invoke()));
            ExecuteChain();
        }
        return this;
    }

    public TimeManager LoopForever<T>(float spacing, T param, Action<T> callback)
    {
        if (CheckTime(spacing))
        {
            enumeratorQ.Enqueue(LoopForeverHandle(spacing, () => callback?.Invoke(param)));
            ExecuteChain();
        }
        return this;
    }

    public TimeManager LoopForever<T, K>(float spacing, T param1, K param2, Action<T, K> callback)
    {
        if (CheckTime(spacing))
        {
            enumeratorQ.Enqueue(LoopForeverHandle(spacing, () => callback?.Invoke(param1, param2)));
            ExecuteChain();
        }
        return this;
    }

    private IEnumerator LoopForeverHandle(float spacing, Action action)
    {
        while (true)
        {
            yield return new WaitForSeconds(spacing);
            action?.Invoke();
            //如果前期链式调用的时候把它算进去 就会卡死掉
            if (enumeratorQ.Count > 0)
                yield break;
        }
    }
    #endregion

    public void Stop(IEnumerator func)
    {
        StopCoroutine(func);
        //停止退队的时候要还一个新的回去 不然其仍在队列之中
        if (enumeratorQ.Contains(func))
        {
            var tempQueue = new Queue<IEnumerator>();
            while (enumeratorQ.Count > 0)
            {
                IEnumerator item = enumeratorQ.Dequeue();
                if (item != func)
                {
                    tempQueue.Enqueue(item);
                }
            }
            enumeratorQ = tempQueue;
        }
    }

    public void StopAll()
    {
        StopAllCoroutines();
        enumeratorQ.Clear();
        isChaining = false;
    }
}

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

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

相关文章

套接字缓冲区以及Net_device

基础网络模型图 一般网络设计分为三层架构和五层设计&#xff1a; 一、三层架构 用户空间的应用层 位于最上层&#xff0c;是用户直接使用的网络应用程序&#xff0c;如浏览器、邮件客户端、即时通讯软件等。这些程序通过系统调用&#xff08;如 socket 接口&#xff09;向内核…

2024下半年真题 系统架构设计师 案例分析

案例一 软件架构 关于人工智能系统的需求分析&#xff0c;给出十几个需求。 a.系统发生业务故障时&#xff0c;3秒内启动 XXX&#xff0c;属于可靠性 b.系统中的数据进行导出&#xff0c;要求在3秒内完成&#xff0c;属于可用性 c.质量属性描述&#xff0c;XXX&#xff0c;属…

c++介绍智能指针 十二(2)

智能指针share_ptr,与unique_ptr不同&#xff0c;多个shar_ptr对象可以共同管理一个指针&#xff0c;它们通过一个共同的引用计数器来管理指针。当一个智能指针对象销毁时&#xff0c;计数器减一。当计数器为0时&#xff0c;会将所指向的内存对象释放。 #include<memory>…

西门子S7-1200 PLC远程调试技术方案(巨控GRM532模块)

三步快速实现远程调试 硬件部署 准备西门子S7-1200 PLC、巨控GRM552YW-C模块及编程电脑。GRM552YW-C通过网口与PLC连接&#xff0c;支持4G/5G/Wi-Fi/有线网络接入&#xff0c;无需复杂布线。 软件配置 安装GVCOM3配置软件&#xff0c;注册模块&#xff08;输入唯一序列号与密…

Mac上更改默认应用程序

Mac上为某些文件设置默认打开应用的时候&#xff0c;刚开始是通过打开方式&#xff0c;其他里面&#xff0c;勾选始终以此方式打开&#xff0c;但实际上这个功能并不太好用&#xff0c;经常会让人误以为已经设置好了。但是实际上只是在当前目录起作用。真正解决这个问题可以按照…

【开源+代码解读】Search-R1:基于强化学习的检索增强大语言模型框架3小时即可打造个人AI-search

大语言模型(LLMs)在处理复杂推理和实时信息检索时面临两大挑战:知识局限性(无法获取最新外部知识)和检索灵活性不足(传统方法依赖固定检索流程)。现有方法如检索增强生成(RAG)和工具调用(Tool-Use)存在以下问题: RAG:单轮检索导致上下文不足,无法适应多轮交互场景…

贪心算法和遗传算法优劣对比——c#

项目背景&#xff1a;某钢管厂的钢筋原材料为 55米&#xff0c;工作需要需切割 40 米&#xff08;1段&#xff09;、11 米&#xff08;15 段&#xff09;等 4 种规格 &#xff0c;现用贪心算法和遗传算法两种算法进行计算&#xff1a; 第一局&#xff1a;{ 40, 1 }, { 11, 15…

网络安全防护总体架构 网络安全防护工作机制

1 实践内容 1.1 安全防范 为了保障"信息安全金三角"的CIA属性、即机密性、完整性、可用性&#xff0c;信息安全领域提出了一系列安全模型。其中动态可适应网络安全模型基于闭环控制理论&#xff0c;典型的有PDR和P^2DR模型。 1.1.1 PDR模型 信息系统的防御机制能…

SpringCloud带你走进微服务的世界

认识微服务 随着互联网行业的发展&#xff0c;对服务的要求也越来越高&#xff0c;服务架构也从单体架构逐渐演变为现在流行的微服务架构。这些架构之间有怎样的差别呢&#xff1f; 单体架构 单体架构&#xff1a;将业务的所有功能集中在一个项目中开发&#xff0c;打成一个包部…

Python设计模式 - 建造者模式

定义 建造者模式是一种创建型设计模式&#xff0c;主要用于构建包含多个组成部分的复杂对象。它将对象的构建过程与表示分离&#xff0c;使得同样的构建过程可以创建不同的对象表示。 结构 抽象建造者&#xff08;Builder&#xff09;&#xff1a;声明创建产品的各个部件的方…

在 Ubuntu 上安装和配置 Docker 的完整指南

Docker 是一个开源的平台&#xff0c;旨在简化应用程序的开发、部署和运行。通过将应用程序及其依赖项打包到容器中&#xff0c;Docker 确保应用程序可以在任何环境中一致地运行。 目录 前言安装前的准备安装 Docker 步骤 1&#xff1a;更新包索引步骤 2&#xff1a;安装必要…

网络安全之数据加密(DES、AES、RSA、MD5)

刚到公司时&#xff0c;我的工作就是为app端提供相应的接口。之前app使用的是PHP接口&#xff0c;对数据加密方面做得比较少。到使用java接口时&#xff0c;老大开始让我们使用DES加密&#xff0c;进行数据传输&#xff0c;但是后来觉得DES是对称加密&#xff0c;密钥存在客户端…

基于SpringBoot的“校园周边美食探索及分享平台”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“校园周边美食探索及分享平台”的设计与实现&#xff08;源码数据库文档PPT) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 校园周边美食探索及分享平台结构图…

vscode关闭仓库后如何打开

vscode源代码管理->更改->代码 关闭仓库后如何打开。 关闭仓库操作 打开仓库操作 1.按下 Ctrl Shift P&#xff08;Windows/Linux&#xff09;或 Cmd Shift P&#xff08;Mac&#xff09;打开命令面板。 2.在命令面板中输入 Git: Open Repository&#xff0c;然后选…

DeepSeek-R1 论文阅读总结

1. QA问答&#xff08;我的笔记&#xff09; Q1: DeepSeek如何处理可读性问题&#xff1f; 通过构建冷启动数据&#xff08;数千条长CoT数据&#xff09;微调基础模型&#xff0c;结合多阶段训练流程&#xff08;RL训练、拒绝采样生成SFT数据&#xff09;&#xff0c;并优化输…

Linux 》》Ubuntu 18 LTS 之后的版本 修改IP地址 主机名

进入目录 /etc/netplan 修改 50-cloud-init.yaml 》保存文件后&#xff0c;执行以下命令应用更改&#xff1a; sudo netplan apply 》》 DHCP模式 修改主机名 hostnamectl set-hostname xxxx 修改cloud.cfg 防止重启主机名还原 但测试下来 不修改&#xff0c; 重启 也不会还…

泰山派开发之—Ubuntu24.04下Linux开发环境搭建

简介 最近翻到了吃灰已久的泰山派&#xff0c;是刚出来的时候用优惠券买的&#xff0c;当时价格挺便宜的&#xff0c;最近给它翻出来了&#xff0c;打算试试做个项目。买的泰山派容量是2G16G&#xff0c;SOC芯片使用的是RK3566&#xff0c;搭载1TOP算力的NPU&#xff0c;并且具…

哈尔滨算力服务器托管推荐-青蛙云

哈尔滨年平均气温3.5摄氏度&#xff0c;有发展云计算和算力数据中心的天然优势 &#xff0c;今天为哈尔滨算力服务器托管服务商&#xff1a;青蛙云&#xff0c;黑龙江经营17年的老牌IDC服务商。 先来了解下算力服务器&#xff1a; 算力服务器&#xff0c;尤其是那些用于运行人…

openharmony体验

openharmony5 去年已经出来了 如果以前做过android开发的&#xff0c;学起来不难&#xff0c;关键 1&#xff1a;环境 DevEco Studio 5.0.3 Beta2 https://developer.huawei.com/consumer/cn/deveco-studio/ win10_64bit CPU amd64(不是arm的) 2:安装 执行EXE 安装就行&#x…

[Ai 力扣题单] 数组基本操作篇 27/704/344/386

题单分类:DeepSeek刷力扣辅助题单 存留记录-CSDN博客 27 27. 移除元素 - 力扣&#xff08;LeetCode&#xff09; 这道题就一个点 1.数组在内存上连续 所以要么赋值覆盖,要么移动覆盖,但是它要求了前 k 个元素 所以只能移动覆盖 所以我有了如下思考过程: 3223 , 3举例 如果是…