OpenHarmony C/C++三方库移植适配

简介

众所周知,C/C++三方库相对与JS/ETS的三方组件来说,其运行效率高。那如何将一个C/C++三方库移植到OH系统上呢?本文将介绍如何快速高效的移植一个C/C++三方库到OpenHarmony上。

C/C++三方库适配问题与解决方案

由上图可以看出,三方库移植的流程以及现状。

三方库运行时依赖分析

针对运行时依赖的分析,我们开发了对应的C/C++三方库风险识别工具,通过该工具可以扫描出三方库是否有对NDK,OpenGL等接口的依赖,以及是否有bionic的C库接口的依赖等。该工具可以让我们快速的对一个C/C++三方库进行风险识别。

工具的使用请参照C/C++三方库风险识别工具使用方法.

三方库编译构建

OpenHarmony的应用编译开发使用的是DevEco Studio,而该工具目前只支持cmake的编译,但开源的C/C++三方库编译方式多样化,包含cmake,configured等方式。对于原生库cmake无法在IDE上编译构建的,我们需要分析问题原因并需要针对IDE修改原生CMakeLists.txt。而非cmake编译方式的三方库,我们也需要分析该库的编译方式进行手写CMakeLists.txt文件将该库编译方式改为cmake编译构建。这些过程比较耗时,尤其对一些大型的C/C++三方库.

针对于这些问题,我们开发一套基于linux下用原生库的编译脚本进行交叉编译三方库的工具。该工具协助开发者,在 linux系统上快速编译构建能在OpenHamony上运行的c/c++ 三方库。

三方库测试验证

业界内C/C++三方库测试框架多种多样,我们无法将其统一,因此为了保证原生库功能完整,我们基于原生库的测试用例进行测试验证。为此,我们需要集成了一套可以在OH环境上进行make test等操作的环境,具体方法可参照:
CItools 介绍

三方库的使用

将编译好的三方库以及对应的头文件拷贝到应用工程对应的CPP目录,或将三方库拷贝到对应的工程/entry/libs/armxx/目录,头文件拷贝到工程/entry/include目录。目前建议使用第一种方式,即将三方库以及对应的头文件拷贝到CPP目录。

快速适配三方库实例

我们可以通过工具在 linux系统上快速编译构建能在OpenHamony上运行的c/c++ 三方库,该现在支持cmake以及config及make等构建方式,下面以minizip-ng三方库为例详细讲解lycium工具的使用。

使用约束

  • OpenHarmony SDK版本: Ohos_sdk_public 3.2.11.9
  • API版本: API Version 9 Release
  • DevEco Studio版本: 3.1.0.400

环境搭建

  • 工具下载:工具
  • 环境搭建参照 编译环境搭建
  • OpenHarmony SDK版本下载地址: Ohos_sdk_public 3.2.11.9 (API Version 9 Release)

编译脚本规则

工具编译脚本模板如下:

# Contributor: Your Name <youremail@domain.com>
# Maintainer: Your Name <youremail@domain.com>

pkgname=NAME # 库名(必填)
pkgver=VERSION # 库版本(必填)
pkgrel=0 # 发布号,默认为0
pkgdesc="" # 库描述
url="" # 库的官网链接
archs=("armeabi-v7a" "arm64-v8a") # cpu 架构, 默认编译2种架构
license=()  # 库的开源协议
depends=() # 依赖库的目录名 必须保证被依赖的库的archs是当前库的archs的超集,有依赖时必须填写相应的依赖
makedepends=() # 构建库时的依赖工具
source="https://downloads.sourceforge.net/$pkgname/$pkgname-$pkgver.tar.gz" # 库源码下载链接(必填)

downloadpackage=true # 是否自动下载压缩包,默认true;如果为 false 则需要用户在 prepare 函数中自行下载(如代码只能通过git clone下载(项目中依赖 submoudle)等特殊情况)
autounpack=true # 是否自动解压,默认 true, 如果为 false 则需要用户在 prepare 函数中自行解压
buildtools= # 编译方法, 暂时支持cmake, configure, make等, 根据原生库的编译构建方式填写.(必填)

builddir= # 源码压缩包解压后目录名(必填)
packagename=$builddir.tar.gz # 压缩包名,保持该默认值

# 编译前准备工作,如设置环境变量,创建编译目录等
prepare() {
  mkdir -p $builddir/$ARCH-build
}

# 执行编译构建的命令
build() {
}

# 安装打包
package() {
    cd $builddir/$ARCH-build
    make install
    cd $OLDPWD
}

# 测试,需要在 ohos 设备上进行
check() {
    echo "The test must be on an OpenHarmony device!"
}

# 清理环境
cleanbuild() {
  rm -rf ${PWD}/$builddir #${PWD}/$packagename
}

每个编译脚本都需要按照该规则定义相应的变量以及对应的5个函数,其中变量标明必填是每个库根据库信息必须填写正确,否则导致编译失败,其他变量无初始值的建议根据库信息也填写,方便后期维护。
函数说明:

  • prepare 函数

    编译前准备工作,主要包含:

    1. 创建编译目录(推荐根据不同架构创建不同编译目录,即使用模板默认方式即可)
    2. 设置环境变量(根据不同的编译构建方式进行设置)
    3. 下载源码(downloadpackage=false,推荐使用框架下载)
    4. 解压源码包(下载的是源码包且autounpack=fasle,推荐使用框架解压)
    5. 对于编译时需要做特殊修改(如编译时需要对编译脚本进行打patch操作等)
  • build 函数

    三方库的编译构建函数,makefile生成以及执行make指令。该函数需要根据原生库的构建方式进行配置,不同编译构建基本模板如下:

    1. cmake

      build() {
          cd $builddir  ## 进入到编译目录
          ${OHOS_SDK}/native/build-tools/cmake/bin/cmake $* -DOHOS_ARCH=$ARCH -B$ARCH-build -S./ -L  ## 执行cmake,配置相应的变量并生成Makefile文件
          make -j4 -C $ARCH-build  ## 执行make指令,生成对应的库文件以及可执行用例
          ret=$?    ## 记录make执行的返回值
          cd $OLDPWD  ## 返回进入编译目录前的路径
          return $ret    ## 返回make的返回值
      }
      

      变量说明:

      1. 其中 OHOS_SDK是 ohos sdk的安装路径,在执行编译前需要设置。
      2. $*代表的参数:-DCMAKE_FIND_ROOT_PATH="..." -DCMAKE_TOOLCHAIN_FILE="..." -DCMAKE_INSTALL_PREFIX="..." 依赖库的搜索路径,toolchain file 路径,安装路径
      3. -DOHOS_ARCH 代表当前的编译架构
      4. -B 代表编译路径
      5. -S 代表源码路径
      6. 其他特殊设置需要根据库自身情况在cmake后面进行添加。
    2. configure

      build() {
        cd $builddir/$ARCH-build
        ../configure $*>> `pwd`/build.log 2>&1   ## 执行configure,配置相应的变量并生成Makefile文件
        make -j4 >> `pwd`/build.log 2>&1
        ret=$?
        cd $OLDPWD
        return $ret
      }
      

      变量说明:

      1. $*代表的参数:库的安装路径
      2. 其他特殊设置需要根据库自身情况在configure后面进行添加。
    3. make

      make CC=${cc} AR=${ar} RANLIB=${ranlib} -j4 >> `pwd`/build.log 2>&1
      

      变量说明:

      1. 其中CC,AR,RANLIB等变量根据原生库Makefile文件中变量来设定,其值可在prepare函数中设定。
  • package 函数

    三方库安装打包函数,该函数只需在编译目录直接执行make install即可。对于不支持make install的三方库,需要在该函数中手动安装三方库文件以及头文件等(将对应文件通过cp命令拷贝到对应的安装路径下面)

  • check 函数

    该函数实现了测试准备以及测试说明。对于在目标机器上测试需要生成的测试用例或对于测试需要做修改的,可以在该接口中实现,并需要在该函数中说明在目标机器上运行测试的方法 。真正的测试需要在目标机器上进行。

  • cleanbuild 函数

    该函数主要清理当前库的编译环境。

编译脚本模板更多信息可以参照HPKBUILD。

minizip快速适配

通过对minizip-ng三方库的分析,我们可以知道,该库依赖了openssl,lzma,bzip2,libz,zstd以及googletest等诸多其他的三方库,我们可以选择需要依赖的三方库,关闭不依赖的三方库,此例中我们选择lzma,openssl以及bzip2为依赖进行说明,而这3个依赖库的编译方式分别是cmake,configure以及make。

  • 在thirdparty目录下创建minizip-ng三方库目录,以及对应的xz(该库编译完后会生成liblzma.a以及对应的liblzma.so),openssl和bzip2.

    cd thirdparty
    mkdir minizip-ng
    mkdir xz
    mkdir openssl
    mkdir bzip2
    
  • 参照编译脚本规则编写对应库的HPKBUILD脚本

  • xz三方库的HPKBUILD脚本
    xz库的编译构建方式是cmake编译构建,所以我们需要设置的基本变量信息:

    pkgname=xz  ## 库名
    pkgver=5.4.1 ## 库的版本号
    source="https://tukaani.org/$pkgname/$pkgname-$pkgver.tar.gz" ## 库的源码包路径
    buildtools="cmake"  ## xz库编译构建方式为cmake
    
    builddir=$pkgname-${pkgver} ## xz源码包解压后的文件夹名
    

    其他变量保持默认配置即可。cmake编译方式交叉编译环境变量是通过toolchain文件进行配置,因此在prepare时无需设置环境变量,只需要创建一个对应架构的编译路径即可:

    prepare() {
     mkdir -p $builddir/$ARCH-build
    }
    

    xz库编译时需要配置编译类型以及设置编译动态库,因此在cmake后面添加了对应的配置:-DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON,因此build函数需要如下修改:

    build() {
      cd $builddir
      ${OHOS_SDK}/native/build-tools/cmake/bin/cmake $* -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DOHOS_ARCH=$ARCH -B$ARCH-build -S./ -L > `pwd`/$ARCH-build/build.log 2>&1
      make -j4 -C $ARCH-build >> `pwd`/$ARCH-build/build.log 2>&1
      ret=$?
      cd $OLDPWD
      return $ret
    }
    

    xz原生库测试是通过make test进行测试,对于在目标机上测试无需做其他修改,因此在check函数中只需说明测试方法即可“

    check() {
      echo "The test must be on an OpenHarmony device!"
      # real test CMD
      # 将编译目录加到 LD_LIBRARY_PATH 环境变量或者进入到编译目录
      # make test
    }
    

​ 其他函数可使用模板默认即可。xz完整编译脚本:xz HPKBUILD

  • openssl编译构建脚本HPKBUILD编写

    openssl库的编译构建方式是configure编译构建,因为 configure交叉编译是需要配置host类型的,且需要配置对应的环境变量,框架中基成了环境变量设置的接口,封装在envset.sh 中,因此我们除了基本信息外,还需要定义一个host变量以及导入envset.sh文件,基本变量信息修改如下:

    pkgname=openssl  ## 库名
    pkgver=OpenSSL_1_1_1t ## 库的版本号
    source="https://github.com/openssl/$pkgname/archive/refs/tags/$pkgver.zip" ## 库的源码包路径
    buildtools="configure"  ## 编译方式为configure
    
    builddir=$pkgname-${pkgver} ## openssl 源码包解压后的文件夹名
    
    source envset.sh      ## 导入envset.sh
    host=
    

    相比cmake编译方式,configure方式中的prepare()函数除了创建编译目录外,还需要配置对应架构的环境变量

    prepare() {
      mkdir -p $builddir/$ARCH-build
      if [ $ARCH == ${archs[0]} ]
      then
        setarm32ENV
        host=linux-generic32
      fi
      if [ $ARCH == ${archs[1]} ]
      then
        setarm64ENV
        host=linux-aarch64
      fi
    }
    

    build()函数使用configure命令生成Makefile并执行make指令:

    build() {
      cd $builddir/$ARCH-build
      ../Configure $* $host > `pwd`/build.log 2>&1
      make -j4 >> `pwd`/build.log 2>&1
      ret=$?
      cd $OLDPWD
      return $ret
    }
    

    openssl测试时需要单独通过编译目标depend生成测试用例,因此我们还需要修改对应的check()函数,在check函数中执行 make depend,并在执行完后清理对应的环境变量,而且在该函数后面通过注释说明该库在目标机上的测试方法。

    check() {
        cd $builddir/$ARCH-build
        make depend >> `pwd`/build.log 2>&1
        cd $OLDPWD
        if [ $ARCH == ${archs[0]} ]
        then
            unsetarm32ENV
        fi
        if [ $ARCH == ${archs[1]} ]
        then
            unsetarm64ENV
        fi
        unset host
        echo "Test must be on an OpenHarmony device!"
        # real test CMD
        # 将编译目录加到 LD_LIBRARY_PATH 环境变量
        # make test
      }
    

    其他函数可使用模板默认的即可。openssl完整编译脚本openssl HPKBUILD.

  • bzip2三方库的HPKBUILD脚本

    bzip2原生库提供了Makefile,其编译构建方式就是make,对此我们需要分析原生库的Makefile,了解该库交叉编译需要设置哪些变量。对于bzip2库我们分析其交叉编译时只需要设置CC,AR和RANDLIB三方变量即可,因此我们在配置基本信息时需要额外定这三个变量:

    pkgname=bzip2  ## 库名
    pkgver=1.0.6 ## 库的版本号
    source="https://sourceforge.net/projects/$pkgname/files/$pkgname-$pkgver.tar.gz" ## 库的源码包路径
    buildtools="make"  ## 编译方式为make
    
    builddir=$pkgname-${pkgver} ## openssl 源码包解压后的文件夹名
    
    cc=
    ar=
    ranlib=
    

    三个变量需要根据编译架构进行赋值,我们在prepare函数中执行即可:

    prepare() {
      cp -rf $builddir $builddir-$ARCH-build  ## 为了保留构建环境(方便测试)。因此同一份源码在解压后分为两份,各自编译互不干扰
      cd $builddir-$ARCH-build
      if [ $ARCH == ${archs[0]} ]
      then
        cc=${OHOS_SDK}/native/llvm/bin/arm-linux-ohos-clang
        ar=${OHOS_SDK}/native/llvm/bin/llvm-ar
        ranlib=${OHOS_SDK}/native/llvm/bin/llvm-ranlib
      fi
      if [ $ARCH == ${archs[1]} ]
      then
        cc=${OHOS_SDK}/native/llvm/bin/aarch64-linux-ohos-clang
        ar=${OHOS_SDK}/native/llvm/bin/llvm-ar
        ranlib=${OHOS_SDK}/native/llvm/bin/llvm-ranlib
      fi
      cd $OLDPWD # 1> /dev/null
    }
    

    编译时,我们需要将Makefile中需要的三个变量做为参数传入即可,而通过分析Makefile时知道,在执行make all时会执行make test测试导致make失败,因此我们也需要在make时指定需要编译的目标:

    build() {
      cd $builddir-$ARCH-build
      make CC=${cc} AR=${ar} RANLIB=${ranlib} -j4 libbz2.a bzip2 bzip2recover > `pwd`/build.log 2>&1
      ret=$?
      cd $OLDPWD
      return $ret
    }
    

    因为check函数无需做任何编译相关的动作,因此我们在package安装打包后需要清空对应的变量,而check函数只需要注释测试说明:

    package() {
      cd $builddir-$ARCH-build  # 进入到编译目录
      make install PREFIX=$LYCIUM_ROOT/usr/$pkgname-$ARCH-install >> `pwd`/build.log 2>&1 # 执行安装动作,此时需要配置对应的安装路径
      cd $OLDPWD
      unset cc ar ranlib      # 清空变量
    }
    check() {
        echo "Test must be on an OpenHarmony device!"
        # real test CMD
        # 将编译目录加到 LD_LIBRARY_PATH 环境变量或进入到编译目录:
        # make test
    }
    

    该库清理环境和之前库不一样,因为在prepare时是拷贝了对应的目录,因此清理时需要把拷贝的目录也删除:

    cleanbuild(){
      rm -rf ${PWD}/$builddir $builddir-armeabi-v7a-build  $builddir-arm64-v8a-build #${PWD}/$packagename
    }
    

    bzip完整的编译脚本可以参照:bzip2 HPKBUILD

  • minizip-ng三方库的HPKBUILD脚本

    minizip-ng三方库的编译方式是通过cmake,而且该库依赖了多个库,此时除了基本信息外,我们还需要填写其依赖库:

    pkgname=minizip-ng  # 库名
    pkgver=3.0.4        # 库版本
    depends=("xz" "openssl" "bzip2")  # minizip依赖的库
    source="https://github.com/zlib-ng/${pkgname}/archive/refs/tags/${pkgver}.tar.gz" # 库源码包链接
    buildtools="cmake"  # cmake编译方式
    
    builddir=$pkgname-${pkgver} # 源码包解压后名字
    

    函数设计中,build函数需要设置多个参数,其中包含

    1. 设置openssl依赖路径,因为openssl是通过configure编译的,其依赖路径必须通过PKG_CONFIG_PATH设置。
    2. 关闭一些未准备好的依赖库
    build() {
      cd $builddir
      ## 此处将依赖库iconv以及zstd屏蔽,如有强制需求可以将此2库定义为true并在depends中加上这2个库的依赖
      PKG_CONFIG_PATH=${LYCIUM_ROOT}/usr/openssl-${ARCH}-install/lib/pkgconfig ${OHOS_SDK}/native/build-tools/cmake/bin/cmake $* -DMZ_ZSTD=false -DMZ_ICONV=false -DOHOS_ARCH=$ARCH -B$ARCH-build -S./ -L > `pwd`/$ARCH-build/build.log 2>&1
      make -j4 -C $ARCH-build >> `pwd`/$ARCH-build/build.log 2>&1
      ret=$?
      cd $OLDPWD
      return $ret
    }
    

    minizip 原生库未提供测试框架,因此无需在check中说明,其他函数使用模板默认即可。minizip-ng完整的编译脚本参照:Minizip-ng HPKBUILD

minizip编译构建

编写完HPKBUILD文件后,我们就可以进行三方库的编译了。在lycium目录执行如下指令进行编译:

./build.sh minizip-ng xz bzip2 openssl googletest

其中minizip-ng是我们需要编译的三方库,而xz,bzip2,openssl以及googletest是minizip-ng三方库的依赖库。进行编译完后,会在lycium/usr下生成对应架构的三方库的的库文件和头文件等。

minizip-ng/arm64-v8a minizip-ng/armeabi-v7a 
  # 依赖库
openssl/arm64-v8a openssl/armeabi-v7a xz/arm64-v8a xz/armeabi-v7a zstd/arm64-v8a zstd/armeabi-v7a bzip2/arm64-v8a bzip2/armeabi-v7a

注意:

  • 有依赖库的必须将依赖库一起编译,否则框架无法进行编译。
  • 安装目录下对应的三方库有2份,其中armeabi-v7a对应的32位的库,arm64-v8a对应的是64位的库。

minizip在应用中的使用

minizip在应用中使用请参考文档minizip 集成到应用hap

为了能让大家更好的学习鸿蒙(HarmonyOS NEXT)开发技术,这边特意整理了《鸿蒙开发学习手册》(共计890页),希望对大家有所帮助:https://qr21.cn/FV7h05

《鸿蒙开发学习手册》:

如何快速入门:https://qr21.cn/FV7h05

  1. 基本概念
  2. 构建第一个ArkTS应用
  3. ……

开发基础知识:https://qr21.cn/FV7h05

  1. 应用基础知识
  2. 配置文件
  3. 应用数据管理
  4. 应用安全管理
  5. 应用隐私保护
  6. 三方应用调用管控机制
  7. 资源分类与访问
  8. 学习ArkTS语言
  9. ……

基于ArkTS 开发:https://qr21.cn/FV7h05

  1. Ability开发
  2. UI开发
  3. 公共事件与通知
  4. 窗口管理
  5. 媒体
  6. 安全
  7. 网络与链接
  8. 电话服务
  9. 数据管理
  10. 后台任务(Background Task)管理
  11. 设备管理
  12. 设备使用信息统计
  13. DFX
  14. 国际化开发
  15. 折叠屏系列
  16. ……

鸿蒙开发面试真题(含参考答案):https://qr18.cn/F781PH

鸿蒙开发面试大盘集篇(共计319页):https://qr18.cn/F781PH

1.项目开发必备面试题
2.性能优化方向
3.架构方向
4.鸿蒙开发系统底层方向
5.鸿蒙音视频开发方向
6.鸿蒙车载开发方向
7.鸿蒙南向开发方向

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Ypay源支付前端美化模板

功能&#xff1a; 首页加了运行时间&#xff0c;加了首页一言打字效果&#xff0c;加了访问次数&#xff0c;还有底部也适当的加了一点美化 而且加了一个播放器功能&#xff0c;可以自定义歌曲之类的 完美契合于源支付 直接上传主题包使用即可 演示图: 使用: 请不要在后台…

C语言学习笔记之指针(一)

目录 什么是指针&#xff1f; 指针和指针类型 指针的类型 指针类型的意义 指针-整数 指针的解引用 指针 - 指针 指针的关系运算 野指针 什么是野指针&#xff1f; 野指针的成因 如何规避野指针&#xff1f; 二级指针 什么是指针&#xff1f; 在介绍指针之前&#…

Ubuntu上安装Chrome浏览器

安装步骤 1.下载安装chrome安装包 wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb2.安装Chrome浏览器 sudo dpkg -i google-chrome-stable_current_amd64.debsudo apt-get -f install3.启动Chrome浏览器 查看收藏夹里的Chrome图标 单击C…

LeetCode刷题总结 | 图论3—并查集

并查集理论基础 1.背景 首先要知道并查集可以解决什么问题呢&#xff1f; 并查集常用来解决连通性问题。大白话就是当我们需要判断两个元素是否在同一个集合里的时候&#xff0c;我们就要想到用并查集。 并查集主要有两个功能&#xff1a; 将两个元素添加到一个集合中。判…

python怎么连接oracle

一&#xff1a;弄清版本&#xff0c;最重要&#xff01;&#xff01;&#xff01; 首先安装配置时&#xff0c;必须把握一个点&#xff0c;就是版本一致&#xff01;包括&#xff1a;系统版本&#xff0c;python版本&#xff0c;oracle客户端的版本&#xff0c;cx_Oracle的版本…

IAR 使用笔记(IAR BIN大小为0异常解决)

烧写 由于芯片的内部SPI FLASH的0级BOOT 程序起到到开启JTAG SW 仿真功能&#xff0c;一旦内部SPI FLASH存储的BL0启动代码被损坏&#xff0c;芯片的JTAG 将不能被连接。所以对BL0的烧写需要谨慎&#xff0c;烧写BL0过程保证芯片不断电。 如果烧写了多备份的启动代码&#xff…

深度学习架构(CNN、RNN、GAN、Transformers、编码器-解码器架构)的友好介绍。

一、说明 本博客旨在对涉及卷积神经网络 &#xff08;CNN&#xff09;、递归神经网络 &#xff08;RNN&#xff09;、生成对抗网络 &#xff08;GAN&#xff09;、转换器和编码器-解码器架构的深度学习架构进行友好介绍。让我们开始吧&#xff01;&#xff01; 二、卷积神经网络…

【Java探索之旅】掌握数组操作,轻松应对编程挑战

&#x1f3a5; 屿小夏 &#xff1a; 个人主页 &#x1f525;个人专栏 &#xff1a; Java编程秘籍 &#x1f304; 莫道桑榆晚&#xff0c;为霞尚满天&#xff01; 文章目录 &#x1f4d1;前言一、数组巩固练习1.1 数组转字符串1.2 数组拷贝1.3 求数组中的平均值1.4 查找数组中指…

手写签名功能(vue3)

手写签名功能&#xff08;vue3&#xff09; 效果 显示效果 签名版效果 代码 代码引入 写成子组件形式&#xff0c;直接引入即可 <signature-features />代码结构 signatureFeatures&#xff1a;签名的显示效果 vueEsign&#xff1a;画板 xnSignName&#xff1a;打开…

Ubuntu修改DNS

【永久修改DNS】 临时修改DNS的方法是在 /etc/resolv.conf 添加&#xff1a;nameserver 8.8.8.8 nameserver 8.8.8.8 注意到/etc/resolv.conf最上面有这么一行&#xff1a; DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN 说明重启之后这个文件会被自动…

关于系统数据缓存的思考以及设计

文章目录 引言案例A项目B项目 分析我的实现总结 引言 缓存&#xff0c;这是一个经久不衰的话题&#xff0c;它通过“空间换时间”的战术不仅能够极大提升处理查询性能还能很好的保护底层资源。最近针对系统数据缓存的优化后&#xff0c;由于这是一个通用的场景并且有了一点心得…

力扣练习题(2024/4/15)

1打家劫舍 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&#xff0c;如果两间相邻的房屋在同一晚上被小偷闯入&#xff0c;系统会自动报警。 给定一个代表每个房屋…

java实现论文查重,文本查重方案 采用 ansj 分词法

需求要求实现一个文本查重&#xff0c;重复率超过70% 就不让用户新增文本。固研究实现基于java的文本查重工具&#xff0c;分享出来方便大家使用&#xff5e; ansj 分词法介绍 Ansj 是一个开源的 Java 中文分词工具&#xff0c;基于中科院的 ictclas 中文分词算法&#xff0c…

THS6.0.1.0开启健康检查(by lqw)

可以在节点管理器或者分组管理的编辑配置里添加以下信息&#xff1a; 之后点监控,点击实时指标&#xff0c;点击HTTP集群统计&#xff1a; 下图是配置并生效的效果&#xff1a; 也可以使用頁面配置&#xff1a; 推荐使用tcp形式&#xff0c;有的应用后端可能不支持http…

代理知识科普:为什么有的代理IP速度比较慢呢?

代理IP在跨境业务中被广泛的应用&#xff0c;今天我们将一同深入探讨一个问题&#xff1a;“为什么有的IP代理速度比较慢&#xff1f;”随着数字化时代的不断发展&#xff0c;代理服务成为了许多网络操作的关键环节。然而&#xff0c;有时我们可能会遇到IP代理速度慢的问题&…

MT3026 砍玉米

样例1&#xff1a; 输入&#xff1a; 6 1 3 4 2 5 1 7 8 19 10 30 2 输出&#xff1a; 6 其中1<n<10^5,1<xi,hi<10^9 思路&#xff1a;贪心&#xff1a;从左到右或者从右到左依次判断每一棵玉米是否可以倒下 &#xff08;以从左到右为例&#xff1a;先往左倒&…

[论文笔记]Root Mean Square Layer Normalization

引言 今天带来论文Root Mean Square Layer Normalization的笔记&#xff0c;论文题目是均方根层归一化。 本篇工作提出了RMSNorm&#xff0c;认为可以省略重新居中步骤。 简介 层归一化对Transformer等模型非常重要&#xff0c;它可以帮助稳定训练并提升模型收敛性&#xf…

生成对抗网络GAN的扩展应用理解

注&#xff1a;本文仅个人学习理解&#xff0c;如需详细内容请看原论文&#xff01; 一、cycleGAN 1.整体架构&#xff1a; 将图片A通过生成器生成图片B&#xff0c;然后通过判别器判别图片B的真假&#xff1b;并且图片B通过另一个生成器生成A‘&#xff0c;让A和A’近似。 2…

Python这十大特征,堪称“圆满”!

当你犹豫是否要开始 Python 学习之前&#xff0c;可以先详尽了解一下这门编程语言。 软件开发者 Guido Van Rossum 于 1991 年创建了 Python&#xff0c;旨在使程序员的工作更加简单。Python 是目前全球比较流行且产业急需的程序设计语言&#xff0c;也是一门跨平台、开源、免…

2024-8.python作用域+函数其他

变量的作用域 讲到了函数就必须介绍变量的作用域相关。 作用域指的是变量的有效范围。变量并不是在哪个位置都可以访问的&#xff0c;访问权限取决于这个变量是在哪里赋值的&#xff0c;也就是在哪个作用域内赋的值。变量在哪个作用域内赋值&#xff0c;则表示该变量的作用域就…