关于后端:深入浅出JVM六之前端编译过程与语法糖原理

本篇文章将围绕Java中的编译器,深入浅出的解析前端编译的流程、泛型、条件编译、加强for循环、可变长参数、lambda表达式等语法糖原理 编译器与执行引擎编译器Java中的编译器不止一种,Java编译器能够分为:前端编译器、即时编译器和提前编译器 最为常见的就是前端编译器javac,它可能将Java源代码编译为字节码文件,它可能优化程序员应用起来很不便的语法糖 即时编译器是在运行时,将热点代码间接编译为本地机器码,而不须要解释执行,晋升性能 提前编译器将程序提前编译成本地二进制代码 前端编译过程筹备阶段: 初始化插入式注解处理器解决阶段 解析与填充符号表 词法剖析: 将Java源代码的字符流转变为token(标记)流 字符: 程序编写的最小单位标记(token) : 编译的最小单位比方 关键字 static 是一个标记 / 6个字符语法分析: 将token流结构成形象语法树填充符号表: 产生符号信息和符号地址 符号表是一组符号信息和符号地址形成的数据结构比方: 指标代码生成阶段,对符号名调配地址时,要查看符号表上该符号名对应的符号地址插入式注解处理器的注解解决 注解处理器解决非凡注解: 在编译器容许注解处理器对源代码中非凡注解作解决,能够读写形象语法树中任意元素,如果产生了写操作,就要从新解析填充符号表 比方: Lombok通过非凡注解,生成get/set/结构器等办法语义剖析与字节码生成 标注查看: 对语义动态信息的查看以及常量折叠优化  int i = 1; char c1 = 'a'; int i2 = 1 + 2;//编译成 int i2 = 3 常量折叠优化 char c2 = i + c1; //编译谬误 标注查看 查看语法动态信息 数据及控制流剖析: 对程序运行时动静查看 比方办法中流程管制产生的各条路是否有适合的返回值解语法糖: 将(不便程序员应用的简洁代码)语法糖转换为原始构造字节码生成: 生成<init>,<clinit>办法,并根据上述信息生成字节码文件前端编译流程图 源码剖析代码地位在JavaCompiler的compile办法中 Java中的语法糖泛型将操作的数据类型指定为办法签名中一种非凡参数,作用在办法、类、接口上时称为泛型办法、泛型类、泛型接口 Java中的泛型是类型擦除式泛型,泛型只在源代码中存在,在编译期擦除泛型,并在相应的中央加上强制转换代码 与具现化式泛型(不会擦除,运行时也存在泛型)比照长处: 只须要改变编译器,Java虚拟机和字节码指令不须要扭转 因为泛型是JDK5退出的,为了满足对以前版本代码的兼容采纳类型擦除式泛型毛病: 性能较低,应用没那么不便 为提供根本类型的泛型,只能主动拆装箱,在相应的中央还会减速强制转换代码,所以性能较低运行期间无奈获取到泛型类型信息 ...

February 23, 2024 · 2 min · jiezi

关于后端:如何获取-mysql-外键索引的元数据信息

背景对数据进行对立的治理解决,后续方便使用。 根本信息见上一篇的解决。 select * from information_schema.KEY_COLUMN_USAGE where REFERENCED_TABLE_SCHEMA = 'test' \G;*************************** 1. row *************************** CONSTRAINT_CATALOG: def CONSTRAINT_SCHEMA: test CONSTRAINT_NAME: user_extra_ibfk_1 TABLE_CATALOG: def TABLE_SCHEMA: test TABLE_NAME: user_extra COLUMN_NAME: user_id ORDINAL_POSITION: 1POSITION_IN_UNIQUE_CONSTRAINT: 1 REFERENCED_TABLE_SCHEMA: test REFERENCED_TABLE_NAME: users REFERENCED_COLUMN_NAME: id1 row in set (0.06 sec)字段解释这是一个查问信息模式(information_schema)中的要害列应用状况的SQL语句,通过指定条件REFERENCED_TABLE_SCHEMA = 'test'筛选了特定的数据库(test)。 上面是查问后果的具体解释: CONSTRAINT_CATALOG: 示意外键束缚所属的目录,这里是默认值 "def"。CONSTRAINT_SCHEMA: 示意外键束缚所属的数据库,这里是 "test"。CONSTRAINT_NAME: 示意外键束缚的名称,这里是 "user_extra_ibfk_1"。TABLE_CATALOG: 示意表所属的目录,这里是默认值 "def"。TABLE_SCHEMA: 示意表所属的数据库,这里是 "test"。TABLE_NAME: 示意表的名称,这里是 "user_extra"。COLUMN_NAME: 示意表中的列名,这里是 "user_id"。ORDINAL_POSITION: 示意列在表中的程序地位,这里是第1列。POSITION_IN_UNIQUE_CONSTRAINT: 示意在惟一束缚中的地位,这里是第1个地位。REFERENCED_TABLE_SCHEMA: 示意被援用表所属的数据库,这里是 "test"。REFERENCED_TABLE_NAME: 示意被援用表的名称,这里是 "users"。REFERENCED_COLUMN_NAME: 示意被援用表中的列名,这里是 "id"。这个查问的后果通知咱们,在数据库 "test" 中,表 "user_extra" 中的 "user_id" 列是一个外键,它参照了表 "users" 中的 "id" 列,外键的束缚名称为 "user_extra_ibfk_1"。 ...

February 23, 2024 · 1 min · jiezi

关于后端:openai-sora-只能根据文本生成视频不TA-是通用物理世界模拟器

视频生成模型作为世界模拟器咱们摸索了在视频数据上进行大规模生成模型的训练。 具体来说,咱们联结在可变持续时间、分辨率和长宽比的视频和图像上训练文本条件扩散模型。 咱们利用了一个在视频和图像潜在编码的时空补丁上操作的变压器架构。 咱们最大的模型Sora可能生成一分钟的高保真视频。咱们的结果表明,扩大视频生成模型是建设通用物理世界模拟器的有前途的路径。 TODO: 视频PS:其余视频省略。 这份技术报告着重介绍了两个方面: (1) 咱们将各种类型的视觉数据转化为对立示意的办法,从而实现了生成模型的大规模训练; (2) 对Sora的能力和局限性进行了定性评估。模型和实现细节不蕴含在本报告中。 之前的钻研曾经探讨了利用各种办法对视频数据进行生成建模,包含循环网络、生成反抗网络、自回归变压器和扩散模型等。 这些工作通常专一于某一类视觉数据,或者是针对较短的视频,或者是针对尺寸固定的视频。 Sora是一种通用的视觉数据模型——它能够生成逾越不同持续时间、长宽比和分辨率的视频和图像,高清视频的长度可达一分钟。 将视觉数据转化为补丁 Turning visual data into patches咱们受到大型语言模型的启发,这些模型通过在互联网规模的数据上进行训练取得了通用能力。 语言模型范式的胜利局部得益于优雅地对立了文本、代码、数学和各种自然语言等多种形式的令牌的应用。 在这项工作中,咱们思考了生成视觉数据模型如何继承这些益处。 而语言模型有文本令牌,Sora有视觉补丁。曾经有钻研表明,补丁是视觉数据模型的无效示意。咱们发现,补丁是一种高度可扩大且无效的示意,可用于训练不同类型的视频和图像的生成模型。 在高层次上,咱们通过首先将视频压缩成低维潜在空间,而后将示意合成为时空补丁来将视频转化为补丁。 视频压缩网络 Video compression network咱们训练了一个网络来升高视觉数据的维度。该网络将原始视频作为输出,并输入一个在工夫和空间上都被压缩的潜在示意。 Sora在这个压缩的潜在空间上进行训练,并随后生成视频。咱们还训练了一个相应的解码器模型,将生成的潜在示意映射回像素空间。 时空潜在补丁 Spacetime latent patches给定一个压缩的输出视频,咱们提取一系列时空补丁,这些补丁充当变压器令牌。 这个计划对图像也实用,因为图像只是具备单个帧的视频。咱们基于补丁的示意使得Sora可能在分辨率、持续时间和长宽比各异的视频和图像上进行训练。 在推理时,咱们能够通过将随机初始化的补丁排列成适当大小的网格来管制生成视频的大小。 对视频生成进行变压器的扩大 Scaling transformers for video generationSora是一个扩散模型;给定输出的噪声补丁(以及诸如文本提醒等的条件信息),它被训练成预测原始的“洁净”补丁。 值得注意的是,Sora是一个扩散变压器。变压器在各种畛域展现了显著的扩大个性,包含语言建模、计算机视觉和图像生成。 在这项工作中,咱们发现扩散变压器(diffusion transformers)在视频模型中也能无效扩大。 上面,咱们展现了随着训练计算量减少,应用固定种子和输出的视频样本的比拟。 随着训练计算量的减少,样本品质显著进步。 变动的持续时间、分辨率、长宽比 Variable durations, resolutions, aspect ratios过来的图像和视频生成办法通常会将视频调整大小、裁剪或修剪到规范大小——例如,256x256分辨率的4秒视频。 咱们发现,与其在规范大小上进行训练,不如在数据的原始大小上进行训练具备几个益处。 采样灵活性 Sampling flexibilitySora能够对宽屏的1920x1080p视频、垂直的1080x1920视频以及两者之间的所有内容进行采样。 这使得Sora可能间接依照其原成长宽比为不同设施创立内容。这也使咱们可能在生成全分辨率之前疾速原型化较低大小的内容——而所有这些都是应用同一个模型实现的。 改善构图和构图 Improved framing and composition咱们凭教训发现,应用视频的原始长宽比进行训练能够改善构图和构图。 咱们将Sora与咱们模型的一个版本进行比拟,该版本将所有训练视频裁剪为正方形,这在训练生成模型时是常见的做法。 在应用正方形裁剪训练的模型(左)中,有时会生成主体仅局部可见的视频。相比之下,来自Sora(右)的视频具备改善的构图。 语言了解 Language understanding训练文本到视频生成零碎须要大量带有相应文本题目的视频。咱们利用了DALL·E 3中引入的从新题目技术到视频中。咱们首先训练一个高度描述性的题目生成模型,而后应用它为咱们训练集中的所有视频生成文本题目。咱们发现,在高度描述性的视频题目上进行训练不仅能够进步文本的准确性,还能够进步视频的整体品质。 ...

February 23, 2024 · 1 min · jiezi

关于后端:Flink-ML的新特性解析与应用

摘要:本文整顿自阿里巴巴算法专家赵伟波,在 Flink Forward Asia 2023 AI特色工程专场的分享。本篇内容次要分为以下四局部: Flink ML 详情在线学习的设计与利用在线推理的设计与利用特色工程算法与利用一、Flink ML 详情 Flink ML 是 Apache Flink 的子项目,遵循 Apache 社区标准,愿景是成为实时传统机器学习的事实标准。 2022年1月份 Flink ML API 公布,7月份公布齐备、高性能的 Flink ML 基础设施,2023年4月份发力特色工程算法并服务用户,6月份反对 Flink 多版本。 二、在线学习的设计与利用2.1 在线机器学习工作流样例 有两个模型AB,用 online 在线学习的形式去训练这两个模型,并且应用模型去进行在线推理,在推理过程中这个模型是流动模式,叫做 Model stream (模型流),以模型流的形式将模型一直地流入链路中,使模型具备更好的实时性。推理完结之后,推理样本会举荐给一些后方的客户,客户对后果进行反馈,再进行一些样本的拼接,最初返回到训练的数据流造成闭环,这就是工作流样例。 接下来以工作流样例来介绍在线学习的设计。训练数据进行切分后,切成不同的 window,每个 window 在通过 Estimator 的时候须要更新外面的模型,之后该模型会流到上面推理的链路中,随着数据的一直流入,模型会一个接一个的往推理的链路中流动,这就是 Model stream(模型流),其思路是通过把模型做成一个队列的形式去反对推理以达到更好的时效性。 存在的问题: 如何使数据拆分更加正当?对不同的业务有不同的要求,有的心愿用工夫,有的心愿用大小,都须要一些策略。因为数据和模型都是流动的,两个往同一个中央去流,那么如何决定一条样本来了之后用哪个模型进行推理?如何保障模型的一致性?因为链路中有两个模型,如果两个模型的训练数据不统一会导致呈现一些问题。数据是用哪一个模型推理进去的?每一条样本是哪个模型推理进去的,预测的好坏须要去追溯源头。2.2 在线机器学习的设计 针对四个问题,有四条设计需要: 反对将输出数据划分为多个 window 进行训练,产生一个模型流。反对应用输出的模型流来对数据进行预测。反对用户指定推理数据和以后模型数据的时间差。每一条样本来了之后,咱们心愿用最新的模型去进行推理,然而最新的模型可能还没有训练进去,这个时候就须要设定一个时间差,容许它用非最新的模型进行推理。反对在输入数据中裸露预测每条数据时应用的模型版本。从预测后果追溯出模型的需要。针对这些需要,咱们的设计方案是: 减少 HasWindows 接口。容许用户申明划分数据的不同策略。为 ModelData 减少 model version 和 timestamp。model version 的值从 0 开始,每次减少 1。模型数据的工夫戳为训练失去该模型的数据的最大工夫戳。减少 HasMaxAllowedModelDelayMs 接口。容许用户指定预测数据 D 时,应用的模型数据 M 早于 D 的工夫小于等于设定的阈值。减少 HasModelVersionCol 接口。推理过程中,容许用户输入预测每条数据时应用的模型版本。 ...

February 23, 2024 · 2 min · jiezi

关于后端:DevOps的八大能力

DevOps的八大能力DevOps 是什么?DevOps是一种交融文化、工具和实际的理念,旨在通过自动化技术实现高效率高质量的交付指标,贯通整个软件生命周期。它次要包含继续打算、继续集成、继续部署、继续测试、继续运维、继续平安、继续监控、继续反馈这八大外围能力。 一、 继续打算应采纳麻利开发实际来进步速度和品质。 麻利开发是一种用于项目管理和软件开发的迭代办法,可帮忙团队将工作分解成更小的局部,从而提供增量价值。更多内容请参考 DevOps与麻利开发。 二、 继续集成集成指将更新的代码合并或者提交到骨干源码仓库。 继续集成是指在版本控制的根底上,通过频繁的代码提交、自动化构建和单元测试放慢集成周期和问题反馈速度,从而及时验证零碎可用性。 次要包含性能:拉取代码、代码品质扫描、代码平安扫描、代码标准查看、单元测试、集成测试(不依赖服务)、编译和制作镜像、推送到制品库 三、 继续部署部署指将制品装置到运行环境。 继续部署是通过自动化的伎俩将部署的操作过程进行简化,升高部署的复杂度,使得部署是一个随时可进行的疾速流动。 继续部署并不特指通过品质验证的制品主动部署到生产环境。四、 继续测试部署指将制品装置到运行环境。 继续部署是通过自动化的伎俩将部署的操作过程进行简化,升高部署的复杂度,使得部署是一个随时可进行的疾速流动。 继续部署并不特指通过品质验证的制品主动部署到生产环境。五、 继续运维治理面向客户的端到端IT服务交付,包含设计、施行、配置、部署和保护反对组织服务的所有IT基础架构过程中波及的实际。 六、 继续平安源于DevSecOps理念,其目标是通过平安左移到开发测试团队,使平安评审阶段的时长变短,从而进一步缩短交付周期。并且它能够在更早的阶段发现并修复安全漏洞,从而缩小上线前发现安全漏洞的返工老本。 平安左移是为了让团队对他们开发的内容负责,通过将平安等工作(比方测试平安)从部署前的平安评审阶段左移到更早的阶段,从而更早、更快地发现并解决平安问题,而不是等到几天后部署时才发现,或者几个月后再收回浸透测试报告。 七、 继续监控疾速辨认并解决影响产品失常运行工夫、速度和性能的事务。 主动告诉团队无关变更、高风险操作或故障的信息,以便放弃服务的运行。 八、 继续反馈对每个版本进行评估,并生成报告以改良将来版本。 通过收集继续反馈,团队能够改良其流程,并驳回客户反馈以改良下一个版本。 本文由mdnice多平台公布

February 23, 2024 · 1 min · jiezi

关于后端:深入浅出JVM五之Java中方法调用

本篇文章将围绕Java中办法的调用,深入浅出的阐明办法调用的指令、解析调用以及分派调用等 办法调用要晓得Java中办法调用惟一目标就是确定要调用哪一个办法 办法调用能够分为解析调用和分派调用,接下来会具体介绍 非虚办法与虚办法非虚办法: 静态方法,公有办法,父类中的办法,被final润饰的办法,实例结构器 其余不是非虚办法的办法就是虚办法 非虚办法的特点就是没有重写办法,适宜在类加载阶段就进行解析(符号援用->间接援用) 【编译时就可能确定】 调用指令一般调用指令 invokestatic:调用静态方法invokespecial:调用公有办法,父类中的办法,实例结构器<init>办法,final办法invokeinterface:调用接口办法invokevirtual: 调用虚办法应用invokestatic和invokespecial指令的肯定是非虚办法 应用invokeinterface指令肯定是虚办法(因为接口办法须要具体的实现类去实现) 应用invokevirtual指令的是虚办法 动静调用指令 invokedynamic: 动静解析出须要调用的办法再执行jdk 7 呈现invokedynamic,反对动静语言 测试虚办法代码父类 public class Father {     public static void staticMethod(){         System.out.println("father static method");    }      public final void finalMethod(){         System.out.println("father final method");    }      public Father() {         System.out.println("father init method");    }      public void overrideMethod(){         System.out.println("father override method");    } }接口 public interface TestInterfaceMethod {     void testInterfaceMethod(); }子类 public class Son extends Father{      public Son() {         //invokespecial 调用父类init 非虚办法         super();         //invokestatic 调用父类静态方法 非虚办法         staticMethod();         //invokespecial 调用子类公有办法 非凡的非虚办法         privateMethod();         //invokevirtual 调用子类的重写办法 虚办法         overrideMethod();         //invokespecial 调用父类办法 非虚办法         super.overrideMethod();         //invokespecial 调用父类final办法 非虚办法         super.finalMethod();         //invokedynamic 动静生成接口的实现类 动静调用         TestInterfaceMethod test = ()->{             System.out.println("testInterfaceMethod");        };         //invokeinterface 调用接口办法 虚办法         test.testInterfaceMethod();    }      @Override     public void overrideMethod(){         System.out.println("son override method");    }      private void privateMethod(){         System.out.println("son private method");    }      public static void main(String[] args) {         new Son();    } } ...

February 23, 2024 · 4 min · jiezi

关于后端:进大厂前先学会阅读源码之shenyu网关替换ZooKeeper客户端

置信大家碰到源码一开始都是比拟无从下手的,不晓得从哪开始浏览,面对大量代码昏头昏脑,索性就读不上来了,又节约了一次晋升本人的机会。 我认为有一种办法,能够解决大家的困扰!那就是通过浏览某一次开源【commit】、某一次社区【ISSUE】,从这个入口登程去浏览源码!! 至此,咱们发现自己开始从大量堆砌的源码中脱离开来。恍然大悟,柳暗花明又一村。 一、前瞻明天咱们攻克的一次开源提交:commit链接 本次commit的核心内容就在下图红框中,意思很清晰明了:替换以后的ZooKeeper客户端。 看看Magic Header是什么 Magic Header 通常指的是文件结尾的一段特定字节序列,用来标识或确认文件的格局和类型。这些字节序列是事后定义的,不同的文件格式有不同的 Magic Header。操作系统和应用程序通过读取这些特定的字节序列来辨认文件的格局,即便文件扩展名被更改或失落。简略来说就是用来标识文件。 咱们先整体看下本次所有提交的内容,尽管看起来波及了大量的模块、大量的代码,但外围其实就是红框对应的内容。既然是要替换以后的ZooKeeper客户端,那便是要新建Curator这个新的客户端,同时批改调用端的调用对象! 上面咱们就来看看贡献者是怎么实现替换的!!同时上文提到并将数据保留在没有 magic header 的 zk 中,正确翻译应该是保留数据在zk时,不应用magic header来标识数据,那他又是怎么做的?? 二、摸索咱们参照上图,先看下ZookeeperClient类,该类很显眼的引入了本次提交的配角CuratorFramework,ZookeeperClient封装了CuratorFramework作为ZooKeeper新的客户端。 public class ZookeeperClient { private static final Logger LOGGER = LoggerFactory.getLogger(ZookeeperClient.class); private final ZookeeperConfig config; private final CuratorFramework client; private final Map<String, CuratorCache> caches = new ConcurrentHashMap<>(); public ZookeeperClient(final ZookeeperConfig zookeeperConfig) { this.config = zookeeperConfig; ExponentialBackoffRetry retryPolicy = new ExponentialBackoffRetry(config.getBaseSleepTimeMilliseconds(), config.getMaxRetries(), config.getMaxSleepTimeMilliseconds()); CuratorFrameworkFactory.Builder builder = CuratorFrameworkFactory.builder() .connectString(config.getServerLists()) .retryPolicy(retryPolicy) .connectionTimeoutMs(config.getConnectionTimeoutMilliseconds()) .sessionTimeoutMs(config.getSessionTimeoutMilliseconds()) .namespace(config.getNamespace()); if (!StringUtils.isEmpty(config.getDigest())) { builder.authorization("digest", config.getDigest().getBytes(StandardCharsets.UTF_8)); } this.client = builder.build(); } /** * start. */ public void start() { this.client.start(); try { this.client.blockUntilConnected(); } catch (InterruptedException e) { LOGGER.warn("Interrupted during zookeeper client starting."); Thread.currentThread().interrupt(); } }}而ZookeeperInstanceRegisterRepository就是起到控制器的作用,把ZookeeperConfig类的配置注册到ZookeeperClient来初始化咱们新的客户端。 ...

February 23, 2024 · 2 min · jiezi

关于后端:记一次-Rust-内存泄漏排查之旅-经验总结篇

在某次继续压测过程中,咱们发现 GreptimeDB 的 Frontend 节点内存即便在申请量安稳的阶段也在继续上涨,直至被 OOM kill。咱们判断 Frontend 应该是有内存透露了,于是开启了排查内存透露之旅。 Heap Profiling大型项目简直不可能只通过看代码就能找到内存透露的中央。所以咱们首先要对程序的内存用量做统计分析。侥幸的是,GreptimeDB 应用的 jemalloc 自带 heap profiling,咱们也反对了导出 jemalloc 的 profile dump 文件。于是咱们在 GreptimeDB 的 Frontend 节点内存达到 300MB 和 800MB 时,别离 dump 出了其内存 profile 文件,再用 jemalloc 自带的 jeprof 剖析两者内存差别(--base 参数),最初用火焰图显示进去: 显然图片两头那一大长块就是一直增长的 500MB 内存占用了。仔细观察,竟然有 thread 相干的 stack trace。难道是创立了太多线程?简略用 ps -T -p 命令看了几次 Frontend 节点的过程,线程数稳固在 84 个,而且都是预知的会创立的线程。所以“线程太多”这个起因能够排除。 再持续往下看,咱们发现了很多 Tokio runtime 相干的 stack trace,而 Tokio 的 task 透露也是常见的一种内存透露。这个时候咱们就要祭出另一个神器:Tokio-console。 Tokio ConsoleTokio Console 是 Tokio 官网的诊断工具,输入后果如下: ...

February 22, 2024 · 2 min · jiezi

关于后端:AGAT-强大的-GFFGTFBED-工具包

AGAT - 弱小的 GFF/GTF/BED 工具包还在用 gffread、GenomeTools等软件将 GFF 文件转化为 GTF 格局?连忙试试 AGAT 这款更弱小的工具!!! AGAT (Another GTF/GFF Analysis Toolkit) 是一个 GFF/GTF 工具包,简直能实现所有你可能想要对这两种格式文件进行的操作。 AGAT 有能力查看、修复、填充任何类型的 GTF 和 GFF 的缺失信息 (特色/属性),以创立残缺、分类和标准化的 gff3 格局。通过多年的优化,它曾经开发了大量工具来执行简直任何可能与 GTF/GFF 格式文件相干的工作 (转换,合并,批改,过滤,FASTA 序列提取,增加信息等)。与其余办法相比,AGAT 即便对最不标准的 GTF/GFF 文件也可实用。 <img src="https://cdn.jsdelivr.net/gh/ShengXinF3/ShengXinF3/Pics/agat.png" style="zoom:67%;" /> 次要性能将任何 GTF/GFF 文件标准化/整顿为全面的 GFF3 格局 (通过带有 _sp_ 前缀的脚本) 工作工具查看、修复、填充缺失信息到分类和标准化的 gff3agat_convert_sp_gxf2gxf.pl增加缺失的父特色 (例如,如果只有CDS/外显子存在,则增加基因和mRNA) 增加缺失的性能 (例如外显子和UTR) 增加缺失的强制属性 (即ID, Parent) 修复标识符至惟一 修复特色地位 删除反复特色 汇合相干特色 (如果扩散在文件的不同地位) 排序功能 (tabix可选) 合并重叠的基因座成一个繁多的基因座(仅当选项激活) 转换多种格局工作工具任意 GTF/GFF 转 BEDagat_convert_sp_gff2bed.pl任意 GTF/GFF 转 GTFagat_convert_sp_gff2gtf.pl任意 GTF/GFF 转 表格agat_sp_gff2tsv.pl任意 BAM (minimap2) 转 GFFagat_convert_sp_minimap2_bam2gff.pl任意 GTF/GFF 转 ZFFagat_sp_gff2zff.pl任意 GTF/GFF 转 任意 GTF/GFF (bioperl)agat_convert_sp_gxf2gxf.plBED 转 GFF3agat_convert_bed2gff.plEMBL 转 GFF3agat_convert_embl2gff.plgenscan 转 GFF3agat_convert_genscan2gff.plmfannot 转 GFF3agat_convert_mfannot2gff.pl其它工作工具特色 统计agat_sp_statistics.plmake function statisticsagat_sp_functional_statistics.pl提取 任何类型的序列agat_sp_extract_sequences.pl提取 属性agat_sp_extract_attributes.pl补充 正文 (non-overlapping loci)agat_sp_complement_annotations.pl合并 正文agat_sp_merge_annotations.pl通过 ORF 长度 过滤基因模型agat_sp_filter_by_ORF_size.pl筛选 最长转录本agat_sp_keep_longest_isoform.pl增加 内含子特色agat_sp_add_introns.pl修复 cds 相位agat_sp_fix_cds_phases.pl操作 IDsagat_sp_manage_IDs.pl操作 UTRsagat_sp_manage_UTRs.pl操作 intronsagat_sp_manage_introns.pl操作 性能正文agat_sp_manage_functional_annotation.pl性能简介所有以 GFF/GTF 为输出的工具能够分为两组: _sp_ 和 _sq_ ...

February 22, 2024 · 2 min · jiezi

关于后端:论文分享利用对象存储进行高性能数据分析

本次分享的是慕尼黑工业大学(TUM) Dominik Durner,Viktor Leis,和 Thomas Neumann 于 2023 年 7 月发表在 PVLDB(Volume 16 No.11) 的论文:Exploiting Cloud Object Storage for High-Performance Analytics。 DB:https://umbra-db.com/论文地址:https://www.vldb.org/pvldb/vol16/p2769-durner.pdf 概述: ...Our experiments show that even without caching, Umbra with integrated AnyBlob achieves similar performance to state-of-the-art cloud data warehouses that cache data on local SSDs while improving resource elasticity...咱们的云原生时序剖析型数据库研发团队在这篇文章上受益匪浅,论文次要聚焦于如何在对象存储上进行高性能数据分析,其中一些论断为咱们的工程实际提供了明确的领导方向。 AWS S3 背景介绍AWS S3 每 TB 存储老本为 23 美元每月,同时能够实现 11 个 9 的可用性。须要留神的是,最终费用还取决于调用的 API 次数以及跨 Region 的流量费用;拜访 S3 的带宽可达到 200 Gbps,这取决于实例的带宽。在原文的 Introduce section 中为 100 Gbps,但后文提到在 AWS C7 系列机型上,这一带宽能够跑满 200 Gbps。论文中提到 AWS S3 面临以下挑战:挑战 1:无奈充分利用带宽;挑战 2:存在网络 CPU 额定开销 (次要是 One-to-one thread mapping 带来的一些问题);挑战 3:短少多云反对。 ...

February 22, 2024 · 3 min · jiezi

关于后端:SaToken事件发布观察者模式

集体博客:无奈何杨(wnhyang) 集体语雀:wnhyang 共享语雀:在线常识共享 Github:wnhyang - Overview 前文提到很屡次satoken的事件公布,应用的是观察者模式,这次就来探索一下,很简略的。 参考官网:全局侦听器 观察者模式简介:观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,当一个对象的状态产生扭转时,其所有依赖者都会收到告诉并自动更新。 在sa-token-core的cn.dev33.satoken.listener包下有 SaTokenListener 下面就是它的所有形象办法,如正文形容的那样:你能够通过实现此接口在用户登录、退出等关键性操作时进行一些AOP切面操作。 SaTokenListenerForLog框架中唯二实现SaTokenListener接口的类。 之前贴图的satoken日志都是由此类实现的。 SaTokenListenerForSimple/** * Sa-Token 侦听器,默认空实现 * * <p> 对所有事件办法提供空实现,不便开发者通过继承此类疾速实现一个可用的侦听器 </p> * * @author click33 * @since 1.31.0 */public class SaTokenListenerForSimple implements SaTokenListener { ...}SaTokenEventCenter/** * Sa-Token 事件核心 事件公布器 * * <p> 提供侦听器注册、事件公布能力 </p> * * @author click33 * @since 1.31.0 */public class SaTokenEventCenter { // --------- 注册侦听器 private static List<SaTokenListener> listenerList = new ArrayList<>(); static { // 默认增加控制台日志侦听器 listenerList.add(new SaTokenListenerForLog()); } ...}SaTokenEventCenter从命名就能够晓得这是satoken的事件公布核心类。次要属性就是List<SaTokenListener> listenerList,也就是所有侦听器,其办法次要分为两类:一类是治理侦听器,另一类就是事件公布,而且所有办法都是静态方法。 ...

February 22, 2024 · 1 min · jiezi

关于后端:AWS-EC2-必知必会小技巧-机型特点解析和选型技巧分享

背景AWS EC2 是 AWS 的弹性计算服务,为宽广开发者提供简略便捷弹性的虚拟机,是 AWS 历史最悠久的服务之一(另外一个是 S3),从 2006 年公布至今,曾经倒退了近 17 年历史。 置信不少刚开始接触 EC2 的敌人都有如下相似的感触: AWS EC2 的类型切实是太多了(数百种)!我到底应该抉择哪一种 EC2 机型既能满足业务需要且不超过预算 ?EC2 的 CPU 和 Memory 配置一样,是不是代表它们的性能差别也一样 ?采纳什么样的 EC2 付费模式才比拟划算 ?回忆 EC2 刚开始公布时,只有两种 机型可供选择,而现在则有 781 种,目不暇接的 EC2 类型必然会让开发者们陷入抉择艰难症。本文将简略介绍一些 EC2 机型抉择的小技巧,目标是为了帮忙读者可能更快地抉择适合的 EC2 机型。 机型分类和抉择总体分类只管 AWS 有数百种 EC2 机型,但其实只有以下几种大的分类: General Purpose:Compute、Memory 和 Networking 资源绝对均衡,即 M 系列和 T 系列。绝大多数场景用 General Purpose 就足够了;Compute Optimized:计算优化型,适宜计算密集型服务,即 C 系列;Memory Optimized:内存优化实例旨在为解决大型数据集的工作负载提供疾速性能,次要有 R 和 X 系列;Accelerated Computing:减速计算实例应用硬件加速器或协处理器来执行性能,例如浮点数计算、图形处理或数据模式匹配,比在 CPU 上运行的软件更高效;Storage Optimized:存储优化实例专为须要在本地存储上对十分大的数据集进行高速间断读写访问的工作负载而设计;HPC Optimized:这是 AWS 新出一个分类(HPC 系列),次要实用于须要高性能解决的应用程序,例如大型简单模仿和深度学习工作负载。一般来说,每一个具体的 EC2 型号都从属于某个带有相应数字序号的 Family,比方以 General Purpose 类型的 M 系列为例: ...

February 22, 2024 · 2 min · jiezi

关于后端:shiro-整合-springboot-实战

序言后面咱们学习了如下内容: 5 分钟入门 shiro 平安框架实战笔记 shiro 整合 spring 实战及源码详解 这一节咱们来看下如何将 shiro 与 springboot 进行整合。 spring 整合maven 依赖<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.9.RELEASE</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>shiro-inaction-01-springboot</artifactId> <description>springboot web 整合</description> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring-boot-web-starter</artifactId> <version>1.4.1</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build></project>这里次要是 spring-boot-starter-web 和 shiro-spring-boot-web-starter。 咱们这里为了演示页面,所以引入了 spring-boot-starter-thymeleaf application.properties 配置文件配置文件内容如下: # 指定服务信息server.port=7777# thymeleafspring.thymeleaf.prefix=classpath:/templates/spring.thymeleaf.check-template-location=truespring.thymeleaf.suffix=.htmlspring.thymeleaf.content-type=text/html# spring.thymeleaf.mode=HTMLspring.thymeleaf.cache=false# shiro 相干配置# 登录地址shiro.loginUrl = /login.html# Let Shiro Manage the sessionsshiro.userNativeSessionManager = true# disable URL session rewritingshiro.sessionManager.sessionIdUrlRewritingEnabled = false页面都放在 classpath:/templates/ 目录下,此处不做开展。 ...

February 22, 2024 · 2 min · jiezi

关于后端:shiro-整合-springmvc-实战及源码详解

序言后面咱们学习了如下内容: 5 分钟入门 shiro 平安框架实战笔记 shiro 整合 spring 实战及源码详解 置信大家对于 shiro 曾经有了最根本的意识,这一节咱们一起来学习写如何将 shiro 与 springmvc 进行整合。 spring mvc 整合源码maven 依赖版本号<properties> <jetty.version>9.4.34.v20201102</jetty.version> <shiro.version>1.7.0</shiro.version> <spring.version>5.2.8.RELEASE</spring.version> <taglibs.standard.version>1.2.5</taglibs.standard.version></properties>shiro 相干依赖<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>${shiro.version}</version></dependency><dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>${shiro.version}</version></dependency><dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-web</artifactId> <version>${shiro.version}</version></dependency>其余依赖次要是 servlet、spring、数据库和 tags <dependency> <groupId>javax.annotation</groupId> <artifactId>javax.annotation-api</artifactId> <version>1.3.2</version></dependency><dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope></dependency><dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version></dependency><dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version></dependency><dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version></dependency><dependency> <groupId>org.hsqldb</groupId> <artifactId>hsqldb</artifactId> <version>2.5.0</version> <scope>runtime</scope></dependency><dependency> <groupId>org.apache.taglibs</groupId> <artifactId>taglibs-standard-spec</artifactId> <version>${taglibs.standard.version}</version> <scope>runtime</scope></dependency><dependency> <groupId>org.apache.taglibs</groupId> <artifactId>taglibs-standard-impl</artifactId> <version>${taglibs.standard.version}</version> <scope>runtime</scope></dependency>jetty依赖于 jetty 作为容器启动: <plugin> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <version>${jetty.version}</version> <configuration> <httpConnector> <port>8080</port> </httpConnector> <webApp> <contextPath>/</contextPath> </webApp> </configuration></plugin>配置applicaiton.properties次要指定了 shiro 相干的配置 ...

February 22, 2024 · 8 min · jiezi

关于后端:shiro-整合-spring-实战及源码详解

序言后面咱们学习了如下内容: 5 分钟入门 shiro 平安框架实战笔记 shiro 整合 spring 实战及源码详解 置信大家对于 shiro 曾经有了最根本的意识,这一节咱们一起来学习写如何将 shiro 与 spring 进行整合。 spring 整合maven 依赖<dependencies> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.7.0</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.13.RELEASE</version> </dependency></dependencies>服务类定义定义一个简略的服务类,用于演示 @RequiresPermissions 注解的权限校验。 package com.github.houbb.shiro.inaction02.springalone;import org.apache.shiro.authz.annotation.RequiresPermissions;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Component;/** * Simple Service with methods protected with annotations. */@Componentpublic class SimpleService { private static Logger log = LoggerFactory.getLogger(SimpleService.class); @RequiresPermissions("write") public void writeRestrictedCall() { log.info("executing method that requires the 'write' permission"); } @RequiresPermissions("read") public void readRestrictedCall() { log.info("executing method that requires the 'read' permission"); }}疾速开始咱们对原来的 Quick Start 进行革新如下: ...

February 22, 2024 · 6 min · jiezi

关于后端:面试官什么是Java内存模型

当问到 Java 内存模型的时候,肯定要留神,Java 内存模型(Java Memory Model,JMM)它和 JVM 内存布局(JVM 运行时数据区域)是不一样的,它们是两个齐全不同的概念。 1.为什么要有 Java 内存模型?Java 内存模型存在的起因在于解决多线程环境下并发执行时的内存可见性和一致性问题。在古代计算机系统中,尤其是多处理器架构下,每个处理器都有本人的高速缓存,而主内存(RAM)是所有处理器共享的数据存储区域。当多个线程同时拜访和批改同一块共享数据时,如果没有适当的同步机制,就可能导致以下问题: 可见性:一个线程对共享变量所做的批改可能不会立刻反映到另一个线程的视角中,因为这些批改可能只存在于本地缓存中,并未刷新回主内存。有序性:编译器和处理器为了优化性能,可能会对指令进行重排序,这可能导致程序在单线程环境中看似依照源代码程序执行,但在多线程环境中的理论执行程序却与预期不同。原子性:即便是最简略的读取或赋值操作,在硬件层面也不肯定保障是原子性的,即在没有同步的状况下,多线程下可能看到操作只执行了一部分的后果。Java 内存模型通过定义一套规定来标准并限度编译器、运行时以及处理器对内存拜访的重排序行为,确保了多线程间的交互具备明确的语义。它规定了共享变量的拜访规定、提供了 happens-before 准则以及 volatile 关键字、synchronized 等工具来实现内存可见性和一致性的保障。这样,程序员在编写并发代码时,能够根据这些规定来确保代码的正确执行,从而防止因为多线程带来的不确定性和谬误。 如果没有 Java 内存模型就会呈现以下两大问题: CPU 和 内存一致性问题。指令重排序问题。具体内容如下。 1.1 一致性问题要讲明确缓存一致性问题,要从计算机的内存构造说起,它的构造是这样的:所以从下面能够看出计算机的重要组成部分蕴含以下内容: CPUCPU 寄存器:也叫 L1 缓存,一级缓存。CPU 高速缓存:也叫 L2 缓存,二级缓存。(主)内存当然,局部高端机器还有 L3 三级缓存。 因为主内存与 CPU 处理器的运算能力之间有数量级的差距,所以在传统计算机内存架构中会引入高速缓存(L2)来作为主存和处理器之间的缓冲,CPU 将罕用的数据放在高速缓存中,运算完结后 CPU 再讲运算后果同步到主内存中,这样就会导致多个线程在进行操作和同步时,导致 CPU 缓存和主内存数据不统一的问题。 1.2 重排序问题因为有 JIT(Just In Time,即时编译)技术的存在,它可能会对代码进行优化,比方将本来执行程序为 a -> b -> c 的流程,“优化”成 a -> c -> b 了,但这样优化之后,可能会导致咱们的程序在某些场景执行出错,比方单例模式双重效验锁的场景,这就是典型的善意办好事的事例。 2.定义Java 内存模型(Java Memory Model,简称 JMM)是一种标准,它定义了 Java 虚拟机(JVM)在计算机内存(RAM)中的工作形式,即标准了 Java 虚拟机与计算机内存之间是如何协同工作的。具体来说,它规定了一个线程如何和何时能够看到其余线程批改过的共享变量的值,以及在必须时如何同步地访问共享变量。 ...

February 22, 2024 · 1 min · jiezi

关于后端:MySQL高可用架构探秘主从复制剖析切换策略延迟优化与架构选型

MySQL高可用的基石在分布式系统中,单机节点在产生故障时无奈提供服务,这可能导致长期的服务不可用,从而影响其余节点的运作,导致的结果十分重大 为了满足服务的高可用,往往是通过节点冗余(新增雷同性能的从节点),当产生故障时进行主从切换,让从节点成为新的主节点来持续提供服务 比方:MySQL的主从、Redis的主从、MQ broker的主从...思维大体相似的 作为高可用的基石——主从架构功不可没,本篇文章就来聊聊MySQL的主从的一些细节 binlogbinlog作为逻辑上复原数据的日志,是主从数据同步、数据恢复的根底 binlog分为三种格局:statement、row、mixed statement :记录写操作的SQL,语句轻量、传输快,应用该格局可能会导致数据不统一(因为从机与主机所处的环境不同,比方从机工夫与主机不同时,应用now()函数) row : 记录数据的批改,数据量大、传输慢,误操作时能够复原数据(反向操作),主从同步时数据统一 mixed :联合statement、row的长处,主动混合选择格局 大多数状况下都是抉择格局为row,因为数据统一并且能够复原数据 主从复制往期文章中说过当收到写操作须要批改数据时,为了满足数据的一致性,会写undo log(原子性)、redo log(持久性)、binlog等日志 当主节点接管到写操作更改数据时,也须要对从节点进行数据的批改以此来达到数据统一 在主从复制数据依附的就是binlog,大抵流程分为三个阶段: 主节点dump线程监听binlog变动告诉从节点从节点应用IO线程接管binlog并将其写入本地 relay log(中继日志)从节点应用SQL线程依据relay log复原数据 在单机中写完日志即可提交事务响应,而在主从中依据响应阶段的不同,主从复制的形式分为多种: 同步复制:所有从节点都响应(复原完数据)主节点才响应,性能差、数据强统一 异步复制:主节点告诉完从节点就立马响应,性能最好,存在提早有数据一致性问题 半同步复制:只有有一个从节点响应主节点就响应,一主一从下与同步复制统一,网络超时进化为异步复制 加强半同步复制:在半同步复制的根底上,主节点收到响应后才提交事务,数据一致性会比半同步好,但性能稍差 提早复制:从节点提早一段时间复原数据,这样即便产生误操作也能够进行回滚数据 主从切换当主机产生故障时须要将从机切换为主机 不同策略个别中间件的主从切换都只能在CAP实践中满足其二,即在分区容错(P)下只能满足牢靠(C)或可用(A) binlog上会记录主节点写操作的工夫,从节点会保护一个 seconds_behind_master 来记录主从提早的工夫 在牢靠策略下,须要等到旧的从节点实现所有的数据恢复(即seconds_behind_master为0)才成为主节点,提供写服务 在此期间只提供读服务、无奈提供写服务,因而牢靠策略会损失肯定的可用性,取决于主从提早的工夫 在可用策略下会立刻将从节点设置为新的主节点提供读写服务,某些场景下可能导致数据不统一 假如id自增,记录格局为(id,name),新增数据a,b,c 主节点曾经新增(1,a),(2,b),(3,c)时宕机从节点可能只重做数据(1,a),(2,b) 而(3,c)还在中继日志中此时旧的从节点成为新的主节点又持续提供写服务,须要新增d,新增完d后才将中继日志的数据进行复原 如果应用的binlog格局为statement或mixed,则会新增为(3,d)和(4,c) 如果格局为row,则会主键抵触报错,新增(3,d)后中继日志为(3,c) 在可用策略下可能导致数据不统一,应用row会提前裸露数据不统一的问题 基于GTID的主从切换GTID 全局事务ID 格局为 server_uuid:gno server_uuid 为节点标识 gno 为事务标识(事务提交时取得,全局自增) 在进行主从切换时,每个从节点同步数据的日志偏移量都不同,个别会找最新偏移量的从节点为新的主节点(这个偏移量是须要运维去定位的) 在GTID 全局事务ID进去后,binlog中每个事务有对应的GTID则能够通过GTID主动定位偏移量,不必手动定位 主从提早起源默认状况下主从复制会应用异步复制,而在主从架构下个别会应用读写拆散,主机服务写操作,从机服务读操作 因为应用异步复制,主从之间的数据一致性会存在肯定的提早,物理上主从会放在同一机房中,网络通信忽略不计,老本最大的就是从机SQL线程解析日志复原数据的过程 如果复原数据是一些大事务时会导致很长的提早,比方在主机上执行批量操作耗时5s,在从机上执行时也会耗时那么久(资源大略统一) 可能写完操作就会进行读操作,如果此时从库还未重做数据就会导致写完查不到的数据不统一状况 先来看看哪些状况可能会导致主从提早太长: 业务高峰期频繁读写(高TPS),从机不仅要同步数据,还要解决读操作解决大事务,大事务导致延迟时间太久从机硬件配置低,导致跟不上主机IO速度主从机器可能参数不同(缓冲池、IO参数...)从机自身就是提早复制... 当主从提早过长时能够思考应用计划缩短提早: 调整redo log\bin log刷盘策略,加强IOcanal监听(告诉改为监听)从机并行复制从机并行复制借助于redo log、bin log两阶段提交时,redo log prepare阶段不会有锁抵触,能够并行执行 ...

February 22, 2024 · 1 min · jiezi

关于后端:神奇的-Bleach-网络安全清洁专家

有没有想过,在海量的网络信息中,如何确保数据的平安和污浊?恶意代码潜藏在一段段不起眼的文本里,一个不小心就可能导致平安劫难。侥幸的是,有了 Bleach 这个神奇的工具,它就像网络世界的清洁剂,让你的数据面目一新! 意识 Bleach:网络数据的清洁专家Bleach 是一个 Python 库,可能删除或本义 HTML 中的非法字符和标签,避免网站受到 XSS(跨站脚本)攻打。它背地的支持者是 Mozilla,这家因 Firefox 浏览器而广为人知的公司。 Bleach 不仅能够清理 HTML 文档,还可能对链接进行解决,查看是否是非法格局,并能够应用白名单来管制哪些 HTML 标签、属性是平安的,因而非常适合用于清洁用户输出的数据,确保网站平安。 常见的和 Bleach 相似的库包含 html-sanitizer 和 lxml 的 clean 模块等。Bleach 的劣势在于它可能间接与 HTML5lib 配合应用,这让它在解决各种简单并且不规范的 HTML 数据时更加得心应手。同时,它提供了丰盛的自定义选项,以满足不同场景下的平安需要。 我的项目地址: https://github.com/mozilla/bleach 反对的 Python 版本: Python 3.6 及以上。 装置 Bleach装置 Bleach 是一件轻而易举的事件,只须要一个 pip 命令: pip install bleach和邪恶的标签说再见Bleach 能够移除 HTML 文档中不在白名单上的所有标签和属性。一个惯例的清洁过程如下: import bleachdirty_html = "<script>alert('XSS Attack!')</script><p>Hello, World!</p>"clean_html = bleach.clean(dirty_html)print(clean_html)下面的代码将 <script> 标签移除,防止了潜在的 XSS 攻打,输入后果将仅蕴含 <p>Hello, World!</p>。 抉择你信赖的标签如果要容许某些特定的标签和属性,Bleach 容许咱们定义本人的白名单: ...

February 22, 2024 · 1 min · jiezi

关于后端:从零开始写-Docker一实现-mydocker-run-命令

本文为从零开始写 Docker 系列第一篇,次要实现 mydocker run 命令,结构了一个具备根本的 Namespace 隔离的简略容器。 <!--more--> 如果你对云原生技术充斥好奇,想要深刻理解更多相干的文章和资讯,欢送关注微信公众号。 搜寻公众号【摸索云原生】即可订阅 本文次要实现咱们的第一个命令 mydocker run,相似于 docker run -it [command]。 docker run 命令是通过创立新的 namespace 对新的过程进行视图隔离。 残缺代码见:https://github.com/lixd/mydocker 欢送 Starurfave/cli 工具次要用到了 urfave/cli 来实现命令行工具,具体用法参考官网文档。 两个罕用 cli 库比照: urfave/cli 比拟简洁,实现简略的 cli 工具举荐应用。 spf13/cobra 功能强大,实现简单的 cli 工具举荐应用。 一个简略的 urfave/cli Demo 如下: // urfaveCli cli 包简略应用,具体能够参考官网文档func urfaveCli() { app := cli.NewApp() // 指定全局参数 app.Flags = []cli.Flag{ cli.StringFlag{ Name: "lang, l", Value: "english", Usage: "Language for the greeting", }, cli.StringFlag{ Name: "config, c", Usage: "Load configuration from `FILE`", }, } // 指定反对的命令列表 app.Commands = []cli.Command{ { Name: "complete", Aliases: []string{"c"}, Usage: "complete a task on the list", Action: func(c *cli.Context) error { log.Println("run command complete") for i, v := range c.Args() { log.Printf("args i:%v v:%v\n", i, v) } return nil }, }, { Name: "add", Aliases: []string{"a"}, // 每个命令上面还能够指定本人的参数 Flags: []cli.Flag{cli.Int64Flag{ Name: "priority", Value: 1, Usage: "priority for the task", }}, Usage: "add a task to the list", Action: func(c *cli.Context) error { log.Println("run command add") for i, v := range c.Args() { log.Printf("args i:%v v:%v\n", i, v) } return nil }, }, } err := app.Run(os.Args) if err != nil { log.Fatal(err) }}具体成果如下: ...

February 22, 2024 · 7 min · jiezi

关于后端:规则引擎框架LiteFlow在渠道API项目中的应用

作者: 随风 一、渠道API我的项目简介“渠道API”是一种通过流量平台间接获取用户流量的形式。传统上咱们获取流量的形式有:投放广告,吸引用户下载主营APP进而应用借款服务;投放H5服务,用户通过不同渠道关上H5页面应用借款服务。“渠道API”的形式是指用户间接在流量方的原生APP中应用咱们的借款服务,这就须要将咱们的零碎能力依照约定的标准封装成一套API接口提供给流量方服务端调用。这里的标准能够是我方定义的,也能够是流量方定义的。这里次要探讨依照流量方规范进行接入的形式。为了进步对接的效率,咱们冀望在接入一家新渠道的时候,所做的工作越简略越好,越少越好。最好每个API只须要适配申请参数,调用底层服务,封装响应后果。但要积淀这样的底层服务何谈容易,就借款来说波及的次要流程有:准入判断、授信申请、银行卡绑定、借款、还款。首先,单个业务流程的逻辑就很简单,拿授信申请来说,须要实现用户注册、前置校验判断、实名认证、保留用户根底信息、联系人信息、支出信息、身份证照片认证、活体照片认证、戳额等,而且身份证照片认证、活体照片认证、戳额都是异步服务,须要期待认证后果来驱动流程进行。其次,不同流量方的流程也是不一样的,有的有独自的绑卡流程,有的绑卡是嵌入到借款流程中的;有的用户信息是在授信申请流程中提交,有的是在借款流程中提交;有的能够在借款流程中从新进行身份证照片认证,以防认证过期,有的则不能够。 二、引入LiteFlow的起因若以传统形式实现各业务流程,则很难防止大量硬编码判断逻辑,导致系统可扩展性差,保护老本高。咱们心愿能够将一个个业务片段封装成组件,在这些组件根底上为不同流量方的不同流程编排不同的解决逻辑。因而,咱们引入了LiteFlow框架。 三、LiteFlow简介LiteFlow是一个十分弱小的现代化的规定引擎框架,交融了编排个性和规定引擎的所有个性。LiteFlow为解耦逻辑而生,为编排而生,在应用LiteFlow之后,你会发现打造一个低耦合,灵便的零碎会变得大海捞针!利用LiteFlow,你能够将瀑布流式的代码,转变成以组件为外围概念的代码构造,这种构造的益处是能够任意编排,组件与组件之间是解耦的,组件能够用脚本来定义,组件之间的流转全靠规定来驱动。LiteFlow领有开源规定引擎最为简略的DSL语法。十分钟就可上手。 组件可实时热更替,也能够给编排好的逻辑流里实时减少一个组件,从而扭转你的业务逻辑。LiteFlow的脚本组件,反对泛滥脚本语言,齐全和Java买通,你能够用脚本来实现任何逻辑。LiteFlow反对把编排规定和脚本放在数据库,注册核心中,还有能够任意扩大的接口,不便你定制。编排语法弱小到能够编排出任何你想要的逻辑流程。 LiteFlow具备如下个性:• 组件定义对立:所有的逻辑都是组件,为所有的逻辑提供统一化的组件实现形式,小身材,大能量。• 规定轻量:基于规定文件来编排流程,学习规定入门只须要5分钟,一看即懂。• 规定多样化:规定反对xml、json、yml三种规定文件形式,喜爱哪种用哪个。• 任意编排:再简单的逻辑过程,利用LiteFlow的规定,都是很容易做到的,看规定文件就能晓得逻辑是如何运行的。• 规定长久化:框架原生反对把规定存储在规范结构化数据库,Nacos,Etcd,Zookeeper,Apollo,Redis。您也能够本人扩大,把规定存储在任何中央。• 优雅热刷新机制:规定变动,无需重启您的利用,即时扭转利用的规定。高并发下不会因为刷新规定导致正在执行的规定有任何错乱。• 反对宽泛:不论你的我的项目是不是基于Springboot,Spring还是任何其余java框架构建,LiteFlow都能熟能生巧。• JDK反对:从JDK8到JDK17,通通反对。无需放心JDK版本。• Springboot反对全面:反对Springboot 2.X到最新的Springboot 3.X。• 脚本语言反对:能够定义脚本语言节点,反对Groovy,Java,Javascript,QLExpress,Python,Lua,Aviator。将来还会反对更多的脚本语言。• 脚本和Java全买通:所有脚本语言均可调用Java办法,甚至于能够援用任意的实例,在脚本中调用RPC也是反对的。• 规定嵌套反对:只有你想的出,你能够利用简略的表达式实现多重嵌套的简单逻辑编排。• 组件重试反对:组件能够反对重试,每个组件均可自定义重试配置和指定异样。• 上下文隔离机制:牢靠的上下文隔离机制,你无需放心高并发状况下的数据串流。• 申明式组件反对:你能够让你的任意类秒变组件。• 具体的步骤信息:你的链路如何执行的,每个组件耗时多少,报了什么错,高深莫测。• 稳固牢靠:历时2年多的迭代在各大公司的外围零碎上稳固运行。• 性能卓越:框架自身简直不耗费额定性能,性能取决你的组件执行效率。• 自带简略监控:框架内自带一个命令行的监控,可能晓得每个组件的运行耗时排行。四、LiteFlow集成示例 引入依赖 实现业务组件 spring boot配置新增规定表在数据库中,新建一张表来存储编排规定。在规定表中,一行数据就是一个规定。在脚本表中,一行数据就是一个脚本组件。规定表:liteflow_chain加载规定并执行而后你就能够在Springboot任意被Spring托管的类中拿到flowExecutor,进行执行链路:五、我的项目中应用liteflow的教训对于存在多种驱动形式的业务流程,咱们倡议编排一个残缺的解决逻辑,而后通过isAccess()办法针对特定节点进行跳过解决。这种形式能够防止逻辑扩散,更加直观。以“授信申请”流程为例,授信申请须要实现用户注册、前置校验、实名认证、保留用户信息、身份证照片认证、戳额操作。咱们个别会编排如下流程:用户被动发动授信申请的流程收到身份证认证后果告诉MQ的流程执行状态弥补定时工作流程 但这种形式有如下毛病:因为流程的解决逻辑扩散在不同的中央,导致咱们无奈直观地理解流程的整体解决逻辑,在需要变更的时候,就有可能考虑不周,脱漏某些批改。倡议咱们能够编排一个残缺的业务解决流程,无论是用户被动发动、接管到告诉音讯、还是定时工作都走同样的流程。这样将解决逻辑集中在一块,让咱们对授信流程有个整体的把握,减少程序的可读性、可维护性。残缺流程如下: 此时有一个问题,流程中有些组件应该只执行一次,怎么防止每次流程运行都执行这些组件呢?LiteFlow的组件基类NodeComponent有一个办法public boolean isAccess(),如果返回false,则跳过该组件。这样咱们能够重写组件的isAccess办法并将组件的执行状态记录在数据库中,每次执行到该组件的时候,依据状态判断是否须要执行。

February 22, 2024 · 1 min · jiezi

关于后端:Go-deadcode查找没意义的死代码对于维护项目挺有用

大家好,我是煎鱼。 还记得我前两年在深圳加入了个技术大会,其中一个议题是携程的一个大佬分享他在日常工作中,发现一大堆过期的无意义代码和逻辑,导致大家工作较为繁琐且较为辛苦的状况。 携程应该是 Java 利用为主,他基于 Java 各种钻研,通过 JVM 内参数联合各种伎俩找到了无意义的死代码,并通过灰度机制等实现了逐渐上线和替换。 最近 Go 官网也终于有了相似的工具,明天分享给大家,能够继续关注! 用 deadcode 检测代码广泛来讲,作为 Go 我的项目源代码一部分,但在任何执行过程中都无奈涉及的函数被称为 "死代码",它们会连累代码库的保护工作。 也会造成程序员在浏览代码时的认知累赘,看了半天发现这代码基本没用。或是莫名其妙就被引入模块依赖里里。难堪得很。 当初咱们能够用 deadcode 来辨认他。装置形式如下: $ go install golang.org/x/tools/cmd/deadcode@latest$ deadcode -helpThe deadcode command reports unreachable functions in Go programs.Usage: deadcode [flags] package...以下是一个简略 Demo: func main() { var g Greeter g = Helloer{} g.Greet()}type Greeter interface{ Greet() }type Helloer struct{}type Goodbyer struct{}var _ Greeter = Helloer{}var _ Greeter = Goodbyer{}func (Helloer) Greet() { hello() }func (Goodbyer) Greet() { goodbye() }func hello() { fmt.Println("你好,煎鱼!") }func goodbye() { fmt.Println("再见,煎鱼!") }运行后果: ...

February 22, 2024 · 1 min · jiezi

关于后端:Aladdin编码规范Idea插件实践

背景  在软件开发过程中,不标准的代码和违规组件的引⼊经常会导致代码品质降落和给项⽬引⼊⻛险。⽽在继续集成业务中,现有代码标准扫描拦挡发⽣在代码push时候,违规组件拦挡发⽣在⽣成构建产物后,发现问题工夫点较晚,为了将品质卡点进⼀步左移、升高研发⼈员因代码准⼊失败造成的返⼯老本、提⾼代码编写品质,须要寻求上述问题场景的解决⽅案。 2. ⽅案   通过插件⽅案的调研与验证,咱们基于intellij平台开发了Aladdin研发插件,插件次要提供增量代码扫描,扫描规定基于Alibaba编码标准条款,和研发中⼼组件使⽤规约,提供多种扫描⽅式为:实时增量代码扫描、编译时增量代码扫描、提交前增量扫描、⼿动全局代码扫描、⼿动增量代码扫描。同时提供提交问题拦挡和扫描⽅式配置。 插件性能实现原理3.1 注册Inspection想要对代码进⾏扫描,咱们须要向idea注册⼀个Inspection查看器,当编辑器中代码发⽣变动或者保留代码时,都会调⽤这个查看器,扫描代码,注册渲染问题形容到对应代码中。 ● 开发⼀个⾃定义inspection , ⾸先要注册咱们的增量inspection, 在插件项⽬中\src\main\resources\META-INF\plugin.xml 插件配置⽂件中配置咱们的增量⾼危代码剖析inspection XML   1        <extensions defaultExtensionNs="com.intellij"> 2                            <localInspection language="JAVA" 3                                                                       shortName="AladdinCodeStyleP1Incr" 4                                                                       displayName="增量⾼危代码剖析" 5                                                                       hasStaticDescription="true" 6                                                                       enabledByDefault="true" 7                                                     implementationClass="com.example.PmdP1IncrInspect ion" 8                                                                       groupName="Aladdin编码标准" 9                                                                       level="ERROR" 10                                                                       runForWholeFile="true" 11                    /> 12      </extensions> ● 注册好Inspection后,接下来实现咱们的增量代码剖析性能。当idea编辑器中⽂件发⽣变动或被动保留时候,都会触发inspection的扫描,⽽Inspection可能会有很多,每⼀个都会触发⼀次,因而实时检测对性能要求⽐较⾼。明确增量代码Inspection次要有以下⼏件事件要做: 1.插件启动的时候初始化好PMD规定,并依照类型分类到不同的Inspection中2.只剖析⽬录src/main/java下的有代码变动的Java⽂件,缩⼩扫描⽂件范畴 3.调⽤PMD实现增量⽂件的扫描,获取代码存在的问题 4.依据增量代码⾏来控制代码问题的注册和编辑器中的问题标注显示 初始化规定并进⾏等级分类 ⾼危问题Inspection 继承PmdBaseInspection重写filterByPmdRulePriority()⽅法,将所有⾼危问题纳⼊PmdP1IncrInspection中 接下来就是实现psiElementVisitor来实现增量代码的扫描和问题注册渲染性能了,这个在下⽂具体介绍 3.2 增量代码实时扫描3.2.1 增量代码实时扫描原理图 性能阐明:编写代码时,实时对增量/变动代码进⾏扫描,并对有问题的代码标红提醒,并提供疾速修复性能和问题解释阐明 ⽬的:在存量代码不变动的状况下,心愿对增量的代码进⾏代码问题扫描,防⽌新增代码引⼊代码问题 ● 原理图 3.2.2 增量代码实时扫描性能阐明及效果图 ● 插件可配置开启实时⾼危增量代码扫描,并提供实时修复倡议。● 插件代码实时扫描,实时提供问题提醒及示例。如图: 3.2.3 实时增量代码扫描原理 当初⼤局部代码扫描⼯具都是对全量代码进⾏扫描,但在⼀些状况下,如⽼项⽬的存量代码不敢轻易优化,只心愿对增量代码进⾏扫描,防⽌引⼊新的代码问题,对此咱们减少了增量代码扫描的性能,思考到不同的场景对获取增量代码⾏的性能和扫描范畴的要求不同,咱们进⾏了⼀些摸索,最终采⽤了以下两种获取增量代码⾏的⽅式: 这⾥有以下关键点: 1.实时扫描是对以后⽂件的扫描,对实时性要求⾼,应最⼩老本的实现(采⽤读取idea已有的增量⾏数据)2.被动扫描,扫描范畴为整个git项⽬中增量⽂件和变更⽂件的增量代码⾏,须要咱们⾃⼰实现(这⾥加⼊扫描缓存来升高扫描增量代码⾏老本) 获取以后⽂件代码增量⾏: ⾸先,咱们观测到idea自身就帮忙咱们计算了增量⾏数据,编辑器⻚⾯就有体现,间接试⽤idea的api:project.getLineStatusManager().getLineStatusTracker获取使⽤即可,如下图所示: 核⼼代码:1.idea提供了PsiElementVisitor抽象类扩大点visitFile()可实现代码扫描性能2.咱们实现⾃⼰的PsiElementVisitor ,来实现代码问题扫描、注册、渲染的逻辑 ...

February 22, 2024 · 1 min · jiezi

关于后端:深入浅出JVM四之类文件结构

深入浅出JVM(四)之类文件构造Java文件编译成字节码文件后,通过类加载机制到Java虚拟机中,Java虚拟机可能执行所有符合要求的字节码,因而无论什么语言,只有可能编译成符合要求的字节码文件就可能被Java虚拟机执行 Java虚拟机和字节码是语言、平台无关性的基石 本篇文章将深入浅出的解析字节码文件 无关性的基石已经: 源代码->通过编译->本地机器码 Java: 源代码->通过编译->字节码 -> 解释器 -> 本地机器码 字节码: 与操作系统和机器指令集无关的,平台中立的程序编译后的存储格局 字节码是无关性的基石平台无关性的基石: 所有平台都对立反对字节码不同的Java虚拟机都能够执行平台无关的字节码因而实现了 一次编译,到处运行 语言无关性的基石: Java虚拟机字节码Java虚拟机不是只能够执行Java源代码编译而成的字节码,只有符合要求(平安...)的字节码,它都能够执行 因而Kotlin...等语言能够运行在Java虚拟机上 Class类文件构造文件格式存取数据的类型无符号数 : u1,u2,u4,u8代表1,2,4,8个字节的无符号数(能够示意数字,UTF-8的字符串,索引援用....)表: 由n个无符号数或n个表组成(命名以_info结尾)初识Class文件格式编写Java源代码 public class Test {     private int m;     private final int CONSTANT=111;      public int inc() throws Exception {         int x;         try {             x = 1;             return x;        }catch (Exception e){             x = 2;             return  x;        }finally{             x = 3;        }    } }应用可视化工具classpy查看反编译的后果每个汇合前都有一个计数器来统计汇合中元素的数量 ...

February 22, 2024 · 2 min · jiezi

关于后端:深入剖析-Java-类属性与类方法的应用

Java 类属性Java 类属性,也称为字段,是类中的变量。它们用于存储与类相干的数据。 创立类属性 在类定义中申明属性: public class Main { int x; // 属性 String name; // 属性}拜访类属性 应用点语法拜访对象的属性: Main myObj = new Main();myObj.x = 5; // 设置属性值System.out.println(myObj.x); // 获取属性值批改类属性 能够批改对象的属性值: Main myObj = new Main();myObj.x = 5;myObj.x = 10; // 批改属性值System.out.println(myObj.x); // 输入 10属性类型 属性能够是任何数据类型,包含: 根本类型:int、double、boolean、char等援用类型:String、Date、List等修饰符 能够应用修饰符来管制属性的拜访权限: public:公开拜访private:公有拜访protected:受爱护拜访default:默认拜访示例 public class Main { private int x; // 公有属性 public String name; // 公开属性 public void myMethod() { // 能够拜访公有属性 x = 10; } public static void main(String[] args) { Main myObj = new Main(); // 能够拜访公开属性 myObj.name = "John Doe"; // 无法访问公有属性 // myObj.x = 5; // 谬误 }}一些额定的阐明: ...

February 21, 2024 · 2 min · jiezi

关于后端:SoraPika文生视频模型对比

OpenAI 重磅公布文生视频模型 Sora,Sora在视频时长与视觉效果等方面相较于 Pika、Runway 等支流文生视频工具有了极大幅度的晋升。具体来看,Sora 生成的视频具备超长时长、世界模型、多镜头切换的三大个性: 1)超长时长Sora 可生成长达一分钟的高清视频,而此前 Pika、Runway 等模 型生成的视频时长仅在 20s 以内,在视频时长大幅晋升的同时,视频具备连贯性,即便人物和其余场景元素被临时遮挡或来到视线,仍能放弃一致性 2)世界模型Sora 不仅可能深刻了解用户提醒,还学会了物理世界的局部法则, 比方一个人吃汉堡后会留下咬痕、火车车窗上会产生真切的倒影,而 Runway 等模型的拟真水平则绝对较弱; 3)多镜头切换Sora 可在单个视频中设计出多个镜头,并且能在多角度的镜头切换中,实现角色和视觉格调的一致性,而 Runway 等绝大部分模型只能生成单镜头视频。 相较于此前的视频生成模型,Sora 在底层模型和算法上的翻新点次要体现在以下三个方面: 1)采纳 Transformer 架构的扩散模型不同于 Runway Gen1、Stable Video Diffusion 等扩散模型次要采纳经典的 U-Net 架构,Sora 用 Transformer 架构替 换 U-Net 架构,大幅晋升模型扩展性; 2)训练视频数据放弃原始大小 不同于其余视频生成模型通常事后将视频调整、 裁剪或修剪为规范大小,例如裁剪为分辨率为 256×256 的 4s 视频,Sora 在原 始大小的数据上进行训练,一方面数据采样更灵便,能够对宽屏 1920×1080p 视频、垂直 1080×1920 视频以及介于两者之间的所有视频进行采样,这使 Sora 能够间接以原始宽高比为不同设施创立内容,另一方面能够改善构图和取景,在 通过方形裁剪后的视频上训练的模型有时主体仅局部可见,而 Sora 生成的视频 取景失去了明显改善; 3)为训练视频生成具体的文字描述其余文生视频模型通常在大型文本-视频对 数据集上进行训练,而Sora采纳了DALL·E3和GPT的研究成果,通过为视频 训练数据生成或补充具体的字幕形容,晋升训练成果,使模型预测更精确。 目前 Sora 仍存在肯定局限性,包含无奈模仿简单场景的物理个性、难以了解特 定场景下的因果关系、误会用户提醒中的空间细节信息,有待于后续的进一步 欠缺和晋升。目前 Sora 模型已向局部专家凋谢,以评估潜在的危险,同时也正 在向局部设计师、电影制作人、视觉艺术家等授予拜访权限,以取得应用反馈。 ...

February 21, 2024 · 1 min · jiezi

关于后端:Flink-在蚂蚁实时特征平台的深度应用

摘要:本文整顿自蚂蚁团体高级技术专家赵亮星云,在 Flink Forward Asia 2023 AI 特色工程专场的分享。本篇内容次要分为以下四局部: 蚂蚁特色平台特色实时计算特色 Serving特色仿真回溯一、 蚂蚁特色平台 是一个多计算模式交融的高性能 AI 数据处理框架,可能满足 AI 训练和推理场景对特色低提早产出、高并发拜访以及在离线统一等方面的诉求。 蚂蚁建设特色平台的外围目标,是让算法同学在数据供应侧可能自力更生,即 data-self-sufficient。具体是心愿算法同学通过平台以低代码的形式进行特色研发、测试、公布、上线,整个流程不须要专门数据工程团队反对对接。 特色上线当前,背地对应的高性能实时特色生产工作、高性能查问服务以及特色在 “离线” 和 ”在线” 两个世界保持数据一致性等性能由特色平台主动提供,对用户通明。 特色平台从 2017 年开始建设,基于风控畛域的积攒和数据教训把风控的外围数据产品抽出来,组建为特色平台。这套特色平台较好地服务了蚂蚁风控的业务。在 19 年到 20 年期间,平台向全站算法业务推广的过程十分困难。外围起因是基于风控建设的特色平台蕴含十分多风控业务语义,它的计算范式是面向风控场景特地定制的,包含计算 DAG、数据精度、算子类型等都是针对风控畛域优化设计的,所以向全站推广的过程中显得难以适配。因而从 20 年开始,蚂蚁特色平台进行了彻底的重构。 截止目前,蚂蚁特色平台曾经服务了蚂蚁包含搜推,微贷,国内风控,网商,财产保险,芝麻等次要业务方。特色规模 10 万+,在线 Serving 的 QPS 两百万,日常的计算 TPS 100 万左右。 想一套特色平台满足全站特色业务诉求,平台应该具备的外围能力有以下 4 方面: 疾速实现任意计算范式的能力:首要诉求是算法同学面对异构场景、差别需要可能疾速以配置化形式将实时特色上线。所以特色平台不能和某种固定计算范式绑定,须要具备疾速实现任意灵便计算范式的能力。特色大规模仿真回溯的能力:模型训练的第一个阶段是样本筹备。如果算法同学想训练一个模型,选好了一批实时特色,而这些实时特色还没上线,意味着它没快照,构建不进去样本。因而对于这批新定义且未上线的实时特色,特色平台须要疾速计算出它们在历史时刻面对历史查问申请的“瞬时值”,即特色平台可能针对历史样本对新增未上线特色进行特色补全。这就须要特色平台具备大规模特色仿真回溯的能力,对平台提出了流批一致性的能力要求。实时特色冷启动的能力:试想某个模型里用了很多实时特色,这些实时特色又是窗口特色,如果等实时特色上线、窗口累计残缺后再提供 Serving 服务,模型迭代效率非常低。这就要求实时特色一旦定义好,要疾速补全特色窗口值,进而让特色尽快开始提供线上 Serving 服务,这就须要特色平台具备实时数据冷启动的能力。高性能特色 Serving 的能力:模型上线后,要提供一个高性能的模型推理服务,依赖的数据输出必须是高性能的。因为在模型服务的过程中,性能瓶颈点个别在数据 IO 阶段,为了让模型服务更高效、更精确,必须要提供一套高性能、低提早的特色在线查问服务。这就须要特色平台具备高性能特色 Serving 的能力。 依据四个必须具备的外围能力提出蚂蚁新一代的特色平台架构 UFE(universal-featureEngine-based-architecture),这个架构横跨离线和在线两个数据世界。离线局部是一套用于特色大规模仿真回溯的零碎。在线局部用存储把 “写” 和 “读” 两侧离开:“写” 是基于Flink打造的一套实时数据生产零碎。这套实时生产零碎跟大规模仿真零碎合起来的叫做 Skyline。“读” 是一套基于自研高性能 SQL 引擎实现的高性能特色查问服务。其次要目标是给模型推理服务提供高效的特色批量查问服务,即如何把一批特色在尽量短的提早内返回给模型服务。 Serving 服务上面有一套用于特色品质监控的 feature insight 体系。它能够实时监控特色的调用状况、耗时状况,也能够剖析特色的内容散布。如果内容散布产生了急剧的变动则会产生正告。 ...

February 21, 2024 · 2 min · jiezi

关于后端:Git合并固定分支的某一部分至当前分支

在 Git 中,通常应用 git merge 命令来将一个分支的更改合并到另一个分支。如果你只想合并某个分支的一部分代码,能够应用以下两种办法:1.批量文件合并1.1.创立并切换到一个新的长期分支首先,从要合并的源分支(即要提取代码的分支)中创立并切换到一个新的长期分支。这样能够在该分支上进行批改,以便选择性地合并代码git checkout -b temp-branch source-branchtemp-branch 是长期分支的名称source-branch 是要提取代码的源分支的名称。1.2.重置长期分支应用 git reset 命令来将长期分支重置到源分支的某个特定提交,这样就能够选择性地抉择要合并的代码git reset <commit-hash>commit-hash 是源分支中你想要合并代码的特定提交的哈希值如果你只想获取最新提交的哈希值,能够应用 git log 命令的 --oneline 选项,以简化输入 git log --oneline1.3.增加、提交和推送更改在长期分支上进行必要的更改,而后将这些更改增加、提交并推送到近程仓库。git add .git commit -m "Partial merge from source-branch"git push origin temp-branch1.4.合并到指标分支当初,你能够切换到指标分支,并应用 git merge 命令将长期分支中的更改合并到指标分支中。git checkout target-branchgit merge temp-branch1.5.解决可能的抵触如果有任何抵触,在合并过程中会被提醒,并且须要手动解决这些抵触1.6.删除长期分支如果你曾经胜利地合并了长期分支中的局部代码,那么能够将它删除git branch -d temp-branch通过以上步骤,你能够在 Git 中选择性地合并某个分支的局部代码到另一个分支中。记得在操作前做好备份,确保不会失落重要的更改2.局部文件合并如果你只想合并分支 A 中的某几个文件到以后分支(假如为指标分支),你能够应用 git checkout 命令来检出分支 A 中的指定文件,而后将这些文件复制到以后分支,最初提交更改。以下是具体的步骤:2.1.检出分支 A 中的指定文件git checkout A <path/to/file1> <path/to/file2> ...其中 path/to/file1, path/to/file2, 等等是你想要合并的文件的门路。2.2.将文件复制到以后分支如果只是简略地想要笼罩以后分支上的对应文件,你能够间接将文件复制到当前工作目录中2.3.增加、提交更改增加并提交你所复制的文件到以后分支git add .git commit -m "Merge selected files from branch A"这样就实现了只合并分支 A 中的指定文件到以后分支的操作。须要留神的是,这种办法不会保留分支 A 中的提交历史,它只是将特定文件的最新版本复制到以后分支,并创立一个新的提交。如果须要保留提交历史,你可能须要思考应用 git cherry-pick 命令来选择性地将分支 A 中的特定提交合并到以后分支3.git cherry-pick选择性合并文件git cherry-pick 命令用于选择性地将一个或多个提交从一个分支利用到另一个分支上。这个命令能够用于合并单个提交或一系列提交,而不须要将整个分支合并过去。3.1.git cherry-pick 的根本用法git cherry-pick <commit-hash-1> <commit-hash-2> ...commit-hash-1commit-hash-2, 等等是你想要利用的提交的哈希值。3.2.切换到指标分支首先,确保你在要利用更改的指标分支上git checkout target-branch3.3.利用提交而后应用 git cherry-pick 命令来利用你想要合并的提交git cherry-pick <commit-hash-1> <commit-hash-2> ...这将会将指定的提交利用到以后分支中3.4.解决抵触如果在 cherry-pick 过程中呈现了抵触,须要手动解决这些抵触3.5.提交更改解决抵触后,应用 git commit 来提交这些更改git commit如果你只是想要应用默认提交音讯,你能够间接运行 git commit 命令,Git 将会应用预设的提交音讯。这样,你就能够应用 git cherry-pick 命令将特定提交从一个分支合并到另一个分支中

February 21, 2024 · 1 min · jiezi

关于后端:Go-更强的代码洁癖可以把-gofmt-给换了

大家好,我是煎鱼。 咱们从一开始写 Go 代码和利用,就会被各种官网和民间教程,甚至 IDE 教诲咱们必须配一个 Gofmt 工具。他可能格式化 Go 程序的代码。会应用制表符示意缩进,空白示意对齐。 这解决了程序员届的老大难问题之一,代码格局上的标准问题。无效的进步了 Go 代码的浏览的友好度和缩小了共事间的 **。十分值得认可。 但有时候,还是会看到一些糟心的代码,总会感觉 Gofmt,还是格式化的不够。 明天给大家分享我发现的一个更狠的工具:gofumpt,例子次要基于官网文档。 更强的格式化:gofumptGofumpt 会执行比 gofmt 更严格的 Go 格局标准。同时确保向后兼容。 该工具是 Go 1.21 的 gofmt 分支,须要 Go 1.20 或更高版本。它能够间接代替现有的 Go 代码格式化,也就是在 gofumpt 之后运行 gofmt 不会产生任何新的变动。 装置命令: $ go install mvdan.cc/gofumpt@latest执行命令: $ gofumpt -l -w .main.go再查看对应被格式化的文件就曾经失效了。 以下是一些更具体的 gofmt 和 gofumpt 的区别例子。可能很好的帮忙大家辨认其中的差别。 赋值运算符后无空行本来由 gofmt 格式化后: func foo() string { foo := "脑子进煎鱼了!" return foo}改为 gofumpt 格式化后: func foo() string { foo := "脑子进煎鱼了!" return foo}函数体四周无空行本来由 gofmt 格式化后: ...

February 21, 2024 · 2 min · jiezi

关于后端:openai-DALLE-3-论文-提升图像生成的关键更好的图像描述

摘要咱们展现了通过训练高度描述性的生成图像题目,能够显着改善文本到图像模型的提醒追随能力。 现有的文本到图像模型在追随具体的图像形容方面存在艰难,常常疏忽单词或混同提醒的含意。 咱们假如这个问题源于训练数据集中存在嘈杂和不精确的图像题目。咱们通过训练定制的图像题目生成器来解决这个问题,并应用它从新为训练数据集生成题目。而后咱们训练了几个文本到图像模型,并发现在这些合成题目上进行训练牢靠地进步了提醒追随能力。 最初,咱们利用这些发现构建了 DALL-E 3:一个新的文本到图像生成零碎,并对其性能进行了基准测试,评估设计用于掂量提醒追随、连贯性和美感,发现它与竞争对手相比具备显著劣势。咱们公布了这些评估的样本和代码,以便将来的钻研能够持续优化文本到图像零碎的这一重要方面。 1 引言近年来生成建模的停顿使得文本到图像生成模型实现了显著的性能晋升。 特地是,通过采纳基于采样的办法,如自回归生成建模[27, 2, 1, 20, 30]或应用扩散过程[25, 6, 11, 12, 19, 22]来解决问题,使咱们可能将图像生成问题合成为小的、离散的步骤,这些步骤更容易被神经网络学习。 与此同时,钻研人员还找到了利用自注意力层重叠构建图像生成器的办法[15, 3, 4]。 通过将图像生成与卷积的隐含空间偏差拆散开来,使文本到图像模型可能通过变压器的良好钻研的缩放属性牢靠地改良。 联合足够大的数据集,这些办法使得能够训练出大型的文本到图像模型,这些模型可能生成靠近人类能够产生的照片和艺术品品质的图像。 该畛域面临的一个重要挑战是图像生成零碎的可控性,这些零碎常常疏忽给定题目中的单词、单词程序或含意。咱们用术语“提醒追随”来指代这些挑战。 在几项钻研中曾经指出了这个问题:Rassin等人(2022年)指出DALL-E 2没有强制要求每个单词只有一个含意。Saharia等人(2022年)提出通过对预训练语言模型进行条件化来改良它,并引入了一个名为Drawbench的评估,揭示了常见的提醒追随问题。与此同时,Yu等人(2022b年)引入了他们本人的基准测试Parti Prompts,并表明扩大自回归图像生成器是改良提醒追随的另一种代替办法。 在这项工作中,咱们提出了一种解决提醒追随的新办法:题目改良。咱们假如现有文本到图像模型的一个基本问题是它们所训练的数据集中文本和图像配对的品质较差,这个问题在其余作品中也被指出,比方Jia等人(2021年)。咱们提出通过为数据集中的图像生成改良的题目来解决这个问题。咱们首先学习一个弱小的图像题目生成器,它可能产生图像的具体精确的形容。而后,咱们将这个题目生成器利用于咱们的数据集,以产生更具体的题目。最初,咱们在改良后的数据集上训练文本到图像模型。 在合成数据上进行训练并不是一个新概念。例如,Yu等人(2022b年)提到他们在训练扩大自回归图像生成器时利用了这种技术。咱们的奉献在于构建了一种新鲜的、描述性的图像题目生成零碎,并测量了在训练生成模型时应用合成题目的影响。咱们还建设了一套可重现的基准性能档案,用于掂量提醒追随的一系列评估。 本文重点评估了DALL-E 3在训练高度描述性的生成题目时改良的提醒追随能力。它不涵盖DALL-E 3模型的训练或实现细节。咱们在第2节中提供了一个训练图像题目生成器的高级概述,第3节评估了在原始题目与生成题目上训练的文本到图像模型,第4节评估了DALL-E 3,第5节探讨了限度和危险。 2 数据集从新生成题目咱们的文本到图像模型是在一个由大量配对 (t, i) 组成的数据集上进行训练的,其中 i 是一幅图像,t 是形容该图像的文本。 在大规模数据集中,t 通常是由人类作者衍生进去的,他们专一于简略形容图像的主题,省略了背景细节或图像中描述的常识关系。通常从 t 中省略的重要细节可能包含: 厨房中存在的水槽或人行道上的停车标记等对象以及这些对象的形容。场景中对象的地位以及这些对象的数量。场景中对象的色彩和大小等常识细节。图像中显示的文字。更蹩脚的是,在互联网上找到的题目往往是谬误的;它们形容了图像的相干细节。例如,常见的状况是在用于生成图像题目的 alt-text 中发现广告或迷因。 咱们揣测所有这些缺点都能够通过合成生成的题目来解决。在接下来的局部中,咱们将探讨咱们开发的测试这一实践的程序。 2.1 构建图像题目生成器图像题目生成器与传统的语言模型十分类似,它预测文本。因而,咱们首先提供对语言模型的简要形容。首先,应用分词器将文本字符串合成为离散的标记。一旦以这种形式合成,咱们语料库中的文本局部能够示意为一个序列,t = [t1, t2, . . . , tn]。而后,咱们能够通过最大化以下似然函数来构建一个语言模型: L(t) = log P(tj |tj−k, . . . , tj−1; ) (1) ...

February 21, 2024 · 3 min · jiezi

关于后端:openai-DALLE-3-从文本描述生成图像原理通俗解释

序言在数字时代,图像生成技术正日益成为人工智能畛域的热点。 本探讨将重点聚焦于两个备受瞩目的模型:DALL-E和其余支流AI绘图办法。 咱们将探讨它们的劣势、局限性以及将来的倒退方向。通过比拟剖析,咱们冀望可能更全面地理解这些技术,为将来的钻研和利用提供启发。 Q: 介绍一下 dall-eOpenAI的DALL-E是一个基于深度学习的生成模型,专门用于从文本形容生成图像。 它的名字灵感来源于艺术家Salvador Dali和瓦尔特·艾利斯(Walt Disney)的姓氏组合。 DALL-E的设计灵感来自于OpenAI之前的图像生成模型GPT(Generative Pre-trained Transformer)和CLIP(Contrastive Language-Image Pre-training),它交融了这两种模型的思维。 DALL-E的核心思想是应用Transformer架构来解决输出文本,并通过多层次的卷积神经网络来生成与文本形容相干的图像。 与传统的图像生成模型不同,DALL-E并不是简略地将文本转换成像素级别的图像,而是依据文本的语义和构造来生成视觉上相干的图像。 这使得DALL-E可能发明出与事实世界齐全不同但合乎形容的图像,展示了其在创造性图像生成方面的后劲。 DALL-E的训练过程是基于大规模的图像-文本对数据集进行的,模型通过自监督学习来学习图像和文本之间的对应关系。 在训练过程中,DALL-E被要求预测被遮蔽的局部或与输出文本不统一的局部,从而促使它学习生成与输出文本匹配的图像。 DALL-E的利用后劲十分宽泛,包含但不限于: 创意图像生成:DALL-E能够依据文本形容生成创意图像,例如“一只马由拖拉机的形态组成”。图像编辑和合成:通过批改输出文本,能够实现图像的编辑和合成,例如“在这个房子的屋顶上加一个草坪”。视觉推理和了解:DALL-E能够用于视觉推理工作,例如“给出一段文本形容,推断可能的场景或物体”。只管DALL-E展现出了微小的后劲,但它依然存在一些挑战,例如在生成图像时放弃视觉品质和语义一致性,以及解决简单的文本输出。 随着深度学习和自然语言解决畛域的一直倒退,咱们能够期待DALL-E在将来会有更多的提高和利用。 Q: 通俗易懂的介绍一下 dall-e 的实现原理DALL-E的实现原理能够简略概括为以下几个步骤: 输出文本编码:首先,DALL-E接管到用户提供的文本形容,比方“一只兔子坐在大理石上的薄荷糖上”。这段形容会通过编码器,将文本转换为计算机能够了解的数字模式,称为向量。图像生成:接下来,DALL-E的生成器会依据编码后的文本向量生成图像。生成器是一个经过训练的神经网络,它会依据输出的文本形容来“设想”出对应的图像。这个过程相似于一位艺术家依据形容画出一幅图画,然而这里是由神经网络实现的。优化和训练:在训练过程中,DALL-E会通过大量的图像-文本对数据进行训练。它会一直地调整生成器的参数,使得生成的图像尽可能地与输出的文本形容相匹配。这个过程通常须要大量的计算资源和工夫,以确保生成的图像品质和语义一致性。生成图像输入:最初,DALL-E会将生成的图像输入给用户。用户能够依据须要提供不同的文本形容,DALL-E会依据新的形容从新生成图像。总的来说,DALL-E的实现原理就是通过将文本形容编码成向量,而后利用生成器网络生成对应的图像。 通过一直地优化和训练,DALL-E可能生成与文本形容相符合的图像,展现出弱小的创造力和想象力。 Q: 如何依据编码后的文本向量生成图像?生成图像的过程通常波及将编码后的文本向量输出到一个生成器模型中。这个生成器模型通常是一个深度神经网络,常见的是基于变分自编码器(VAE)或生成反抗网络(GAN)的架构。 变分自编码器(VAE): 在VAE中,编码后的文本向量被视为潜在空间中的点,示意图像的潜在特色。这个潜在点通过解码器(也就是生成器)网络,被映射到图像空间,生成对应的图像。解码器网络通常是一个反卷积神经网络,通过多层次的反卷积操作逐步将潜在特色转换为图像。生成反抗网络(GAN): 在GAN中,生成器网络接管编码后的文本向量作为输出,生成一张图像。生成器的指标是生成真切的图像,使得判断器无奈将生成的图像与实在图像辨别开来。判断器网络则负责辨别生成的图像和实在的图像,它的指标是尽可能精确地区分两者。不论是VAE还是GAN,生成器网络都须要经过训练,以学习如何从编码后的文本向量生成对应的图像。 在训练过程中,生成器会一直地调整参数,使得生成的图像尽可能地与实在图像类似,并且合乎输出的文本形容。通常须要应用大量的图像-文本对数据进行训练,以取得更好的生成成果。 总的来说,生成图像的过程就是将编码后的文本向量输出到生成器网络中,通过网络的映射和变换,生成对应的图像。 Q: dall-e 是如何依据文本向量生成图像的?DALL-E(和相似的模型,比方GAN和VAE)通常应用生成反抗网络(GAN)的思维来生成图像。 上面是DALL-E如何依据文本向量生成图像的简要步骤: 文本编码:首先,输出的文本被编码成一个固定长度的向量。这个向量捕获了文本形容的语义和内容,将其转化为了机器能够了解的数值模式。在DALL-E中,这通常是通过预训练的Transformer模型(如GPT)来实现的。生成器网络:DALL-E有一个生成器网络,它接管文本向量作为输出。这个生成器网络的工作是将输出的文本向量映射到图像空间,并生成与文本形容绝对应的图像。这个网络通常蕴含了多层神经网络,能够是卷积神经网络(CNN)、变分自编码器(VAE)或其余类型的网络结构。生成图像:生成器网络依据文本向量生成图像的过程波及将文本向量转化为一个两头示意,而后通过多个档次的神经网络变换逐步生成图像。在每个阶段,网络都会减少细节和复杂度,直到生成残缺的图像。训练:在训练过程中,DALL-E的生成器网络通过反向流传算法和反抗训练策略来学习如何生成真切的图像。这意味着生成器试图坑骗一个判断器网络,而判断器网络则试图辨别生成的图像和实在的图像。通过这种反抗的训练过程,生成器一直地改良本人的能力,生成更加真切的图像。输入图像:最终,生成器网络生成的图像被输入给用户。这些图像通常与输出的文本形容相匹配,反映了模型对文本语义的了解和图像生成的能力。总之,DALL-E通过一个生成器网络,将输出的文本形容映射到图像空间,并生成与形容相符的图像。这个过程波及将文本向量转化为图像的两头示意,并通过神经网络变换逐步生成图像,同时通过反抗训练来进步生成器的性能。 Q: 介绍一下 反向流传算法和反抗训练策略,以及为什么须要?反向流传算法(Backpropagation)是深度学习中用于训练神经网络的一种优化算法。它通过计算损失函数对网络参数的梯度,而后利用梯度降落等优化算法来更新网络参数,从而使得网络可能逐步拟合训练数据,实现对工作的学习。 反向流传算法的步骤如下: 前向流传:从输出数据开始,通过神经网络的前向流传过程,计算输入后果。计算损失:将网络的输入后果与实在标签进行比拟,计算损失函数的值。反向流传:依据损失函数,计算网络参数(权重和偏置)对损失函数的梯度。参数更新:依据梯度降落等优化算法,更新网络参数,减小损失函数的值。反复步骤1-4,直到达到进行条件(如达到最大迭代次数或损失函数收敛)。反向流传算法是深度学习中十分重要的一部分,它使得神经网络可能通过大量的数据主动学习特色,并依据工作调整网络参数,从而实现对各种简单工作的高效学习。 反抗训练(Adversarial Training)是一种通过引入对抗性样本来进步模型鲁棒性的训练策略。在反抗训练中,模型在训练过程中不仅须要优化损失函数来最小化预测误差,还须要对抗性地解决针对模型的攻打。这样,模型不仅可能对失常样本进行精确预测,还可能在面对对抗性样本时放弃稳健性。 反抗训练的根本思维是引入对抗性扰动,使得模型在训练中对这种扰动具备鲁棒性。对抗性样本通常是通过对原始样本进行渺小的扰动来生成的,这种扰动尽管对人类视觉简直无影响,但可能导致模型产生谬误的预测后果。 反抗训练的目标是使得模型可能在真实世界的简单环境中放弃稳健性,不易受到攻打或噪声的烦扰。 在许多利用中,反抗训练曾经被证实能够显著进步模型的性能和鲁棒性,特地是在平安相干的畛域,如图像识别、语音辨认和自然语言解决等。 Q: dall-e 又是如何保障绘制的图像存在肯定的逻辑呢?DALL-E 在生成图像时,只管它能够生成十分奇异的图像,但也偏向于生成一些与输出形容逻辑相干的图像。这种逻辑性的保障次要来自于以下几个方面: 训练数据的语义一致性:DALL-E是在大规模的图像-文本对数据集上进行训练的,这些数据集往往是通过筛选和整顿的,保障了图像和文本之间的语义一致性。在训练过程中,模型学习到了图像和文本之间的对应关系,从而能够在生成图像时放弃肯定的逻辑。图像-文本匹配:DALL-E是基于文本形容生成图像的,它会尽量放弃生成的图像与输出形容之间的匹配水平。在训练时,模型被要求依据文本形容生成与之匹配的图像,从而促使模型学习到生成与输出形容逻辑相干的图像。语义空间的连续性:DALL-E的潜在空间(latent space)是间断的,并且具备肯定的语义构造。这意味着在潜在空间中,类似的文本形容对应的图像也会在空间中彼此靠近。因而,如果输出的文本形容在语义上是间断的,那么生成的图像也会在肯定水平上放弃间断和逻辑上的一致性。生成器网络的限度:DALL-E的生成器网络是在训练数据集上学习到的,并且受到网络结构和参数的限度。这使得生成的图像在肯定水平上受到了训练数据的束缚,从而保障了生成的图像具备肯定的逻辑性和合理性。只管DALL-E能够生成十分奇异和想象力丰盛的图像,但在许多状况下,它依然会尽量放弃与输出形容相干的逻辑和语义一致性。这使得DALL-E在生成图像时不仅具备创造性和想象力,同时也可能放弃肯定的合理性和逻辑性。 Q: 艰深点的潜在空间的解释?设想你有一张彩色图片,它由成千上万个像素点组成。每个像素点都有本人的色彩值,而且这些色彩值组合在一起就形成了这张图片。 潜在空间就像是这张图片的一个简化版。它不是间接示意每个像素点的色彩值,而是示意了图片的一些重要特色,比方图片中的次要物体、背景、纹理等等。 你能够把潜在空间设想成一个更简洁的形容,它捕获了图片中最重要的信息,但没有具体到每个像素点的细节。 这个潜在空间能够用来做很多事件,比方生成新的图片,批改图片的特色,甚至是进行图像检索。因为它是对图片的高维示意进行了压缩和提取,所以更容易解决和剖析。 Q: 潜在空间(latent space)是什么?具体介绍一下潜在空间(Latent Space)是指在机器学习和深度学习中,数据通过编码或者降维之后所处的形象空间。 这个概念通常用来形容数据的暗藏特色或者示意,它是通过对原始数据进行转换而失去的,能够更好地表白数据的构造和特色。 上面是对于潜在空间的具体介绍: 数据表示与潜在空间: ...

February 21, 2024 · 1 min · jiezi

关于后端:深入浅出JVM三之HotSpot虚拟机类加载机制

HotSpot虚拟机类加载机制类的生命周期什么叫做类加载?类加载的定义: JVM把形容类的数据从Class文件加载到内存,并对数据进行校验,解析和初始化,最终变成能够被JVM间接应用的Java类型(因为能够动静产生,这里的Class文件并不是具体存在磁盘中的文件,而是二进制数据流) 一个类型被加载到内存应用 到 完结卸载出内存,它的生命周期分为7个阶段: 加载->验证->筹备->解析->初始化->应用->卸载 其中重要阶段个别的开始程序: 加载->验证->筹备->解析->初始化 验证,筹备,解析合起来又称为连贯所以也能够是加载->连贯->初始化 留神这里的程序是个别的开始程序,并不一定是执行完某个阶段完结后才开始执行下一个阶段,也能够是执行到某个阶段的中途就开始执行下一个阶段 还有种非凡状况就是解析可能在初始化之后(因为Java运行时的动静绑定) 根本数据类型不须要加载,援用类型才须要被类加载 类加载阶段接下来将对这五个阶段进行具体介绍 Loading加载加载的作用通过这个类的全限定名来查找并加载这个类的二进制字节流 JVM通过文件系统加载某个class后缀文件读取jar包中的类文件数据库中类的二进制数据应用相似HTTP等协定通过网络加载运行时动静生成Class二进制数据流将这个类所代表的动态存储构造(动态常量池)转化为办法区运行时数据结构(运行时常量池)在堆中创立这个类的Class对象,这个Class对象是对办法区拜访数据的"入口" 堆中实例对象中对象头的类型指针指向它这个类办法区的类元数据对于加载能够由JVM的自带类加载器来实现,也能够通过开发人员自定义的类加载器来实现(实现ClassLoader,重写findClass())留神 数组类是间接由JVM在内存中动静结构的,数组中的元素还是要靠类加载器进行加载反射正是通过加载创立的Class对象能力在运行期应用反射Verification验证验证的作用 确保要加载的字节码符合规范,避免危害JVM平安 验证的具体划分 文件格式验证 目标: 保障字节流能正确解析并存储到办法区之内,格局上合乎Java类型信息 验证字节流是否合乎Class文件格式标准(比方Class文件主,次版本号是否在以后虚拟机兼容范畴内...) 元数据验证 目标: 对类的元数据信息进行语义验证 元数据:简略的来说就是形容这个类与其余类之间关系的信息 元数据信息验证(举例): 这个类的父类有没有继承其余的最终类(被final润饰的类,不可让其余类继承)若这个类不是抽象类,那这个类有没有实现(形象父类)接口的所有办法字节码验证(验证中最简单的一步) 目标: 对字节码进行验证,保障校验的类在运行时不会做出对JVM危险的行为 字节码验证举例: 类型转换无效: 子类转换为父类(平安,无效) 父类转换为子类(危险)进行算术运算,应用的是否是雷同类型指令等符号援用验证 产生在解析阶段前:符号援用转换为间接援用 目标: 保障符号援用转为间接援用时,该类不短少它所依赖的资源(外部类),确保解析能够实现 验证阶段是一个十分重要的阶段,但又不肯定要执行(因为许多第三方的类,本人封装的类等都被重复"试验"过了) 在生产阶段能够思考敞开 -Xverify:none以此来缩短类加载工夫 Preparation筹备筹备阶段为类变量(动态变量)分配内存并默认初始化 分配内存 逻辑上应该调配在办法区,然而因为hotSpot在JDK7时将字符串常量,动态变量挪出永恒代(放在堆中)实际上它应该在堆中默认初始化 类变量个别的默认初始化都是初始化该类型的零值 类型零值byte(byte)0short(short)0int0long0Lfloat0.0Fdouble0.0booleanfalsechar'\u0000'referencenull非凡的类变量的字段属性中存在ConstantValue属性值,会初始化为ConstantValue所指向在常量池中的值只有被final润饰的根本类型或字面量且要赋的值在常量池中才会被加上ConstantValue属性 Resolution解析解析的作用 将常量池中的常量池中符号援用替换为间接援用(把符号援用代表的地址替换为实在地址) 符号援用 应用一组符号形容援用(为了定位到指标援用)与虚拟机内存布局无关还是符号援用时指标援用不肯定被加载到内存间接援用 间接执行指标的指针,绝对偏移量或间接定位指标援用的句柄与虚拟机内存布局相干解析间接援用时指标援用曾经被加载到内存中并未规定解析的工夫 能够是类加载时就对常量池的符号援用解析为间接援用 也能够在符号援用要应用的时候再去解析(动静调用时只能是这种状况) 同一个符号援用可能会被解析屡次,所以会有缓存(标记该符号援用曾经解析过),屡次解析动作都要保障每次都是雷同的后果(胜利或异样)类和接口的解析当咱们要拜访一个未解析过的类时 把要解析的类的符号援用 交给以后所在类的类加载器 去加载 这个要解析的类解析前要进行符号援用验证,如果以后所在类没有权限拜访这个要解析的类,抛出异样IllegalAccessError字段的解析解析一个从未解析过的字段 先对此字段所属的类(类, 抽象类, 接口)进行解析而后在此字段所属的类中查找该字段简略名称和描述符都匹配的字段,返回它的间接援用 如果此字段所属的类有父类或实现了接口,要自下而上的寻找该字段找不到抛出NoSuchFieldError异样对此字段进行权限验证(如果不具备权限抛出IllegalAccessError异样)确保JVM取得字段惟一解析后果 如果同名字段呈现在父类,接口等中,编译器有时会更加严格,间接回绝编译Class文件 办法的解析解析一个从未解析过的办法 先对此办法所属的类(类, 抽象类, 接口)进行解析而后在此办法所属的类中查找该办法简略名称和描述符都匹配的办法,返回它的间接援用 如果此办法所属类是接口间接抛出IncompatibleClassChangeError异样如果此办法所属的类有父类或实现了接口,要自下而上的寻找该办法(先找父类再找接口)如果在接口中找到了,阐明所属类是抽象类,抛出AbstractMethodError异样(本身找不到,父类中找不到,最初在接口中找到了,阐明他是抽象类),找不到抛出NoSuchMethodError异样对此办法进行权限验证(如果不具备权限抛出IllegalAccessError异样)接口办法的解析解析一个从未解析过的接口办法 先对此接口办法所属的接口进行解析而后在此接口办法所属的接口中查找该接口办法简略名称和描述符都匹配的接口办法,返回它的间接援用 ...

February 21, 2024 · 2 min · jiezi

关于后端:通俗易懂剖析Go-Channel理解并发通信的核心机制

本文来自 Go待业训练营 小韬同学的投稿。 也强烈安利大家多写博客,不仅能倒逼本人学习总结,也能作为简历的加分项,进步求职面试的竞争力。 你想想看:面试官看到你简历中的博客主页有几十篇文章,几千粉丝是什么感觉。要比你空洞洞的写一句“酷爱技术”强太多啦! 注释咱们在学习与应用Go语言的过程中,对channel并不生疏,channel是Go语言不同凡响的个性之一,也是十分重要的一环,深刻了解Channel,置信可能在应用的时候更加的得心应手。 一、Channel根本用法1、channel类别channel在类型上,能够分为两种: + 双向channel:既能接管又能发送的channel + 单向channel:只能发送或只能接管的channel,即单向channel能够为分为:     + 只写channel     + 只读channel 申明并初始化如下如下: func main() {     // 申明并初始化     var ch chan string = make(chan string) // 双向channel     var readCh <-chan string = make(<-chan string) // 只读channel     var writeCh chan<- string = make(chan<- string) // 只写channel } 上述定义中,<-示意单向的channel。如果箭头指向chan,就示意只写channel,能够往chan里边写入数据;如果箭头远离chan,则示意为只读channel,能够从chan读数据。 在定义channel时,能够定义任意类型的channel,因而也同样能够定义chan类型的channel。例如: a := make(chan<- chan int)   // 定义类型为 chan int 的写channel b := make(chan<- <-chan int) // 定义类型为 <-chan int 的写channel c := make(<-chan <-chan int) // 定义类型为 <-chan int 的读channel d := make(chan (<-chan int)) // 定义类型为 (<-chan int) 的读channel 当channel未初始化时,其零值为nil。nil 是 chan 的零值,是一种非凡的 chan,对值是 nil 的 chan 的发送接管调用者总是会阻塞。 ...

February 21, 2024 · 7 min · jiezi

关于后端:云音乐舆情平台建设云音乐舆情平台建设

本文作者:王桂泽本文介绍了云音乐舆情平台建设过程中遇到的一些问题和解决方案。 背景介绍通用舆情剖析概念和局限通用的舆情剖析是指通过收集、整顿和剖析公众对某一特定话题或事件的舆论、观点和情感,从而理解公众对该话题或事件的态度和情绪的办法。舆情剖析能够通过监测社交媒体、新闻媒体、论坛、博客等渠道上的信息来获取公众的声音和反馈。 通用舆情剖析的局限 通用的舆情剖析因为数据起源宽泛,内容格局宽泛,仅能基于特定主题进行情感剖析或趋势剖析,无奈深刻开掘信息,这意味着企业可能无奈取得对于产品的具体反馈和倡议,无奈理解消费者对产品的具体需要和改良方向。因而,为了满足企业外部对产品晋升的需要,可能须要采纳更业余、更定制化的舆情剖析工具和办法,以便更全面、深刻地理解消费者对产品的态度和冀望。 云音乐舆情平台建设1. 数据特色:数据起源丰盛云音乐舆情剖析的数据起源不仅包含内部公众渠道上的信息(比方社交媒体、新闻、博客等),还有许多外部的数据起源,例如通过APP提交的反馈数据,在歌曲下方的评论数据,或者是通过七鱼客服人工反馈的数据等等。这些数据为精细化的舆情剖析提供了根底。 这些数据具备如下特点: 相关性更高:反馈内容都与产品密切相关。馈更加及时:反馈音讯实时推送,具备高时效性。更加结构化:除了反馈内容,还包含用户信息、设施信息、零碎信息等。2. 剖析诉求:精细化剖析诉求云音乐的舆情剖析平台与通用的舆情剖析不同,它须要反对更多维度和更粗疏的剖析能力,以满足不同业务和场景的监控需要。 聚类分析 云音乐领有多个产品,每个产品都有各自的功能模块,而每个功能模块还能够进一步细分为子性能。能够将这种构造了解为每个产品都有一个性能树(聚类树)。聚类分析是指将舆情数据归类到聚类树上的某个具体的聚类节点,以便更好地理解用户对不同功能模块的态度和需要,从而针对性地进行改良和优化产品。 反馈类型剖析 在确定舆情所属的功能模块之后,还须要进一步剖析用户的反馈类型,不同的反馈类型须要不同的角色关注。包含: 问题反馈:反馈产品或性能问题,开发人员须要关注产品倡议:反馈产品或性能改良倡议,产品经理须要关注应用征询:用户征询产品的应用办法或者相干问题,客服须要关注投诉举报:反馈产品或性能的不良问题或违规行为,合规人员须要关注摘要提取 摘要提取是指提取舆情音讯中的要点和要害信息。通过对原始音讯进行提炼,摘要辨认能够帮忙用户疾速理解舆情音讯。另外,能够对大量舆情音讯进行摘要剖析,以便发现整体问题和趋势,并发现新的热点问题。 情感剖析 情感剖析相似于传统的舆情剖析,次要是辨认用户情感,包含正向、负向和中性。能够帮忙咱们理解用户对特定性能的态度和情绪,从而领导产品的改良和优化方向。 3. 智能监控:监控和报警舆情监控和通用的监控零碎存在一些区别: 有些渠道的舆情音讯是定时爬取的,实时性要求不高舆情音讯量个别都比拟大,个别是对整体趋势、热点问题的监控舆情变化趋势是随机的,和外部产品和外部环境都有关系,没有特定的法则这就要求平台制订更加智能的监控策略,当舆情音讯超出预期时,能够通过短信、邮件等形式向指定人员发送报警告诉,以便相干人员及时处理。 舆情流转链路云音乐舆情平台更加专一于舆情数据的剖析、洞察和监控,通过定义标准化的数据结构疾速接入不同起源的数据,上面是外围的舆情流转链路: 舆情数据来自第三方平台,包含:反馈平台,七鱼私信平台、大数据平台;上报反对包含MQ协定和http协定;输入原始舆情。 适配器:原始舆情先通过适配器解决,标准化各数据源模型构造,补充设施、产品等元数据信息。输入规范舆情。 分析器:对规范舆情进行内容分析,依据舆情所属空间,获取该空间的聚类树,并进行聚类分析、情感剖析、用意剖析、摘要剖析、关键词剖析。输入规范舆情+剖析标。 存储器:将规范舆情和剖析标存储到Elasticsearch,供后续在线查问和剖析。 报警计算器:依据平台内的报警规定(零碎报警+用户报警),判断以后舆情是否满足报警规定并触发报警。 在线查问&剖析:查问、趋势剖析、聚合剖析等。 舆情大盘:发现热点事件、各剖析维度的排行榜等。 舆情音讯模型平台数据起源渠道宽泛,而且每个数据源都有独立的属性,既要反对针对每种渠道的精细化剖析,也要反对在全局视角对多种渠道数据进行整体剖析。为了解决这个问题,平台设计了通用的舆情音讯模型,在数据接入层和产品展现层,都是面向这个数据模型进行设计,这样设计的益处有: 在数据接入层,能够疾速接入新的数据源在产品层,能够复用舆情查问、剖析、报警等性能 一条标准化的舆情音讯有上面一些属性: 数据源数据源是指舆情的数据起源,比方来自App的用户反馈,来自七鱼私信的客服对话等。平台会依据不同的数据源,在产品层做动静的性能展现。比方在舆情查问页,会依据数据源展现相应的属性,在报警配置页,会依据数据源展现相应的筛选条件。 根底属性每种数据源都有一些根底属性。这些属性是在舆情上报时可能辨认并携带上来的,例如用户信息、设施信息、App信息、操作系统信息等。平台反对依照所有根底属性做筛选、聚合剖析,在报警的时候也能够依照所有根底属性做筛选,提供了灵便的查问和监控能力。 分析属性除了根底属性,分析器(包含平台内置的分析器和用户自定义的分析器)还会为舆情增加额定的分析属性。不同的分析器会生成不同的分析属性,例如情感分析器会生成情感属性,聚类分析器会生成聚类属性等。和根底属性相似,所有分析属性都反对筛选、聚合剖析。 扩大属性反对业务方自定义一些扩大属性,以满足不同业务方差异化的查问和剖析需要。 技术架构 数据接入:原始舆情数据,有来自反馈平台、七鱼平台、数据平台等;协定反对MQ和http协定。 解决层: 适配器:将各种起源的数据源整合成规范文档构造,并补充元数据:如产品、设施信息、用户信息等。分析器:对舆情内容进行多维度剖析,包含:聚类、情感、用意、关键词、摘要提取,剖析之后会打上剖析标数据管理:数据管理次要是配置解决层的解决规定以及报警规定 剖析&可视化层:提供对剖析之后的舆情数据的查问和剖析能力; 监控&报警:对接通用监控和对立报警实现舆情监控;同时提供定时剖析和舆情洞察能力,提供舆情大盘和日报性能。 剖析引擎剖析引擎负责对采集上来的数据做剖析,生成对应的分析属性。 平台会内置一些分析器,比方情感剖析、聚类分析、反馈类型剖析等。分析器的抉择是灵便的,能够依据舆情的数据特色(数据源和根底属性)和剖析需要,抉择相应的一个或多个分析器进行剖析解决。同时,平台也能够不便地增加自定义的分析器,以满足不同场景的剖析需要。能够通过GPT提醒词开发、SDK插件、服务接入等多个形式接入自定义的分析器。 内置分析器 平台内置的分析器都是基于GPT开发的,相比传统的机器学习、NLP等分析方法,应用GPT剖析具备以下劣势。 首先,GPT模型可能更好地了解和解决自然语言,在语义了解和文本生成方面表现出色,更好地了解语言的上下文和含意,从而析过程中可能更精确地捕捉到轻微的语义差别。其次,GPT不须要人工标注训练数据,依据需要调整提醒词后即可立刻失效。传统的机器学习和NLP办法通常须要大量标注数据来训练模型,须要消耗大量人力、机器和工夫老本,无奈满足疾速变动的业务需要。另外,GPT模型还能具备总结演绎、发现新问题的能力,而传统的机器学习和NLP办法则则无奈实现这一工作。GPT老本优化 与传统的机器学习、NLP等分析方法相比,GPT剖析会产生费用,并且随着剖析文本数量的减少,老本也会增长。在某些状况下,老本可能会很高,例如在进行聚类分析时,须要将聚类树和文本一起输出给GPT。然而,聚类树自身(包含节点和节点的形容)可能十分宏大,这将耗费大量的Token。平台也针对性的做了一些老本优化措施: 优化1 缓存 基于常见文本的剖析后果缓存基于文本+聚类树版本的剖析后果缓存优化2 精简聚类树 聚类分析场景中,聚类树自身耗费了大量的Token,能够在剖析之前通过文本类似度算法先筛选出"可能归属"的聚类,在剖析的时候只须要剖析这些聚类即可,这能够大大减少聚类树的大小, 无效地升高剖析老本。 在线查问&聚合剖析舆情音讯通过剖析引擎剖析后会保留在 ElasticSearch 数据库中,以便反对实时地在线查问和剖析。舆情查问页设计如下: 舆情查问 舆情查问的次要场景:在限定上下文中,查问和某个关键词相干的舆情。限定上下文反对全属性(包含根底属性和分析属性);关键词也须要反对逻辑运算,通配符匹配等能力。 例如:查问用户反馈数据源、iphone端、负面情感的和『黑椒播放器』相干的舆情音讯。 趋势剖析 平台反对灵便的趋势剖析能力。在给定查问条件后,您能够查看数据的变化趋势,并指定不同的聚合粒度。此外,平台还提供一些趋势指标,如平均值、最小值、最大值、P80和P95等数据,以满足不同的剖析场景。 例如:在新建监控和报警时,心愿依据历史的舆情数据趋势和指标,制订正当的报警阈值。 聚合剖析 平台反对全属性的聚合剖析能力。在给定查问条件后,平台会计算所有『可聚合维度』的散布状况,给出每个维度的不同取值的音讯总数和占比。『可聚合维度』是依据以后搜寻的数据源动静辨认的,不同的数据源能够配置不同的聚合剖析维度。 例如:查问某个工夫范畴内的Top聚类问题,或者剖析和某个主题相干的所有舆情音讯的情感散布、App版本散布等。 监控和报警平台反对灵便的监控和报警策略。一条监控或报警规定包含3个局部: ...

February 21, 2024 · 1 min · jiezi

关于后端:Linux-网络编程从入门到进阶-学习指南

前言大家好,我是小康。在上一篇文章中,咱们探讨了 Linux 零碎编程的诸多根底构件,包含文件操作、过程治理和线程同步等,接下来,咱们将视线扩大到网络世界。在这个新篇章里,咱们要让利用跳出单机限度,学会在网络上跨机器交流信息。 接下来,咱们要深刻套接字(sockets)和 TCP/IP 协定,揭示如何在 Linux 下构建通信和网络服务。咱们会从根底说起,逐渐深刻。指标是为初学者提供一个 Linux 网络编程从入门到进阶的学习指南! 网络通信根底思考一下,如果计算机想要“交朋友”,它们须要怎么相互沟通?正如人们交换须要应用语言一样,计算机通信也必须恪守一套规定 — 这就是网络协议。 协定确保信息能够在不同的设施和平台之间清晰、精确地传递。要深刻了解协定,咱们首先要相熟两个根底的通信模型:OSI 和 TCP/IP 模型。 OSI 模型和 TCP/IP 模型在网络通信的世界里,OSI(开放式系统互联通信参考模型)和 TCP/IP(传输控制协议/网际协议)模型扮演着根底框架的角色。它们各自形容了网络通信的多个档次和阶段,但以不同的形式来分类和解决数据传输的细节。 OSI模型 OSI(Open Systems Interconnection)模型是一个概念性框架,用于形容网络中不同操作档次的性能。由七层组成,从物理硬件的电气信号(物理层),到应用层(如网页浏览器),每一层都有其独特的性能和协定。 TCP/IP模型 TCP/IP 模型,则更加贴近理论网络中的运作。Linux 的网络协议栈就是基于该模型实现的。它是基于四层架构,将网络通信过程简化并集中在协定族上,如传输控制协议(TCP)和互联网协议(IP),这两种协定是古代网络通信中最为外围的局部。 简略图示: 基本概念地址簿:IP地址和MAC地址设想一下,互联网是一个微小的数字城市,而每台计算机或网络设备就像是住在这个城市里的居民。 IP地址:数字世界的“家庭住址” 每台设施的 IP 地址就像是它在这个数字城市里的家庭住址。当计算机须要发送信息或拜访网络资源时,它会应用目的地设施的 IP 地址来确保信息正确地送达。这个地址有点像是咱们事实世界中的邮寄地址,能够依据网络环境的变动而变动(例如,当设施从家庭网络挪动到办公室网络时)。 MAC地址:网络中的“身份证” 而后,咱们有 MAC 地址,这是网络设备的另一个要害标识。每台设施的 MAC 地址都是举世无双的,相似于每个人的身份证号码。它是在设施制作时就被调配的,并且在大多数状况下,这个地址是固定不变的。MAC 地址在本地网络(如家庭或办公室网络)内起着重要作用,它帮忙确保信息被精确地送达到特定设施,就像邮递员须要晓得收件人的具体身份信息能力将包裹精确递交。 总结一下:ip 地址能够让数据包找到目标主机所在的网络,而 MAC 地址确保数据包能精确送到目标主机上。 导航路线:子网掩码和网关子网掩码:定位网络的“区域地图” 子网掩码能够被视为定位网络外部和内部地址的“区域地图”。就像在一个大城市中,你须要晓得哪些街道属于你的社区,哪些通往城市的其余局部。子网掩码帮忙计算机确定一个 IP 地址是属于本地网络(即同一个子网)还是位于内部网络。 外部导航:如果目的地IP地址与计算机所在的子网相匹配(依据子网掩码判断),则数据包在本地网络内传送。内部导航:如果目的地不在本地子网内,计算机晓得它须要将数据发送到更远的目的地。网关:网络间的“中转站” 网关在网络通信中表演中转站的角色。当你的数据包须要从一个网络(比方你的家庭网络)发送到另一个网络(比方你的工作地点的网络)时,网关是这个旅程的第一站。 路由决策:网关查看数据包的目标 IP 地址,而后应用它的路由表来决定最佳的门路将数据包发送到指标网络。总结: 子网掩码和网关独特合作,帮忙数据包在简单的网络结构中找到最无效的门路。子网掩码确定数据包是否在本地网络内,而网关领导跨网络的数据传输。 端口 :确保数据达到正确的“应用程序门牌号”好了,当初咱们的数据包曾经晓得了去哪里,但它如何确保被正确的程序接管呢?这就是端口退场的时候了。端口号就像是收件人的门牌号,确保数据不只是送到了正确的地址,而且被正确的应用程序接管。 Linux 套接字编程套接字是什么在网络编程中,套接字就像是网络世界的通信端口。每一个联网的应用程序,为了可能互发音讯,都会应用到这样一个端口。这个端口容许数据从一个程序流向另一个程序。简而言之,套接字是应用程序用来在网络上交换的桥梁。 设想一下,你要用手机给敌人发一条信息。你只须要晓得他们的手机号码,这样信息就能够间接发送到他们的手机上。在网络编程中,套接字的作用相似。它应用IP地址 (相似于手机号码) 来确定数据发送的指标地位,而端口号则像是确定信息应该送达到对方手机中的哪个应用程序。这样,套接字(应用 ip 地址和端口)确保了数据可能精确地发送给正在监听那个特定端口的程序。 套接字的工作原理: ...

February 21, 2024 · 15 min · jiezi

关于后端:国产操作系统概述

这是ren_dong的第30篇原创1、什么是操作系统?操作系统(Operating System,简称 OS)是连贯硬件和数据库、中间件、应用软件的纽带,自主可控生态构建的外围操作系统位于计算机硬件与应用软件之间,为用户程序提供一个更好、更简略、更清晰的计算机模型,并治理处理器、主存、硬盘、键盘、鼠标、显示器、打印机、输入输出设施等计算机硬件。操作系统次要由内核(运行于内核态,治理硬件资源)以及零碎调用(运行于用户态,为利用程序员写的应用程序提供零碎调用接口)两局部组成,其向下适配治理 CPU、GPU、存储等硬件设施,向上撑持应用软件的开发,提供运行环境。操作系统具备以下五个基本功能:内存治理、过程治理、设施治理、文件治理、提供用户接口CPU和操作系统是整个信创产业的根基,没有CPU和操作系统的平安可控,整个信创产业就是无根之木、无源之水 2、寰球现状Windows 和 Android 别离占据桌面和挪动端 OS 领导位置2.1、Windows & Android 目前寰球 PC 操作系统次要有 Windows、MacOS、Linux、UNIX 四种,挪动端操作系统次要有Android、iOS两种,其中微软 Windows 和谷歌 Android 别离占据各自畛域的领导位置,这也帮忙微软和谷歌成为计算产业的主导者。依据 Statcounter 数据,截至 2020 年 4 月,桌面操作系统中 Windows 寰球市占率 76.2%,中国市占率86.7%;挪动端操作系统中 Android 寰球市占率 70.7%,中国市占率 79.7% 2.2、LinuxLinux 收费开源,在服务器畛域有着重要的位置 Linux 是一套收费应用和自在流传的类 Unix 操作系统,是一个基于 POSIX 和 UNIX 的多用户、多任务、反对多线程和多 CPU 的操作系统。Linux 是由世界各地成千上万的程序员设计和开发实现的,当初开发 Linux 零碎的目标就是建设不受任何商业化软件版权制约的、全世界都能自在应用的类 Unix 操作系统兼容产品,因而 Linux 内核是收费且开源的,任何人都能够取得其代码并依据本人的需要进行批改。操作系统厂商以 Linux 内核为核心,再集成搭配各种各样的系统管理软件或利用工具软件组成一套残缺的操作系统,便称为 Linux 发行版。目前已知大概有 300 个 Linux 的发行版,国内上比拟出名的 Linux 操作系统有 Debian(衍生出桌面版的 Ubuntu、实用于浸透测试的 Kali)、RedHat(衍生出 CentOS、Fedora)、Gentoo、openSUSE 等,其中Debian 是社区化经营的产品,其衍生进去的 Ubuntu 是目前最受欢迎的收费操作系统;RedHat企业级 linux 发行版是免费的商业化产品,但基于其收费源代码重构的 CentOS收费。桌面端是 Linux 操作系统薄弱环节,但其在服务器、嵌入式畛域有着不错的市场份额,Spiceworks数据显示 2016 年 Linux 操作系统在服务器中市占率达到 12%,远高于其在桌面端的市场份额 ...

February 21, 2024 · 1 min · jiezi

关于后端:10个行锁死锁案例⭐️24张加锁分析图彻底搞懂Innodb行锁加锁规则

10个行锁、死锁案例⭐️24张加锁剖析图彻底搞懂Innodb行锁加锁规定!上篇文章 咱们形容原子性与隔离性的实现,其中形容读操作解决隔离性问题的计划时还遗留了一个问题:写操作是如何解决不同的隔离性问题? 本篇文章将会解决这个问题并形容MySQL中的锁、总结Innodb中行锁加锁规定、列举办锁、死锁案例剖析等 再浏览本篇文章前,至多要了解查问应用索引的流程、mvcc等常识(不了解的同学能够依据专栏程序进行浏览) MySQL锁的分类从锁的作用域上划分:全局锁、表锁、页锁、行锁全局锁:锁整个数据库实例,罕用数据备份,禁止全局写,只容许读表锁:锁表,对表进行加锁 元数据锁:表构造批改时表X锁:表独占锁表S锁:表共享锁页锁:位于表锁与行锁两头作用域的锁行锁(innodb特有):锁记录,其中蕴含独占锁(写锁,X锁)和共享锁(读锁,S锁)从性能上划分:意向锁、插入意向锁、自增长锁、乐观锁、乐观锁...意向锁:表锁,示意无意向往表中加锁,获取行锁前会加意向锁,当须要加表锁时,要通过意向锁判断表中是否有行锁 独占意向锁 IX:意向往表中加X锁,兼容IX、IS,不兼容X、S(表级别)共享意向锁 IS:意向往表中加S锁,兼容IX、IS、S,不兼容X(表级别)插入意向锁:隐式锁,意向往表中插入记录自增长锁:隐式锁,在并发场景下不确定插入数量会应用自增长锁加锁生成自增值,如果确定则应用互斥锁(间断模式)乐观锁:乐观锁能够用加行锁实现乐观锁:乐观锁能够用版本号判断实现这些锁有些是MySQL提供的,有些是存储引擎提供的,比方Innodb反对的行锁粒度小,并发性能高,不易抵触 但在某些场景上行锁还是会发生冲突(阻塞),因而咱们须要深刻把握行锁的加锁规定能力在遇到这种场景时剖析出问题 Innodb的行锁加锁规定后面说到行锁分为独占锁 X锁和共享锁 S锁,行锁除了会应用这种模型外,还会应用到一些其余的模型 锁模型record:记录锁,用于锁定某条记录 模型应用S/X (也就是独占锁、共享锁) gap:间隙锁,用于锁定某两条记录之间,禁止插入,用于避免幻读 模型应用GAP next key:临键锁,相当于记录锁 + 间隙锁 模型应用X/S,GAP 在lock mode中罕用X或S代表独占/共享的record,GAP则不分X或S 如果是独占的临键锁则是X、GAP,共享的临键锁则是S、GAP (这个lock mode前面案例时会用到,示意以后SQL被哪种锁模型阻塞) 不同隔离级别下的加锁加锁的目标就是为了可能满足事务隔离性从而达到数据的一致性 在不同隔离级别、应用不同类型SQL(增删改查)、走不同索引(主键和非主键、惟一和非惟一)、查问条件(等值查问、范畴查问)、MySQL版本 等诸多因素都会导致加锁的细节发生变化 因而只须要大抵把握加锁规定,并联合产生阻塞的记录排查出产生阻塞的问题,再进行优化、解决即可(本文基于5.7.X) 在RU(Read Uncommitted)下,读不加锁,写应用X record,因为写应用X record 则不会产生脏写,会产生脏读、不可反复读、幻读, 在RC(Read Committed)下,读应用mvcc(每次读生成read view),写应用X record,不会产生脏写、脏读,但会有不可反复读和幻读 在RR(Repeatable Read)下,读应用mvcc(第一次读生成read view),写应用X next key,不会产生脏写、脏读、不可反复读和大部分幻读,极其场景的幻读会产生 在S(Serializable)下,主动提交状况下读应用mvcc,手动提交下读应用S next key,写应用X next key,不会产生脏写、脏读、不可反复读、幻读 在罕用的隔离级别RC、RR中,读都是应用mvcc机制(不加锁)来进步并发性能的 锁定读的加锁在S串行化下,读会加S锁,那select如何加锁呢? S锁:select ... lock in share mode X锁:select ... for update 通常把加锁的select称为锁定读,而在一般的update和delete时,须要先进行读(找到记录)再操作,在这种状况下加锁规定也能够归为锁定读 update与delete是写操作,必定是加X锁的 (以下锁定读和新增的加锁规定是总结,搭配案例查看,一开始看不懂不要紧~) 锁定读加锁规定在RC及以下隔离级别,锁定读应用record锁;在RR及以上隔离级别,锁定读应用next key锁 (间隙锁的范畴是前开后闭,案例详细描述) ...

February 21, 2024 · 4 min · jiezi

关于后端:大厂的数据质量中心系统设计

日常工作中,数据开发上线完一个工作后并不是就能够居安思危,时常因上游链路数据异样或者本身解决逻辑的 BUG 导致产出的数据后果不可信。而问题发现可经验较长周期(尤其离线场景),往往是业务方通过下层数据报表发现数据异样后 push 数据方去定位问题(对于一个较冷的报表,这个周期可能会更长)。 因为数据加工链路较长,需借助数据血缘关系一一工作排查,也会导致问题定位难度增大,重大影响开发效率。如数据问题未及时发现,可能导致业务方作出谬误决策。此类问题可对立归属为大数据畛域数据品质问题。本文将向大家介绍伴鱼基础架构数据团队在应答该类问题时推出的平台化产品-数据品质核心的设计与实现。 1 调研业内数据品质平台化产品介绍不多,次要对两个开源产品和一个云平台产品进行调研。 1.1 Apache GriffinApache Griffin,eBay 开源基于 Apache Hadoop 和 Apache Spark 的数据品质服务平台。 1.1.1 架构图 数据品质平台的外围流程: Define:数据质检规定(指标)的定义Measure:数据质检工作的执行,基于 Spark 引擎实现Analyze:数据质检后果量化及可视化展现平台对数据质检规定进行了分类(业内广泛认可的数据品质的六大规范): Accuracy:准确性。如是否合乎表的加工逻辑Completeness:齐备性。如数据是否存在失落Timeliness:及时性。如表数据是否按时产生Uniqueness:唯一性。如主键字段是否惟一Validity:合规性。如字段长度是否合规、枚举值汇合是否合规Consistency:一致性。如表与表之间在某些字段上是否存在矛盾该我的项目仅在 Accuracy 类的规定上实现。Griffin是齐全闭环的平台化产品。质检工作执行依赖内置定时调度器的调度,调度执行工夫由用户在 UI 上设定。工作将通过 Apache Livy 组件提交至配置的 Spark 集群。即质检实时性难保,无奈强行阻断产出异样数据的工作,二者不是在同一调度平台被调度,时序也不能放弃串行。 1.2 QualitisQualitis,微众银行开源的一款数据品质管理系统。同样,它提供了一整套对立的流程来定义和检测数据集的品质并及时报告问题。从整个流程上看咱们仍然能够用 Define、Measure 和 Analyze 形容。它是基于其开源的另一款组件 Linkis 进行计算工作的代理散发,底层依赖 Spark 引擎,同时能够与其开源的 DataSphereStudio 工作开发平台无缝连接,也就实现了在工作执行的工作流中嵌入质检工作,满足质检时效性的要求。可见,Qualitis 需借助微众银行开源一系列产品才好用。 1.3 DataWorks 数据品质DataWorks,阿里云提供一站式大数据工场,包含数据品质在内的产品解决方案。实现依赖阿里云其余产品组件反对。DataWorks 数据品质局部的应用介绍从产品状态上给了咱们很大的帮忙,对咱们产品设计有指导性作用。 2 设计指标暂只反对离线局部数据品质治理反对通用规定形容和规定治理质检工作由公司外部对立的调度引擎调度执行,可反对对质检后果异样的工作进行强阻断。同时,尽量升高质检性能对调度引擎的代码侵入反对质检后果可视化3 零碎设计3.1 背景离线调度开发平台基于 Apache Dolphinscheduler(简称DS)实现,分布式去中心化,易扩大的可视化 DAG 调度零碎,反对包含 Shell、Python、Spark、Flink 等多种类型的 Task 工作,并具备很好的扩展性。 3.2 架构 Master 节点负责工作的监听和调度,Worker 节点则负责工作的执行。值得注意的是,每一个须要被调度的工作必然须要设置一个调度工夫的表达式(cron 表达式),由 Quartz 定时为工作生成待执行的 DAG Command,有且仅有一个 Master 节点取得执行权,主持该 DAG 各工作节点的调度执行。 ...

February 20, 2024 · 2 min · jiezi

关于后端:深入解析-Java-面向对象编程与类属性应用

Java 面向对象编程面向对象编程 (OOP) 是一种编程范式,它将程序组织成对象。对象蕴含数据和操作数据的办法。 OOP 的劣势: 更快、更易于执行提供清晰的构造代码更易于保护、批改和调试进步代码重用性缩小开发工夫类和对象 类 是对象的模板,它定义了对象的属性和办法。对象 是类的实例,它蕴含数据和操作数据的办法。示例: 类: 水果对象: 苹果、香蕉、芒果类: 汽车对象: 沃尔沃、奥迪、丰田对象创立 // 创立一个 `水果` 类的对象Fruit apple = new Fruit();// 创立一个 `汽车` 类的对象Car volvo = new Car();对象属性 // 设置 `apple` 对象的 `name` 属性`apple.name` = "苹果";// 获取 `volvo` 对象的 `color` 属性`String color` = `volvo.color`;对象办法 // 调用 `apple` 对象的 `eat()` 办法`apple.eat();`// 调用 `volvo` 对象的 `drive()` 办法`volvo.drive();`面向对象编程的其余重要概念: 继承封装多态学习面向对象编程 许多书籍、网站和在线教程能够帮忙你学习面向对象编程。通过练习,你将可能更好地了解面向对象编程并将其利用于你的编程我的项目中。Java 类和对象Java 是一种面向对象的编程语言,这意味着它围绕着类和对象构建。 类 是对象的蓝图,定义了对象的属性和办法。 对象 是类的实例,具备特定的属性值和办法实现。 创立类 应用 class 关键字创立类: ...

February 20, 2024 · 2 min · jiezi

关于后端:openai-chat-GPT4-Technical-Report-技术报告论文

摘要咱们报告了 GPT-4 的开发,这是一个大规模、多模态的模型,能够承受图像和文本输出,并生成文本输入。尽管在许多事实场景中不如人类,但 GPT-4 在各种业余和学术基准测试中体现出与人类程度相当的性能,包含在模仿的律师资格考试中获得了约前10%的考生得分。 GPT-4 是基于 Transformer 架构的模型,通过预训练以预测文档中的下一个标记。后训练对齐过程导致在事实性和合乎所需行为方面的性能失去改善。该项目标外围组成部分是开发基础设施和优化办法,这些办法在各种规模上都能可预测地运行。 这使咱们可能依据应用的计算资源不超过 GPT-4 1/1,000 的模型精确预测 GPT-4 的某些性能方面。 1. 介绍本技术报告介绍了 GPT-4,这是一个大型多模态模型,可能解决图像和文本输出,并生成文本输入。这类模型是钻研的重要畛域,因为它们有后劲在各种利用中应用,例如对话零碎、文本摘要和机器翻译。因而,近年来它们受到了宽泛关注和停顿(Brown 等,2020年;Hoffmann 等,2022年;Chowdhery 等,2022年;Rae 等,2021年;Dai 等,2019年;Liu 等,2019年;Devlin 等,2018年;Raffel 等,2019年;Shazeer 和 Stern,2018年;Ba 等,2016年;Wei 等,2022a年;Huang 等,2022年;Kojima 等,2022年;Kaplan 等,2020年;Henighan 等,2020年;Yang 等,2022年;Shazeer 等,2017年;Zoph 等,2022年;Wei 等,2022b年;Dehghani 等,2019年;Su 等,2021年;Alayrac 等;Chen 等,2022a年;Wang 和 Komatsuzaki,2021年;Black 等,2021年;Scao 等,2022年;Zhang 等,2022年;Touvron 等,2023年;Radford 等,2017年;Lample 和 Conneau,2019年;Dao 等,2022年;Child 等,2019年;Rabe 和 Staats,2021年;Gray 等,2017年)。 开发这类模型的次要指标之一是进步它们了解和生成自然语言文本的能力,特地是在更简单和奥妙的情景中。为了测试其在这种情景下的能力,GPT-4 在多个本来设计用于人类的考试上进行了评估。在这些评估中,它体现相当杰出,并常常超过绝大多数人类考生。例如,在模仿的律师资格考试中,GPT-4 取得了高达前10%的考生得分。这与 GPT-3.5 相比造成了鲜明对比,后者在前10%考生中得分偏低。 在一系列传统的自然语言解决基准测试中,GPT-4 的体现超过了先前的大型语言模型和大多数最先进的零碎(这些零碎通常具备特定基准测试的训练或手工工程)。在 MMLU 基准测试(Hendrycks 等,2021a, b)上,这是一个涵盖了57个科目的英语多项选择题套件,在英语方面,GPT-4 不仅在现有模型中大幅当先,还在其余语言上表现出色。在 MMLU 的翻译变体中,GPT-4 在思考的26种语言中有24种超过了英语的最新程度。咱们将在前面的章节中更具体地探讨这些模型能力后果以及模型安全性改良和后果。 ...

February 20, 2024 · 3 min · jiezi

关于后端:openai-chatGPT-原理通俗介绍

引言近年来,随着深度学习技术的一直倒退,自然语言解决(NLP)畛域获得了长足的提高。ChatGPT(Generative Pre-trained Transformer)作为一种先进的语言生成模型,在各类对话零碎和智能助手中失去了广泛应用。 然而,只管这些模型在生成文本方面表现出色,但如何保障生成的文本在逻辑上正当依然是一个挑战。 本文将探讨在 ChatGPT 中如何实现逻辑,并探讨自然语言中逻辑的了解形式。 Q: 介绍一下 chatGPT 的实现原理,通俗易懂。当咱们议论 ChatGPT 时,咱们实际上在探讨一个基于人工智能的对话零碎,其核心技术是基于深度学习。 ChatGPT 的实现原理能够概括为以下几个步骤: 数据收集与预处理:ChatGPT 的训练须要大量的对话数据。这些数据能够是来自于网络上的公开对话记录,也能够是特定畛域的对话语料库。数据预处理包含荡涤数据、分词、去除噪声等,以便模型更好地了解和学习。模型架构:ChatGPT 应用了一种称为 Transformer 的神经网络架构。Transformer 是一种极其弱小的模型,用于解决序列到序列的工作,如自然语言解决。它由编码器(Encoder)和解码器(Decoder)组成。ChatGPT 应用了解码器构造,因为它的工作是生成自然语言文本。自监督学习:ChatGPT 是通过自监督学习进行训练的。这意味着它并不需要人工标注的数据,而是从原始的对话数据中主动学习。具体来说,ChatGPT 应用了一种被称为 Masked Language Modeling(MLM)的技术。在 MLM 中,模型被要求预测在输出序列中被遮蔽的局部。通过这种形式,模型被迫了解文本的上下文,并学会生成正当的回复。微调与调参:在大规模的预训练之后,ChatGPT 可能会通过一些微调和调参来适应特定的利用场景或工作。这包含对模型的超参数进行调整,如学习率、批量大小等,以及在特定数据集上进行一些额定的训练。推理与生成:一旦训练实现,ChatGPT 就能够用于对话生成了。给定一个输出文本,模型会依据其外部学到的常识和语言模式生成一个正当的回复。这个过程通常波及到束搜寻(beam search)等技术,用于在生成过程中抉择最合适的文本。总的来说,ChatGPT 的实现原理是基于大规模数据的预训练,并通过深度学习模型来了解和生成自然语言文本。 它的弱小之处在于其可能主动学习语言的法则和上下文,并生成精确、连贯的回复。 Q: 介绍一下 Transformer 神经网络,通俗易懂Transformer 是一种被宽泛用于解决自然语言解决(NLP)工作的神经网络架构。 它的设计革命性地扭转了解决序列数据的形式,特地是在翻译、文本生成和语言了解等工作上获得了巨大成功。 艰深地说,Transformer 就像是一个可能了解长篇文章或对话的超级智能大脑。 它具备两个次要局部:编码器(Encoder)和解码器(Decoder)。 编码器:编码器的作用就像是一个了解输出文本的专家。它将输出文本中的每个词或标记转换成一种称为"向量"的模式,这些向量蕴含了该词在语义空间中的示意。编码器不仅能够了解每个词的意义,还能捕捉到词与词之间的关系,从而造成对整个输出文本的了解。解码器:解码器的作用则是依据编码器生成的语义信息,逐渐生成指标文本。在翻译工作中,解码器会依据源语言句子的编码信息,逐渐生成目标语言的句子。在生成文本工作中,解码器会依据后面生成的局部文本和输出文本的编码信息,逐渐生成后续的文本内容。Transformer 之所以如此弱小,有几个要害的设计特点: 自注意力机制(Self-Attention):这是 Transformer 最外围的局部之一。自注意力机制容许模型在解决每个词时,将注意力集中在输出序列的不同局部,以便更好地了解上下文信息。这样一来,模型不仅可能思考到每个词的语义,还能同时思考到它与其余词的关系,大大晋升了对长距离依赖的解决能力。多头注意力机制(Multi-Head Attention):为了进一步晋升模型的表达能力,Transformer 中的自注意力机制被扩大成多个并行的注意力头。每个头都能够学习不同的注意力权重,从而提供更加丰盛和多样的语义示意。地位编码(Positional Encoding):因为 Transformer 并没有像循环神经网络(RNN)那样显式地保留序列的程序信息,因而须要额定的地位编码来示意词的地位信息。地位编码被加到输出词向量中,以便模型可能辨别不同地位的词。总的来说,Transformer 的胜利在于它弱小的表达能力、可能解决长距离依赖关系以及并行计算的能力,使其成为自然语言解决畛域的一个重要里程碑。 Q: 介绍一下 自监督学习,通俗易懂自监督学习是一种机器学习的办法,它不依赖于人工标注的数据,而是利用数据自身的外在构造和特色来进行学习。 艰深地说,就如同是让机器通过观察本人身边的世界来学习,而不须要人类提供标签或者领导。这种学习办法能够比喻成让机器本人从数据中发现法则,就像是解谜游戏一样,它会尝试从数据中找到模式、法则或者暗藏在其中的信息。 自监督学习的过程能够简略分为以下几个步骤: 数据筹备:首先,咱们须要一个蕴含大量数据的数据集。这些数据能够是图像、文本、音频或者其余模式的数据。设计工作:在自监督学习中,咱们须要设计一个本人解决的工作,这个工作通常是从数据中删除一些信息,而后要求模型来预测被删除的信息。这个过程被称为自监督工作。比方,在图像数据中,能够随机遮挡一部分图像,而后要求模型来预测被遮挡的局部是什么。模型训练:接下来,咱们应用这些带有隐式标签的数据来训练模型。模型会通过一直地尝试预测被暗藏的信息来逐步学习数据中的模式和法则。训练过程通常应用深度学习模型,比方神经网络。模型评估:最初,咱们会对训练好的模型进行评估,看它在预测被暗藏信息的准确度如何。这能够通过在一些保留数据上进行测试来实现。总的来说,自监督学习是一种弱小的学习办法,它可能让机器从未标记的数据中学习到有用的信息和模式,而无需人工干预。这种学习形式的劣势在于它能够充分利用现有的大规模数据,同时也为解决一些不足标注数据的工作提供了一种无效的解决方案。 Q: 艰深介绍一下 Masked Language Modeling(MLM)的技术Masked Language Modeling(MLM)是一种自监督学习技术,罕用于训练自然语言解决模型,特地是像BERT(Bidirectional Encoder Representations from Transformers)这样的模型。 ...

February 20, 2024 · 1 min · jiezi

关于后端:Linux-系统编程从入门到进阶-学习指南

引言大家好,我是小康 ,明天咱们来学习一下 Linux 零碎编程相干的常识。Linux 零碎编程是连贯高级语言和硬件的桥梁,它对深刻了解计算机系统至关重要。无论你是打算构建高性能服务器还是开发嵌入式设施,把握 Linux 零碎编程是 C 和 C++ 开发者的基本技能。 本文旨在为初学者提供一个清晰的 Linux 零碎编程入门指南,带你步入 Linux 零碎编程的世界,从基本概念到实用技能,一步步建设起您的常识体系。 基本概念什么是零碎编程? 零碎编程,指的是开发那些间接与计算机硬件或操作系统进行交互的程序。这些程序负责管理和管制计算机系统的资源,包含但不限于过程、内存、文件系统和设施驱动。确保为应用程序提供一个稳固、高效的运行环境。 零碎编程与利用编程的次要区别: 目的性:零碎编程旨在为计算机或操作系统自身提供性能和服务,而利用编程是为了满足最终用户的特定需要。交互对象:零碎编程间接与硬件或操作系统交互,而利用编程与操作系统或其余利用交互。复杂性:因为零碎编程须要治理和管制计算机的底层资源,因而通常比利用编程更为简单。开发工具:零碎编程通常应用低级语言,如 C 或汇编,因为这些语言提供了间接拜访硬件的能力。而利用编程可能应用更高级的语言,如 Python 或 Java,以进步开发效率。Linux零碎编程核心技术概览在电脑的世界中,操作系统起到桥梁的作用,连贯用户与计算机硬件。其中,Linux 因为其开源、稳固和平安的特点,成为了许多工程师的首选。为了更深刻地了解它,咱们首先须要理解其零碎架构的神秘面纱。 Linux 零碎架构解析用户空间和内核空间的布局 各个内核组件阐明: 零碎调用 (Syscalls): 当应用程序须要拜访硬件资源时,它们应用零碎调用来与内核通信。 过程治理: 负责解决过程创立、调度和终止。确保零碎中的过程偏心、无效地取得 CPU 工夫,并治理过程间的通信和同步。 内存治理: 治理物理内存,提供虚拟内存和分页性能。确保每个过程都有它本人的地址空间,同时爱护过程间的内存不被非法拜访。 文件系统: 提供文件和目录的创立、读取、写入和删除性能。它形象了物理存储设备,为用户和应用程序提供了一个对立的文件拜访接口。 虚构文件系统(VFS): 用户和应用程序不间接与各种文件系统交互。而是通过 VFS(虚构文件系统)进行操作。VFS为各种不同的文件系统(如EXT4, FAT, NFS等)提供一个对立的接口。这样,无论底层应用的是哪种文件系统,用户和利用的文件拜访形式都保持一致,实现在 Linux 中的无缝集成。 网络协议栈: 负责解决计算机之间的通信,使设施可能在网络上发送和接收数据。它蕴含了多层协定,如 TCP/IP,使计算机可能连贯到互联网和其余网络,并与其余计算机进行数据交换。 设施驱动: 设施驱动是一种非凡的软件程序,它容许 Linux 内核和计算机的硬件组件进行交互。这些硬件组件能够是任何物理设施,如显卡、声卡、网络适配器、硬盘或其余输出/输出设备。设施驱动为硬件设施提供了一个形象层,使得内核和应用程序不须要晓得硬件的具体细节,就能与其进行通信和管制。简而言之,设施驱动是硬件和操作系统之间通信的桥梁。 用户空间 (User Space)所有的应用程序,如浏览器、文档编辑器或音乐播放器都运行在这个空间。 安全性:用户空间的程序运行在受限的环境中,它们只能拜访调配给它们的资源,不能间接拜访硬件或其余程序的数据。稳定性:如果一个应用程序解体,它不会影响其余应用程序或零碎的外围性能。内核空间 (Kernel Space)内核空间是操作系统的外围。 权限:内核能够间接拜访硬件,并有权执行任何命令。安全性:尽管内核领有宽泛的权限,但只有那些已知且通过严格测试和验证的代码才被容许在内核空间执行。稳定性:如果内核遇到问题,整个零碎可能会解体。零碎调用与库函数在 Linux 编程中,咱们常常听到“零碎调用”和“库函数”这两个词,但你晓得它们之间的区别吗?接下来就让咱们来具体理解一下。 什么是零碎调用?零碎调用是一个程序向操作系统收回的申请。当应用程序须要拜访某些资源(如磁盘、网络或其余硬件设施)或执行某些特定的操作(如创立过程或线程)时,它通常会通过零碎调用来实现。 工作原理 模式切换:应用程序在用户空间运行,而操作系统内核在内核空间运行。零碎调用波及从用户空间切换到内核空间。参数传递:程序将参数传递给零碎调用,通常通过特定的寄存器。执行:内核依据传递的参数执行相应的操作。返回后果:操作实现后,内核将后果返回给应用程序,并将控制权返回给应用程序。常见的零碎调用函数: read() 和 write():别离用于读取和写入文件。open() 和 close():关上和敞开文件。fork():创立一个新的过程。wait():期待过程完结。exec():执行一个新程序。这只是零碎调用的冰山一角。Linux 提供了上百个零碎调用,每个都有其特定的性能。 ...

February 20, 2024 · 12 min · jiezi

关于后端:spark为什么比mapreduce快

spark为什么比mapreduce快? 首先廓清几个误区:1:两者都是基于内存计算的,任何计算框架都必定是基于内存的,所以网上说的spark是基于内存计算所以快,显然是谬误的 2;DAG计算模型缩小的是磁盘I/O次数(相比于mapreduce计算模型而言),而不是shuffle次数,因为shuffle是依据数据重组的次数而定,所以shuffle次数不能缩小 所以总结spark比mapreduce快的起因有以下几点:1:DAG相比hadoop的mapreduce在大多数状况下能够缩小磁盘I/O次数因为mapreduce计算模型只能蕴含一个map和一个reduce,所以reduce完后必须进行落盘,而DAG能够间断shuffle的,也就是说一个DAG能够实现好几个 mapreduce,所以dag只须要在最初一个shuffle落盘,就比mapreduce少了,总shuffle次数越多,缩小的落盘次数就越多 2:spark shuffle 的优化mapreduce在shuffle时默认进行排序,spark在shuffle时则只有局部场景才须要排序(bypass技师不须要排序),排序是十分耗时的,这样就能够放慢shuffle速度 3:spark反对将须要重复用到的数据进行缓存所以对于下次再次应用此rdd时,不再再次计算,而是间接从缓存中获取,因而能够缩小数据加载耗时,所以更适宜须要迭代计算的机器学习算法 4:工作级别并行度上的不同mapreduce采纳多过程模型,而spark采纳了多线程模型,多过程模型的益处是便于细粒度管制每个工作占用的资源,但每次工作的启动都会耗费肯定的启动工夫,即mapreduce的map task 和reduce task是过程级别的,都是jvm过程,每次启动都须要从新申请资源,耗费不必要的工夫,而spark task是基于线程模型的,通过复用线程池中的线程来缩小启动,敞开task所须要的开销(多线程模型也有毛病,因为同节点上所有工作运行在一个进行中,因而,会呈现重大的资源争用,难以细粒度管制每个工作占用资源) 作者:京东批发 吴化斌 起源:京东云开发者社区 转载请注明起源

February 20, 2024 · 1 min · jiezi

关于后端:技术专栏丨Rust-语言简介及其在-Fabarta-技术栈中的应用

导读:Rust 是一门重视性能和平安的零碎编程语言,通过其独特的所有权零碎、借用零碎和类型零碎,胜利地解决了传统零碎编程中的许多难题。其开发者敌对的语法、丰盛的规范库和弱小的社区反对,使得 Rust 成为当今编程畛域中备受关注的语言之一。01 引言Rust 曾经不算是一门年老的语言了,其诞生工夫跟 Go 语言差不多。2006 年 Rust 作为 Graydon Hoare 的集体我的项目呈现,2007 年 Google 开始设计 Go。但很显著,Go 的倒退要好得多。Rust 在 2015 年才公布了 1.0 版本,而 Go 在 2016 年曾经成为了 TIOBE 的年度语言。相较而言 Rust 的倒退和前景仿佛不怎么好,但其实这与 Rust 语言的定位有十分大的关系。Rust 最后是作为一种在零碎编程畛域里代替 C/C++ 而呈现的语言,其倒退天然要迟缓许多。因为在零碎编程畛域,每走一步都要求十分扎实。 我对 Rust 印象比拟粗浅的有两件事件:首先是看到一篇文章称其学习曲线十分平缓,过后就比拟好奇一门语言能够难到什么水平。其次则是因为 Linus Torvalds 决定在 Linux Kernel 里增加对 Rust 的反对。Linus 以严苛闻名,能受到 Linus 的青眼相对不是一件容易的事件,这阐明 Rust 这门语言必然有独到之处。 最近几年,微软、AWS 等大型商业公司逐步开始应用 Rust 来编写或重写重要零碎。开源界很多器重平安因素的组件,如 sudo/su 也在应用 Rust 进行重写。Rust 除了在零碎编程畛域变得流行起来,也是 WASM 畛域里的举荐语言。这一方面阐明 Rust 语言曾经逐渐成熟,另一方面也阐明了 Rust 有十分强的体现能力,在各个领域都能胜任。所以 Fabarta 在开发多模态智能引擎 ArcNerual 时,通过多方面的衡量后抉择了 Rust 语言。 ...

February 20, 2024 · 4 min · jiezi

关于后端:等级保护是什么为什么要做等级保护

一、 什么是等级爱护: 等级爱护是一种信息安全治理办法,用于对不同级别的信息和信息系统进行分类、评估和爱护。它波及将信息系统和信息依照其重要性和敏感性分级别,而后依据等级要求施行相应的安全措施,以确保信息的保密性、完整性和可用性。等级爱护通常包含信息系统的定级、备案、平安建设、测评和监督等阶段,以确保信息系统达到特定的平安规范和法规要求。 随着信息化技术的飞速发展,信息系统曾经成为企业和政府机构日常经营中不可或缺的一部分。然而,网络安全问题也日益凸显,如黑客攻击、病毒传播等,给集体和企业带来了微小的经济损失和隐衷泄露危险,信息系统的平安问题曾经成为社会各界关注的焦点。为了应答这一挑战,中国政府出台了信息安全等级爱护政策,要求对不同等级的信息系统进行等保测评,以确保其平安性能达到国家标准。通过对不同等级的信息系统进行爱护,能够为信息基础设施提供更加牢靠的平安保障,确保网络安全和社会稳固 二、 为什么须要发展等级爱护工作: 信息安全保障:等级爱护工作有助于确保信息系统中存储、解决和传输的信息受到适当的爱护,避免信息泄露、损坏和未经受权拜访。风险管理:通过对信息系统进行定级和评估,能够帮忙组织辨认和治理潜在的平安危险,采取措施升高危险。法律法规要求:法律法规要求组织对敏感信息进行等级爱护,以确保合规性。信赖建设:通过取得等级认证,组织能够向合作伙伴、客户和利益相关者展现其对信息安全的承诺,加强信赖关系。技术改良:等级爱护工作能够帮忙组织辨认信息系统中的弱点和破绽,从而有针对性地进行技术改良和降级。劫难复原和业务连续性:等级爱护工作包含劫难复原打算,有助于组织在紧急情况下迅速复原业务。三,等级爱护工作具体蕴含的内容: 信息系统定级:将信息系统依照其重要性和敏感性分级,通常分为不同的安全等级,以确定实用的平安规范和要求。信息系统备案:用户单位须要将其信息系统的定级信息备案报送给相干政府部门,以建设信息系统的治理档案。平安建设:依据信息系统的等级要求,进行平安建设,包含访问控制、数据加密、网络防护等措施的施行。等级测评:委托第三方机构进行等级测评,评估信息系统的安全性,并出具测评报告。平安监督和查看:主管单位对信息系统进行定期的监督和查看,确保零碎继续合乎平安规范和法规要求。法律法规恪守:确保信息系统的等级爱护工作符合国家和中央的法律法规,包含隐衷法、网络安全法等。安全意识培训:发展员工的信息安全培训和意识教育,进步员工对信息安全的意识和警惕性。安全漏洞修复:及时修复信息系统中发现的安全漏洞和问题,确保零碎的稳定性和安全性。劫难复原和业务连续性:制订劫难复原打算,确保在紧急情况下可能迅速复原业务。等级爱护工作是为了确保信息系统的安全性、合规性和可用性而进行的一系列治理和技术措施,涵盖了信息系统的定级、备案、平安建设、测评和监督等方面。这些工作有助于爱护信息资产,升高危险,合乎法规要求,并建设信赖关系。

February 20, 2024 · 1 min · jiezi

关于后端:深入浅出JVM一之Hotspot虚拟机中的对象

本篇文章思维导图 对象的创立对象的创立能够分为五个步骤:查看类加载,分配内存,初始化零值,设置对象头,执行实例结构器<init> 类加载查看HotSpot虚拟机遇到一条new指令,会先查看是否在常量池中定位到这个类的符号援用,查看这个类是否类加载过 没有类加载过就去类加载类加载过就进行下一步分配内存分配内存对象所需的内存在类加载实现后就能够齐全确定 分配内存形式虚拟机在堆上为新对象分配内存,有两种内存调配的形式:指针碰撞,闲暇列表 指针碰撞 应用场景: 堆内存规整参差过程: 应用过的空间放在一边,闲暇的空间放在另一边,两头有一个指针作为分界点指示器,把新生对象放在应用过空间的那一边,两头指针向闲暇空间那边移动一个新生对象的内存大小的间隔即可 特点:简略,高效,因为要堆内存规整参差,所以垃圾收集器应该要有压缩整顿的能力 闲暇列表 应用场景: 已应用空间和闲暇空间交织在一起过程: 虚拟机保护一个列表,列表中记录了哪些内存空间可用,调配时找一块足够大的内存空间划分给新生对象,而后更新列表特点: 比指针碰撞简单, 然而对垃圾收集器能够不必压缩整顿的能力分配内存流程分配内存流程(栈--老年代--TLAB--Eden)因为在堆上为对象分配内存,内存不足会引起GC,引起GC可能会有STW(Stop The World)影响响应 为了优化缩小GC,当对象不会产生逃逸(作用域只在办法中,不会被外界调用)且栈内存足够时,间接在栈上为对象分配内存,当线程完结后,栈空间被回收,(局部变量也被回收)就不必进行垃圾回收了 开启逃逸剖析-XX:+DoEscapeAnalysis满足条件的对象就在栈上分配内存 (当对象满足不会逃逸条件除了可能优化在栈上分配内存还会带来锁打消,标量替换等优化...) 尝试该对象能不能在栈上分配内存如果不合乎1,且该对象特地的大,比方内存超过了JVM设置的大对象的值就间接在老年代上为它分配内存如果这个对象不大,为了解决并发分配内存,采纳TLAB 本地线程调配缓冲TLAB 本地线程调配缓存堆内存是线程共享的,并发状况下从堆中划分线程内存不平安,如果间接加锁会影响并发性能 为每个线程在Eden区调配小小一块属于线程的内存,相似缓冲区 哪个线程要分配内存就在那个线程的缓冲区上调配,只有缓冲区满了,不够了才应用乐观的同步策略(CAS+失败重试)保障分配内存的原子性 在并发状况下分配内存是不平安的(正在给A对象分配内存,指针还未修改,应用原来的指针为对象B分配内存),虚拟机采纳TLAB(Thread Local Allocation Buffer本地线程调配缓冲)和CAS+失败重试来保障线程平安 TLAB:为每一个线程事后在伊甸园区(Eden)调配一块内存,JVM给线程中的对象分配内存时先在TLAB调配,直到对象大于TLAB中残余的内存或TLAB内存已用尽时才须要同步锁定(也就是CAS+失败重试)CAS+失败重试:采纳CAS配上失败重试的形式保障更新操作的原子性初始化零值分配内存实现后,虚拟机将调配的内存空间初始化为零值(不包含对象头) (零值: int对应0等) 保障了对象的成员字段(成员变量)在Java代码中不赋初始值就能够应用 设置对象头把一些信息(这个对象属于哪个类? 对象哈希码,对象GC分代年龄)寄存在对象头中 (前面具体阐明对象头) 执行init办法init办法 = 实例变量赋值 + 实例代码块 + 实例结构器 依照咱们本人的志愿进行初始化 对象的内存布局对象内存信息对象在堆中的内存布局能够分为三个局部:对象头,实例数据,对齐填充 对象头包含两类信息(8Byte + 4Byte) Mark Word:用于存储该对象本身运行时数据(该对象的哈希码信息,GC信息:分代年龄,锁信息:状态标记等)类型指针(对象指向它类型元数据的指针):HotSpot通过类型指针确定该对象是哪个类的实例 (如果该对象是数组,对象头中还必须记录数组的长度)类型指针默认是压缩指针,内存超过32G时为了寻址就不能采纳压缩指针了 实例数据是对象真正存储的无效信息 记录从父类中继承的字段和该类中定义的字段父类的字段会呈现在子类字段之前,默认子类较小的字段能够插入父类字段间的空隙以此来节约空间(+XX:CompactFields)对齐填充 HotSpot要求对象起始地址必须是8字节整倍数 所以任何对象的大小都必须是8字节的整倍,如果对象实例数据局部未达到8字节就会通过对齐填充进行补全 剖析对象占用字节Object obj = new Object(); 占多少字节?导入JOL依赖  <!-- https://mvnrepository.com/artifact/org.openjdk.jol/jol-core -->         <dependency>             <groupId>org.openjdk.jol</groupId>             <artifactId>jol-core</artifactId>             <version>0.12</version>         </dependency>mark word : 8 byte ...

February 20, 2024 · 1 min · jiezi

关于后端:新的一年开工大吉

大家好,我是小悟 新的一年,新的征程,咱们站在了一个全新的终点上。动工大吉,这是一个充满希望和时机的时刻。让咱们一起迎接新的挑战,发明更加美妙的将来。 在这个新的终点上,咱们要明确咱们的指标。咱们要设定清晰、具体、可实现的指标,并为之努力奋斗。只有这样,咱们能力在工作中放弃能源和激情,一直向前迈进。 在新的一年中,咱们须要承当更多的责任和工作。只有这样,咱们才可能在新的一年中获得更好的问题,为公司和社会做出更大的奉献。 在过来的一年中,咱们失去了很多人的帮忙和反对,才可能在工作中获得肯定的问题。咱们须要用本人的实际行动来回报那些已经帮忙过咱们的人。 同时,咱们也要重视团队单干。在工作中,咱们须要相互支持、互相帮忙,独特面对挑战。只有团结一心,咱们能力战败艰难,获得更大的成就。 此外,咱们还要一直学习和提高。在疾速倒退的时代,咱们必须不断更新本人的常识和技能,能力跟上时代的步调。只有一直学习,咱们能力一直晋升本人的能力和价值,为公司的倒退奉献更多的力量。 最初,咱们要放弃踊跃的心态。在工作中,咱们难免会遇到挫折和艰难,但咱们要放弃乐观的心态,踊跃面对挑战。只有放弃踊跃的心态,咱们能力一直成长和提高,获得更好的问题。 动工大吉,这是一个新的开始。让咱们一起致力,独特发明更加美妙的将来! 您的一键三连,是我更新的最大能源,谢谢 山水有相逢,来日皆可期,谢谢浏览,咱们再会 我手中的金箍棒,上能通天,下能探海

February 20, 2024 · 1 min · jiezi

关于后端:活动回顾|RocketMQ-运维经验圆桌交流第二期

2023年12月3日,AutoMQ 举办了第二场线上交流会 RocketMQ 运维教训圆桌交换「第二期」,本次交流会汇聚了 RocketMQ 的作者以及来自腾讯云、网易、社区的技术专家。在这个充斥交换激情的流动中, 大家独特探讨了 RocketMQ 的运维教训,分享了贵重的见解。接下来让咱们一起回顾此次 RocketMQ 运维学习之旅! 从用户沉积问题看RocketMQ可观测的实现 腾讯云 RocketMQ 技术专家李伟老师分享了在解决沉积问题时的教训分析方法,包含依据教训疾速定位问题、利用监控指标进行剖析、巡检链路的建设等。他还总结了将运维教训积淀下来的办法,包含集体记录、标准化操作文档、工具化和页面白屏化的倒退。最初,他简要介绍了RocketMQ 5 的可观测指标实现形式,并领导大家如何查找和了解这些指标。 RocketMQ 运维稳定性与可观测性关联剖析 网易云消息中间件研发负责人林德智老师分享了在工作中遇到的 RocketMQ 相干问题和解决办法。重点包含生产常见问题的一些定位,解析了生产失败、生产提早、生产耗时长等状况。他介绍了通过精准采样和音讯轨迹解决难题的办法,探讨了扩缩容导致生产负载不平衡的状况并一一给出解法,强调了正当设置 queue 数量的重要性。 学习 RocketMQ 的精华:知行合一 架构师张勇老师分享了他学习 RocketMQ 四个阶段的经验。第一阶段,RocketMQ 刚开源,他就用它推动重构了同程艺龙的优惠券计算服务,大大优化计算工夫。第二阶段,他本人写了两个轮子,包含分库分表组件和 RPC 框架。第三阶段,他开始在生产环境中实战利用 RocketMQ ,介绍了电商直播答题和自研任务调度零碎两个场景的利用教训。第四阶段,他将 RocketMQ 常识体系串联并输入成文章,同时他从书籍、公众号、大厂实战文章等很多渠道去学习。最初他总结道,学习任何一门技术,都应该做到知行合一,强调实践学习和入手实际的重要性。 RocketMQ 部署、利用、诊断 AutoMQ 联结创始人 & CTO 周新宇老师围绕“如何运上部署高可用的 RocketMQ 集群”“PushConsumer 最佳实际是什么”“用户说音讯未生产怎么排查”三个议题,给大家深刻解说了 RocketMQ 部署、应用、诊断三个方面,并提出了以下重点倡议: 在云上部署高可用集群,举荐应用 GitOps 的配置管理计划,比方将配置文件放在 GitHub 上进行治理。 在部署时拆分小集群,通过小集群分级管理业务,以管制故障半径。 在故障产生时,疾速止血是第一优先级,应用 RocketMQ 的管理工具进行疾速的禁读禁写,以隔离故障。 在 PushConsumer 的利用中,要留神防止误用生产重试的能力,防止将任何谬误都进行重投,尤其是限流谬误,倡议阻塞并在服务端沉积音讯。 在诊断音讯未生产问题时,须要多路径进行排查,包含查看生产轨迹、音讯状态、投递条件、定时音讯等,留神客户端配置和历史变更。 RocketMQ Copilot 自助诊断性能 Apache RocketMQ PMC Member 艾阳坤老师演示了 RocketMQ Copilot 产品的针对于音讯沉积的自助诊断的过程。在周新宇老师提到的音讯未生产问题上,他也应用 RocketMQ Copilot 产品的自助诊断性能进行了演示,只须要填入 Topic,ConsumerGroup 和 MessageId 等信息,RocketMQ Copilot 就能够依据这些元数据和线上信息还原现场,依据音讯未生产的常识图谱顺次排查,并最终定位出问题的根因。 ...

February 20, 2024 · 1 min · jiezi

关于后端:架构师蓝图-理解软件风格与模式

本文介绍了10种软件架构格调及其对应设计模式,梳理了各个格调的优缺点和实用场景,帮忙读者在架构选项过程中能对症下药,做出更适宜业务场景的架构设计。原文: The Architect’s Blueprint: Understanding Software Styles and Patterns with Cheatsheet在软件开发过程中,架构在塑造软件系统的构造和行为方面起着至关重要的作用。架构为零碎设计提供蓝图,具体阐明组件如何互相交互以交付特定性能。然而,因为有大量可用的体系架构格调和模式,分别哪种办法最适宜特定的我的项目或零碎可能须要付出大量工夫。本文旨在说明相干概念,帮忙读者在架构工作中做出理智决策。 架构格调(Architectural Styles) vs 架构模式(Architectural Patterns)在深入研究细节之前,很重要的一点是要辨别架构格调和模式,这些术语通常能够调换应用,但具备不同的含意。 架构格调是为一系列零碎提供形象框架的高级策略。架构格调通过常常解决反复呈现的问题来改良模块划分并促成设计重用。能够把它设想成领导修建或住宅设计的主题或美学,具体实例包含分层(Layered)、事件驱动(Event-Driven)和微服务(Microservices)等。 另一方面,架构模式要更加具体,并且特定于零碎中的特定问题或模块,为体系架构问题提供了结构化解决方案,具体阐明了应该如何为特定性能构建组件和交互。架构模式相似于软件设计模式,然而工作在更高的抽象层次上。具体实例包含模型-视图-控制器(MVC,Model-View-Controller)、公布-订阅(Publish-Subscribe)和无服务器(Serverless)等。 尽管架构格调提供了宽泛框架,能够看作是零碎设计的个别哲学,但架构模式是该框架中特定设计问题的具体解决方案。换句话说,架构格调形容了零碎的总体构造,而架构模式解决了可能在该构造中呈现的特定设计问题。 上面咱们将探讨十种要害的架构格调,每种格调都有其各自的模式、准则、优缺点和利用范畴。这些格调包含分层(Layered)、基于组件(Component-Based)、面向服务(Service-Oriented)、分布式系统(Distributed System)、畛域驱动(Domain-Driven)、事件驱动(Event-Driven)、关注点拆散(Separation of Concern)、解释器(Interpreter)、并发(Concurrency)和以数据为核心(Data-Centric)。通过了解这些格调和模式,能够更好驾驭全局性体系架构,并设计出强壮、可伸缩和可保护的零碎。让咱们开始吧! "在软件设计的雄伟图景中,格调是粗线条的轮廓,而模式是将杰作带入生存的简单细节。"终极备忘录为了帮忙读者浏览架构格调和模式的广大景观,我创立了一个备忘录,蕴含了本文探讨的所有关键点。这个备忘录能够作为不便的参考指南,帮忙读者疾速回顾每种体系架构格调和模式的次要特色。 1. 分层架构格调(Layered Architecture Style)分层架构是最常见的架构模式之一,通常用于传统web利用序和企业应用程序。 准则: 这种体系架构格调将关注点划分为不同的层。典型的例子是三层架构: 表示层、业务逻辑层和数据存储层。长处: 易于了解、测试和保护,每一层都能够独立开发和更新。毛病: 有额定的性能开销,影响多个层的更改可能很难实现。利用: Web利用、企业应用。反模式: 循环依赖,跨层依赖。分层(n层)模式n层架构将零碎划分为n层,每一层都有特定职责。最常见的划分是三层: 表示层、业务逻辑层和数据存储层。 整洁/洋葱模式整洁体系架构,也被称为洋葱体系架构,是一种强调零碎内关注点拆散的软件设计哲学。它将软件组织成同心的层,以畛域模型为外围,四周是特定于应用程序的层。外层只依赖内层,促成高度的解耦和隔离。这使得基础设施、UI或内部代理的更改对业务逻辑的影响最小。对于须要高度可维护性、可测试性和独立于UI、数据库或内部框架的零碎来说,是现实的抉择。 2. 基于组件的体系架构格调这种格调强调对整个软件系统中可用的宽泛性能的关注拆散。 准则: 这种体系架构格调将零碎组织为松耦合、可重用的组件。长处: 高可重用性、灵活性和可维护性。毛病: 治理组件及其交互的复杂性。利用: Web利用、桌面利用、分布式系统。反模式: 过于宏大的组件,冗余的组件。面向对象模式这种模式是基于"对象"的范式,对象能够蕴含数据和代码: 字段模式的数据(通常称为属性)和过程模式的代码(通常称为办法)。该模式促成了封装、继承和多态,使设计、实现、保护简单零碎变得更加容易。 微内核模式此模式将最小性能外围(微内核)与扩大性能及特定于客户的局部拆散开来。微内核蕴含外围性能,而其余个性则作为微内核的插件实现。这使得零碎能够很容易扩大,而无需批改外围。 插件模式此模式容许通过增加新模块或插件向应用程序增加新性能。新模块通过标准接口集成到利用中,从而能够扩大和定制应用程序。这种模式通常用于web浏览器、媒体播放器和内容管理系统。 3. 面向服务的体系架构格调这种格调将软件设计为互相通信的服务汇合。每个服务都是自蕴含的,代表具备确定后果的特定业务流动。 准则: SOA将利用程序设计为通过网络进行通信的服务汇合。长处: 灵活性、可伸缩性、可重用性和松耦合。毛病: 减少了复杂性、网络依赖性和潜在的性能问题。利用: 企业零碎、web服务、微服务。反模式: 疏忽业务需要,在不须要SOA的中央应用SOA。面向服务的体系架构模式这种模式将软件设计为多个零碎可复用的离散服务的汇合。SOA模型中的每个服务都是为执行特定业务性能而构建的,例如查看客户的信用评分、计算付款或解决抵押贷款。这些服务通过网络互相通信,以实现特定流动,例如解决抵押贷款申请。SOA促成了可重用性,多个利用能够灵便应用服务,特定服务能够在不影响其余服务的状况下被批改或替换。 代理(Broker)模式在代理模式中,零碎组件通过代理实体进行通信。代理协调通信,例如转发申请、传输后果和异样。这种模式通过解耦的组件构建分布式软件系统,组件通过近程服务调用进行交互。 微服务模式此模式将软件应用程序设计为一组小型服务,每个服务在其过程中运行,并与轻量级机制(通常是HTTP)通信。这些服务围绕业务性能构建,能够通过齐全自动化的部署机制独立部署。这种模式容许疾速、频繁、牢靠的交付简单应用程序。 无服务器(性能即服务或FaaS)模式在此模式中,应用程序在云环境中构建和运行,不须要思考服务器。云服务商动静治理机器资源的调配,开发人员能够只关注利用代码中的单个性能。此模式非常适合可伸缩的事件驱动应用程序。 4. 分布式系统架构格调这种格调指的是由一组组件交互实现独特指标的零碎,这些组件位于联网的计算机上,通过传递音讯进行通信以及协调相互的动作。 准则: 该架构波及多个零碎在网络上一起工作,对最终用户显示为单个零碎。长处: 可伸缩性、容错性和资源共享。毛病: 减少了复杂性、网络依赖性以及与数据一致性相干的问题。利用: 分布式数据库、云计算、电信网络。反模式: 不思考网络故障,疏忽数据一致性挑战。云架构模式这种模式旨在通过在多个服务器均匀分布服务和资源来防止任何单点故障或性能瓶颈,非常适合须要100%失常运行工夫和程度可扩展性的大容量、要害工作型应用程序,例如金融交易零碎或在线游戏平台。 ...

February 20, 2024 · 1 min · jiezi

关于后端:AnyText-多语言视觉文本生成与编辑

AnyText: 多语言视觉文本生成与编辑论文介绍 Anytext: Multilingual Visual Text Generation and Editing关注微信公众号: DeepGoAI我的项目地址:https://github.com/tyxsspa/AnyText(曾经3.3k+) 论文地址:https://arxiv.org/abs/2311.03054 本文介绍一款基于扩散模型的多语言视觉文本生成与编辑工具AnyText。其旨在图像中渲染精确且连贯的文本。AnyText 通过一个蕴含辅助潜在模块和文本嵌入模块的扩散流程实现文本的生成或编辑,能够在图像中无缝整合文本,反对多种语言,是首个针对多语言视觉文本生成的工作。 上图展现了论文中的 文字生成和编辑的成果。能够说是十分真切且天然。不仅如此,对于文字编辑,能够实现高质量的篡改编辑,属实是十分惊艳。 这里展现了更多编辑的成果,在不规整的掩码下,仍然能够做到毫无违和感的编辑成果。 办法概述 AnyText的框架,包含以下模块: 辅助潜在模块(Auxiliary Latent Module) :该模块应用文本符号、地位和遮罩图像等输出来生成文本生成或编辑的潜在特色。文本嵌入模块(Text Embedding Module) :采纳OCR模型编码笔画数据为嵌入,这些嵌入与来自分词器的图像题目嵌入混合,生成与背景无缝集成的文本。文本管制扩散管道(Text-Control Diffusion Pipeline) :负责解决和生成文本,确保生成的文本与图像背景天然交融。文本感知损失(Text Perceptual Loss) :在训练过程中应用,进一步提高生成品质。工作流程大抵如下: 输出解决 :首先通过辅助潜在模块解决输出数据(文本符号、地位和遮罩图像等),生成用于后续文本生成或编辑的潜在特色。文本嵌入 :应用文本嵌入模块解决OCR模型编码的笔画数据和图像题目嵌入,为扩散管道提供所需的文本信息。文本生成与编辑 :联合潜在特色和文本嵌入,通过文本管制扩散管道生成或编辑图像中的文本,确保文本与图像背景的天然交融。损失计算 :在训练过程中,应用文本感知损失进一步优化模型性能,进步文本生成的准确性和天然度。 论文中次要训练辅助潜在模块,文本嵌入模块以及文本管制扩散管道中的局部参数,如ControlNet。训练指标定义为:$\mathcal{L} = \mathcal{L}_{td} + \lambda \ast \mathcal{L}_{tp}.$ 其中 $L_{td}$ 为文本管制扩散损失,$L_{tp}$ 为文本感知损失,$\lambda$ 用于调整两个损失函数之间的权重比例。文本管制扩散管道潜在示意生成:首先,应用变分自编码器(VAE)解决输出图像 $x_0 \in \mathbb{R}^{H \times W \times 3}$,生成潜在示意 $z_0 \in \mathbb{R}^{h \times w \times c}$。这里,$h \times w$ 代表通过因子 $f$ 下采样的特色分辨率,$c$ 示意潜在特色维度。噪声增加:而后,潜在扩散算法逐渐向 $z_0$ 增加噪声,生成噪声潜在图像 $z_t$,其中 $t$ 示意工夫步。条件集成:给定一组条件,包含工夫步 $t$,辅助特色 $z_a \in \mathbb{R}^{h \times w \times c}$ 由辅助潜在模块生成,以及文本嵌入 $c_{te}$ 由文本嵌入模块生成,文本管制扩散算法利用网络 $\epsilon_\theta$ 来预测增加到噪声潜在图像 $z_t$ 的噪声,指标函数为:$$\mathcal{L}_{td} = \mathbb{E}_{z_0, z_a, c_t, \epsilon, \sim \mathcal{N}(0,1)} \left[ \left\| \epsilon - \epsilon_{\theta}(z_t, z_a, c_{te}, t) \right\|^2 \right]$$ ...

February 20, 2024 · 1 min · jiezi

关于后端:深入理解-Java-方法重载与递归应用

Java 办法重载办法重载 容许在同一个类中定义多个具备雷同名称的办法,但 参数列表 必须不同。 语法: returnType methodName(parameter1, parameter2, ..., parameterN) { // 办法体}示例: public class Main { // 重载 add 办法,反对 int 和 double 类型参数 static int add(int x, int y) { return x + y; } static double add(double x, double y) { return x + y; } public static void main(String[] args) { int sum1 = add(10, 20); double sum2 = add(3.14, 1.618); System.out.println("int: " + sum1); System.out.println("double: " + sum2); }}输入: ...

February 19, 2024 · 2 min · jiezi

关于后端:sensitiveword-v013-特性版本发布-支持英文单词全词匹配

拓展浏览sensitive-word-admin v1.3.0 公布 如何反对分布式部署? sensitive-word-admin 敏感词控台 v1.2.0 版本开源 sensitive-word 基于 DFA 算法实现的高性能敏感词工具介绍 更多技术交换 业务背景对于英文单词 Disburse 之类的,其中的 sb 字母会被替换,要怎么解决,能不能只有整个单词匹配的时候才替换。 针对匹配词进一步判断阐明反对版本:v0.13.0 有时候咱们可能心愿对匹配的敏感词进一步限度,比方尽管咱们定义了【av】作为敏感词,然而不心愿【have】被匹配。 就能够自定义实现 wordResultCondition 接口,实现本人的策略。 零碎内置的策略在 WordResultConditions#alwaysTrue() 恒为真,WordResultConditions#englishWordMatch() 则要求英文必须全词匹配。 入门例子原始的默认状况: final String text = "I have a nice day。";List<String> wordList = SensitiveWordBs.newInstance() .wordDeny(new IWordDeny() { @Override public List<String> deny() { return Collections.singletonList("av"); } }) .wordResultCondition(WordResultConditions.alwaysTrue()) .init() .findAll(text);Assert.assertEquals("[av]", wordList.toString());咱们能够指定为英文必须全词匹配。 final String text = "I have a nice day。";List<String> wordList = SensitiveWordBs.newInstance() .wordDeny(new IWordDeny() { @Override public List<String> deny() { return Collections.singletonList("av"); } }) .wordResultCondition(WordResultConditions.englishWordMatch()) .init() .findAll(text);Assert.assertEquals("[]", wordList.toString());当然能够依据须要实现更加简单的策略。 ...

February 19, 2024 · 1 min · jiezi

关于后端:高性能-Rust-JSON-库-sonicrs-开源

1. sonic-rs 介绍sonic-rs 是一个基于 SIMD 的高性能 Rust JSON 库,是 sonic JSON 库的 Rust 版本。字节跳动 sonic 开源我的项目现在蕴含了不同语言的多个 JSON 库(如下)。其中,sonic-go 最先开源,应用了 JIT 和 SIMD 技术,sonic-cpp 应用了 C++ 模板和 SIMD 技术,这两个 JSON 库均曾经在字节外部失去了较大规模的落地。在老本优化大背景下,为了帮忙 Golang 业务迁徙 Rust,优化 Rust JSON 性能,咱们基于JSON 方面的优化教训和实际,用纯 Rust 语言开发了高性能的 JSON 库 sonic-rs。 sonic: https://github.com/bytedance/sonic(Golang JSON 库)sonic-cpp: https://github.com/bytedance/sonic-cpp(C++ JSON 库)sonic-rs: https://github.com/cloudwego/sonic-rs(Rust JSON 库)sonic-rs 目前反对的 JSON 性能比拟齐全,根本对齐了 serde-json 的相干性能,并且提供更加丰盛的性能和更多的高性能接口。sonic-rs 的次要性能特点有: 根本兼容 Serde 生态,同时反对 Volo 中的 FastStr 类型反对动静类型编解码和按需解析反对 LazyVaue, RawNumber 等类型反对 UTF-8 校验和规范浮点数精度在性能方面,咱们基于 serde-rs 官网 benchmark(https://github.com/serde-rs/json-benchmark) 提供的 Rust 构造体和 JSON 数据,对 serde-json, simd-json 和 sonic-rs 在 Rust 构造体下的解析性能进行了测试,能够发现 sonic-rs 的性能是 simd-json 的 1.5\~2 倍,是 serde-json 2 倍: ...

February 19, 2024 · 2 min · jiezi

关于后端:AutoMQ-社区双周精选第七期2024012920240209

本期概要过来的两周里,社区贡献者@lifepuzzlefun 为 AutoMQ 的 RocketMQ 我的项目优化了 LogCache 的二分查找性能,打消了不必要的List拷贝。 同时,AutoMQ 的骨干动静展现了继续的性能优化和性能加强。在 Kafka 我的项目中,团队设计了新型文件缓存机制,以反对小数据、重复读和二分查找跳读场景,同时优化了 WAL 复原速度,使 1GiB 数据恢复工夫大幅缩短。此外,Kafka 还新增了 Grafana 用户视图和开发者视图的大盘,以提供更全面的集群监控能力。 这些致力将独特推动 AutoMQ 向更高效、牢靠和易用的音讯队列服务迈进。 社区贡献者名单本周新增社区贡献者 :@lifepuzzlefunhttps://github.com/AutoMQ/automq-for-rocketmq/pull/903该 PR 优化了 LogCache 二分查找时额定的 List 拷贝 AutoMQ 骨干动静事务索引和工夫戳索引文件缓存https://github.com/AutoMQ/automq-for-kafka/pull/740https://github.com/AutoMQ/automq-for-kafka/pull/743https://github.com/AutoMQ/automq-for-kafka/pull/745 依据事务索引和工夫戳索引的查问特色,设计了更加适宜小数据、重复读和二分查找跳读的文件缓存: 缓存空间限度在 200MB,不随着分区数量线性扩大;索引长久化的同时写入缓存,缓存的空间能够撑持到 S3Stream 的小 Object 合并成大 Object,使得 AutoMQ Kafka 维持高效索引查问效率; WAL 复原减速https://github.com/AutoMQ/automq-for-rocketmq/pull/910 通过 Buffer 读取机制,减速 WAL 的复原,1GiB 的数据恢复工夫从 92.7s 优化到 15.3s Grafana 用户 & 开发者大盘https://github.com/AutoMQ/automq-for-kafka/pull/778 新增了 Grafana 用户视图和开发者视图的大盘: 在用户视图,用户能够概览整个集群的运行状况,而后依据需要下钻到 Broker 单机大盘、Topic 大盘和 Group 大盘;在开发者视图,开发者能够一览 Broker 的 CPU、JVM、申请吞吐 & 耗时和 S3Stream 外部的具体运行状况;END ...

February 19, 2024 · 1 min · jiezi

关于后端:java添加图片水印

封装文字信息并增加文字 List<ImageDTO> list = new ArrayList<>(); list.add(createImageDTO("测试水印"+ " KG", //文字内容 new Color(255, 0, 0, 255), //色彩及透明度 new Font("微软雅黑", Font.PLAIN, 24), //字体 0.6d, //横坐标地位 0.1d //纵坐标地位 )); //通过网络url获取图片file String url = "https://......."; File srcImgFile = URLToFile(url, fileName); //调用增加文字 BufferedImage file = setWatermarkTask(srcImgFile, list);可间接传入xy坐标地位,本文已改为传入百分比并通过图片宽高计算 /** * 增加水印 */ private BufferedImage setWatermarkTask(File srcImgFile, List<ImageDTO> list) { try { Image srcImg = ImageIO.read(srcImgFile);//文件转化为图片 int srcImgWidth = srcImg.getWidth(null);//获取图片的宽 int srcImgHeight = srcImg.getHeight(null);//获取图片的高 //增加文字: BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB); Graphics2D g = bufImg.createGraphics(); g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null); for (ImageDTO imgDTO : list) { g.setColor(imgDTO.getColor()); //依据图片的背景设置水印色彩 g.setFont(imgDTO.getFont()); //设置字体 g.drawString(imgDTO.getText(), Math.round(imgDTO.getX() * (double) srcImgWidth), Math.round(imgDTO.getY() * (double) srcImgHeight)); //画出水印 } g.dispose(); return bufImg; } catch (Exception e) { throw new RuntimeException(e); } } /** * 创立ImageDTO, 每一个对象,代表在该图片中要插入的一段文字内容: * * @param text : 文本内容; * @param color : 字体色彩(前三位)和透明度(第4位,值越小,越通明); * @param font : 字体的款式和字体大小; * @param x : 以后字体在该图片地位的横坐标; * @param y : 以后字体在该图片地位的纵坐标; * @return */ private ImageDTO createImageDTO(String text, Color color, Font font, Double x, Double y) { ImageDTO imageDTO = new ImageDTO(); imageDTO.setText(text); imageDTO.setColor(color); imageDTO.setFont(font); imageDTO.setX(x); imageDTO.setY(y); return imageDTO; } /** * 读取网络中的图片 */ private File URLToFile(String url, String fileName) { File file1 = new File(fileName); try { URL url1 = new URL(url); FileUtils.copyURLToFile(url1, file1); } catch (IOException e) { e.printStackTrace(); } File absoluteFile = file1.getAbsoluteFile(); return file1; }文字详情实体类 @Data public class ImageDTO { //文字内容 private String text; //字体色彩和透明度 private Color color; //字体和大小 private Font font; //所在图片的x坐标百分比 private Double x; //所在图片的y坐标百分比 private Double y; }

February 19, 2024 · 2 min · jiezi

关于后端:时光机与多维视界⭐️MySQL中原子性与隔离性的科幻大片

“时光机”与“多维视界”⭐️MySQL中原子性与隔离性的科幻大片上篇文章 咱们形容完MySQL的持久性等知识点,本篇文章来形容MySQL的原子性与隔离性知识 ”时光机“指的是实现原子性的undo log,”多维视界“指的是实现并发场景下读不加锁的MVCC,一起往下看看吧~ 内容脑图如下: MySQL中反对事务的只有Innodb,因而本篇文章形容的原理也是Innodb实现原子性的原理 事务的原子性:一组事务要么都胜利,要么都失败 在事务中可能存在一些写操作(新增/批改/删除),有的写操作会执行胜利,然而后续写操作执行失败就会导致事务须要回滚,那么执行胜利的写操作就要退回到原来的“版本” 为了不便回滚,Innodb应用undo log来记录每次写操作批改的内容,依据undo log可能疾速退回到原始版本 每一行记录中存在暗藏列 roll\_pointer 回滚指针,它指向上一次写操作产生的undo log,undo log中也存在相似回滚指针的列,它可能找到它上一次写操作产生的undo log 记录与undo log就会造成一条”版本链“,这样在遇到回滚时便能疾速的回到原来的版本以此来实现原子性(回滚) 留神:undo log只是记录批改的数据,并不是残缺数据,图中只是为了不便展现,图中执行SQL程序为从下到上 隔离性为了避免并发事务穿插执行导致的数据不统一等并发问题,MySQL会依据不同的隔离级别来解决不同的隔离性问题 隔离性问题与隔离级别不同隔离级别下会应用不同的计划来达到隔离性,咱们先来温习一下隔离性问题和隔离级别: 隔离性问题脏写:A事务和B事务同时批改一行记录,A能够笼罩B批改后未提交的记录,后续B又进行回滚 脏读:A事务读取B事务未提交的记录,而后B事务回滚,导致A事务读取的数据不统一 不可反复读:A事务前后两次执行同一个查问,返回的后果数据不同,B事务在此期间进行批改 幻读:A事务前后两次执行同一个查问,返回的后果数量不同,B事务在此期间进行新增 幻读强调后果数量不同,不可反复读强调后果数据不同 隔离级别读未提交(RU):能够读到其余事务未提交的记录,会呈现脏读、不可反复读、幻读 读已提交(RC):只能读到其余事务提交的记录,会呈现不可反复读、幻读 可反复读(RR):Innodb默认,不会呈现不可重读的状况,可能呈现局部幻读 串行化(S):所有隔离性问题都会不产生 随着隔离性的严格,性能也会升高:RU > RC > RR > S MVCC那么在undo log的版本链中是如何做到有的事务可能看到该版本、有的事务看不到该版本的呢? 其实这是通过MVCC(Multi Version Concurrency Control 多版本并发管制)来实现的,MVCC在这种读写并发的场景下,应用无锁机制读取到满足隔离级别的数据 对于事务来说,当事务中呈现第一条写操作的语句时就会生成事务ID,这个事务ID是全局递增的 当应用MVCC时会生成read view来判断以后事务可能读到哪个版本上的记录 read view中就蕴含事务ID相干的属性,便于判断事务能读到哪个版本 最小事务ID:read view生成时沉闷事务中最小的id最大事务ID:read view生成时沉闷事务中最大的id沉闷事务列表:read view生成时存在的沉闷事务 后面说到:事务ID是全局自增的,这示意能够依据事务ID查看哪个事务先执行、哪个事务后执行、哪个事务已提交/回滚、哪个事务以后还在执行中 应用read view与版本链上的最新记录进行判断(判断规定如下): 如果read view的最小事务id大于该记录的事务id,阐明该记录的事务曾经提交了,那么是能够查看的如果read view的最大事务id小于该记录的事务id,阐明该记录的事务在以后事务开启后才开始,那么无奈查看如果该记录id在read view最小、大事务id之间,那么要查看以后沉闷事务列表,如果在列表中,阐明该列的事务沉闷(还未完结),则无奈查看;反之则能够查看如果记录的事务id是以后事务,则能够查问(以后事务执行的,当然能够查看)当该版本的记录无奈查看时,就会遍历版本链持续向下一条记录应用该规定 比方read view 最小事务id:20 最大事务id:30 沉闷事务列表:20,22,24,27,30 ...

February 19, 2024 · 1 min · jiezi

关于后端:营销系统黑名单优化位图的应用解析-京东云技术团队

背景营销零碎中,客户投诉是业务倒退的一大妨碍,个别会过滤掉黑名单高风险账号,并配合频控策略,来缩小客诉,进而减少营销效率,缩小营销老本,晋升营销品质。 营销零碎个别是通过大数据分析建模,在CDP(客户数据平台,以客户为外围,围绕数据交融、人群圈选、用户洞察等提供产品能力)创立营销指标客户群体,黑名单同样也是通过CDP保护。上面的图片简略形容了过滤黑名单的解决流程,流程是绝对简略的。然而,测试过程中却发现一个问题,对于一个近30万的营销群体,整个触达流程须要解决一个多小时,而其中过滤黑名单就占用了近半个小时的工夫,业务有点难以承受这个性能。 性能优化引入多线程优化其实很容易就能想到,对于调用RPC接口这种含有I/O操作的场景,能够引入多线程优化,将一个几十万的账号汇合拆分为多个子工作提交给线程池解决,从而放慢处理速度。从下图能够看出引入多线程后性能有很显著的改善,单线程解决25万、50万个账号的群体别离须要近半小时、近一小时,改为25个线程解决后能够别离管制在1分钟、2分钟左右。 引入位图优化进一步理解CDP的底层原理后,会发现这个问题应该还有其余的解决方案,即通过位图优化。CDP的群体都会有对应的位图文件,也就是说营销客户群体和黑名单群体都是以位图的数据结构存储的,通过CDP下载群体的SDK就能够获取到位图文件,营销群体的位图与黑名单群体位图进行与非操作(andNot,就是从一个位图中移除另一个位图中存在的元素,而保留不在另一个位图中的元素),失去的新的位图就是过滤掉黑名单账号后的指标客户的位图。代码实现很简略,应用CDP SDK的示例代码如下(也能够参考GitHub示例代码,但不适用于CDP群体位图解决): DataLoader dataLoader = new DataLoader(token, bitMapBaseUrl);ABitmap customerBitmap = dataLoader.loadGroup(customerGroupCode);ABitmap blacklistBitmap = dataLoader.loadGroup(blacklistGroupCode);customerBitmap.andNot(blacklistBitmap);位图存储相当节俭空间,50万群体的位图文件也就约2MB大小。同时位图的与非操作是相当快的,上边例子中的25万、50万的群体都能够在80毫秒左右过滤掉黑名单账号。从近半小时、近一小时到几十毫秒这个比照十分惊人了,那么为什么位图的处理速度能够这么快呢? 位图简介位图原理位图的根本思维是应用bit来标记一个数值,1示意该数值存在,0示意不存在。因为以位为单位存储数据,因而能够大大节俭存储空间。通过这种形式,能够十分高效地示意和操作数值汇合。 举个直观的例子,有40亿个不反复的随机自然数,如果应用long型数值存储,一个long型数值8个字节,40亿个数值占用约29.8GB,但如果是存储为40亿个bit,则只须要约0.47GB。 在Java中一个long型数值占64位,能够用一个long型数组long[] words = new long[(nBits - 1) / 64 + 1]存储位图,其中nBits示意位图的初始大小。对于给定任意自然数x,x / 64就能失去x在数组中的下标,x % 64就能失去x在此下标的哪个位。数组的第一个下标words[0]能够示意数值0~63,第二个下标words[1]能够示意数值64~127,之后依此类推。 如果将 3, 4, 6 几个数值存入位图,则如下图所示,对应数组的第一个下标的 3, 4, 6 位被标记为1,其余位均为0。 对于增加操作,假如要增加数值2,能够计算出其在数组中的下标为2 / 64即0,在words[0]的地位为2 % 64即2,只需将1按位左移2位,而后和words[0]进行按位或操作,将相应地位置为1。 对于移除操作,假如要移除刚增加的数值2,和增加操作一样,能够通过计算失去其在数组的下标为0, 在words[0]的地位为2,只需将1按位左移2位再按位取反,而后和words[0]进行按位与操作,将相应地位置为0。 而对于查找操作,假如要查找数值3,能够计算失去其在数组的下标为0, 在words[0]的地位为3,只需将1按位左移3位,而后和words[0]按位与操作不等于0即可判断数值是否存在。 以上内容简略介绍了 Java 中的BitSet的实现原理,理论代码还会略微简单一些,比方会波及到数组扩容,范畴边界的检测等等。有意思的是BitSet中计算数组下标和地位并没有应用除法和取模,都是通过位移操作实现的,x / 64是通过右移操作x >> 6,1按位左移x % 64位是间接将1左移x位即1 << x。 ...

February 19, 2024 · 1 min · jiezi

关于后端:Volo-开源一周年-性能优化与生态建设

回顾过去一年 CloudWeGo Rust Team 所做的工作,如果要用两个关键词来总结一下的话,那就是性能优化和生态建设。本文次要分为三点来介绍,第一点是大抵总结和回顾下 Volo 这一年的倒退,第二点是重点介绍一下 Volo 里的性能优化,第三点是将来咱们的工作重点将聚焦在哪些方面。 1. Volo 这一年在 2022 年 8 月,咱们曾发表了一篇名为「国内首个基于 Rust 语言的 RPC 框架 — Volo 正式开源」的官宣文章,在外面具体介绍了 Volo 的一些个性以及围绕 Volo 所同步开源的 Pilota、Motore、Metainfo 等组件。时隔一年,Volo 及其相干组件已有不少变更,简略来总结一下的话,那将会别离是 Volo - 性能补全 & 性能优化、 Pilota - 能力降级、Motore - 趋于稳定、Metainfo - 易于应用。 特地的,咱们还想带大家一起回顾下 Volo 在这一年中的一些要害节点和技术更新。 在开源后的不久,咱们就收到了来自社区同学 @anwentec 的第一个 PR,该 PR 次要是反对用户在 Windows 上也能应用 Volo 来进行开发,大大补全了框架的多平台支持性。紧接着,咱们迎来了自公布以来的第一个重大性能优化 —— 编解码重构,该优化灵感最后起源于社区同学 @ii64 在 Pilota 中提出的一个新增 Thrift 协定反对的 PR,在一些探讨交换过后,咱们发现 Volo 现有能力不能很好的反对用户传入自定义的编解码,于是才有了当初的 Volo 编解码重构和优化。值得一提的是,在这个过程中,咱们还公布了 linkedbytes 和 faststr 这两个 crate,在辅助优化进行的同时,也丰盛了 Rust 开源的相干生态。最初,在编解码这块,咱们还通过 unsafe 代码绕过了一些边界查看,使得辅助编译器生成了更高效的 SIMD 并行操作指令,大大晋升性能。如果大家还想理解 Volo 更多具体的停顿,能够在 CloudWeGo 官网查看咱们的 Release Note。 ...

February 19, 2024 · 1 min · jiezi

关于后端:程序员金三银四跳槽指南时间线经典面试16问

祝大家胜利上岸,升职加薪,冲鸭 金三银四明天停工,就要开始筹备啦✨ 把握好打工人跳槽的金三银四,取得称心的新工作 工夫线年后跳槽工夫线,过完年刚好开始筹备: 1️ 筹备简历 2.12-2.25⏰梳理过往工作内容依据JD要求,针对性写简历筹备面试题库2️ 集中投递 2.21-3月上旬⏰投递工夫:周一到周四9:00-11:00,下午2:00-4:00投递渠道:企业网站/求职网站/公众号/内推等等3️ 面试练手 2月底-3月上旬⏰抉择低动向度公司3~4家,每周2~3场面试总结面试问题,进步面试技巧指标:适应面试节奏,进步面试通过率4️ 正式面试 3月上-3月底⏰中动向度公司2~3家,高动向度公司2~3家offer越多越好,利用已拿到的offer谈价指标:薪资涨幅越高越好,倒退方向越合乎越好5️ 接offer 入职 4月⏰2~3轮谈薪资绩效考核/福利倒退/五险一金offer越多越好,利用已拿到的offer谈价经典面试16问 秘籍 又出问题啦咱们又出问题啦!大厂Offer集锦!遥遥领先! 这些敌人赢麻了! 这是一个专一程序员升职加薪の常识星球 思否面试题集锦据说这道Go面试题90%的人都搞错了! Go语言学习&面试题专栏

February 19, 2024 · 1 min · jiezi

关于后端:类支付宝积分系统设计方案过期兑奖

集体博客:无奈何杨(wnhyang) 集体语雀:wnhyang 共享语雀:在线常识共享 Github:wnhyang - Overview 申明本篇文章纯正抛砖引玉! 需要阐明单刀直入,业务背景间接跳过。 类比支付宝会员积分,支付宝APP-我的-支付宝会员。 支付宝会员-XXX积分-积分规定,能够看到具体的积分规定,本篇文章类比于此积分业务场景,做简略的设计。 积分阐明积分不具备货币或现金价值,不可兑现,不可转让。用户能够通过领取、账户服务、金融理财和积分处分流动等形式来获取积分。 积分能够兑换各类权利、参加各种积分流动等,具体以权利兑换及流动页面展现为准。 积分支付规定积分发放后,用户可返回“我的”-“支付宝会员”,点击支付积分球,或者在领取胜利页面、服务音讯揭示、账单点击支付,积分方可到账。积分自产生之时起,支付有效期7天(168小时),逾期不领则作废,不予补发。 积分获取形式1、领取 2、账户服务 3、金融理财 4、扫一扫 5、等 积分有效期用户取得的积分有效期为自取得当月起的12个天然月,有效期内未应用的积分到期将主动清零,不予补发。 舒适提醒: 1、用户日常应用的积分,将优先应用行将过期的积分。 2、每月,用户可在“我的”-“支付宝会员”-“收支/订单/规定”页查看当月月底行将过期的积分。 3、已应用的积分若产生退还,积分有效期不变,仍以该笔积分原获取工夫计算有效期。 积分权利兑换积分能够兑换各类权利、参加各种积分流动等,具体以权利兑换及流动页面展现为准。 积分与成长体系略 需要剖析因为下面简直都是粘贴于支付宝对外展现的积分规定,而这篇文章波及范畴并没有那么广,所以这里要申明一下需要范畴。 积分获取形式领取、账户服务、金融理财、扫一扫等。 同步计划:这个就波及到AOP的思维,换言之“狭义AOP”。这个不是单个零碎能实现的,须要多方零碎独特确认,而本零碎须要提供牢靠的积分累计接口。如:用户领取实现后应该累计积分的,通过什么形式与积分零碎交互减少积分呢?这样的接口如何设计呢?除了用户惟一标识、积分值、交易工夫、交易类型还有什么必要字段呢?需不需要重试?如何做幂等?分布式事务如何思考?等等,还有很多因素要思考。 异步计划:有时咱们对于积分累积的时效性并不高,就能够思考异步计划。异步无非就是音讯队列类的异步工作,或是有数据团队来做数据的剖析解决。异步工作形式不论是音讯队列或是事件驱动都大略可行,当然这两头也有很多中央要留神。数据分析解决有点像是定时工作,形容可能不太精确,就是通过剖析用户理论数据来具体分析解决,如:每天2点,数据团队有多个数据模型针对不同的数据表(账户贷款、理财等等)对用户前一天所有交易进行剖析,计算积分而后累计前一天产生的积分。 对于积分获取形式,本次就探讨到这了。其实下面简略剖析曾经蕴含了很多零碎设计的必要思考条件了,而且很多都能够类比的,比方积分累计不就是相似购物产生订单,或是记录操作日志吗。有很多相似之处的,能够类比思考一下。 积分支付规定从前面积分支付规定能够确定,积分支付波及音讯告诉和过期。 音讯告诉必定是成体系的,可参考其余音讯类零碎设计。过期能够参考上面的积分过期。 积分有效期这个是本篇文章中我想要突出的重点。积分产生、积分兑换、积分过期还是须要好好思考一下的,如若不然,甚至不单单是产生零碎bug,甚至会有业务bug,这是难以承受的。 既然下面需要阐明了积分有效期是12个天然月,那么就能够思考设计一张按月存储的表来存储积分。 如5.1-5.31的产生的积分存储为一条可用积分记录,过期工夫为5.31 23:59:59,总积分值为最近12个月积分之和。 用户ID累计积分可用积分值过期工夫13003005.31 23:59:5915005006.30 23:59:5918007007.31 23:59:5915004008.31 23:59:5913002009.30 23:59:59130010010.31 23:59:59150050011.30 23:59:59160060012.31 23:59:59可能有人在接到积分过期需要时就思考到定时工作扫表的形式,尽管可能也是没问题的,但细节其实挺多的,这里就不做过多探讨了。 积分权利兑换用户日常应用的积分,将优先应用行将过期的积分。针对于下面的月度积分表,在积分兑奖时从最早的未过期的月开始计算扣减积分。 设计方案数据表简略设计如下,月度积分关联多条积分明细记录,这样能够不便查问月度积分获取和耗费明细。 月度积分月度积分id用户id年月(参考2024-01之类的)累计积分可用积分过期工夫积分明细月度积分id明细id用户id积分值类型(如:耗费,获取等)操作工夫兑奖明细兑奖明细id用户id奖品耗费积分奖品名称工夫流程积分获取积分由用户操作生成,同时存储于月度积分表和积分明细表。 积分兑奖 其余除了下面这些,还有 总积分查问,最近12个月的月度积分-可用积分之和积分明细查问,倒序查问月度积分和月度积分明细积分兑奖明细,等,简略的就不多提了参考代码积分兑奖 import java.time.LocalDate;import java.util.*;class PointRecord { private int points; private LocalDate expirationDate; // 构造方法、getters和setters省略 public boolean canConsume(int requiredPoints) { return this.points >= requiredPoints; } public void consume(int requiredPoints) { if (canConsume(requiredPoints)) { this.points -= requiredPoints; } else { throw new IllegalArgumentException("Insufficient points to consume."); } }}public class PointService { public void redeemReward(User user, int rewardPointCost) { List<PointRecord> sortedRecords = getSortedUnexpiredPointRecords(user); for (PointRecord record : sortedRecords) { if (record.canConsume(rewardPointCost)) { record.consume(rewardPointCost); rewardPointCost = 0; // 曾经满足耗费条件,跳出循环 break; } else { rewardPointCost -= record.getPoints(); record.setPoints(0); // 耗费完该记录所有积分 } } // 更新数据库中的积分明细表 updateDatabase(sortedRecords); // 如果rewardPointCost依然大于0,阐明积分有余,须要在此处解决异常情况 if (rewardPointCost > 0) { throw new InsufficientPointsException("Not enough valid points to redeem the reward."); } } // 省略了获取用户未过期且已排序的积分记录列表的办法(getSortedUnexpiredPointRecords)以及更新数据库的办法(updateDatabase)}在这个示例中,PointRecord类代表单个积分记录,蕴含积分值和过期日期。PointService中的redeemReward办法首先获取用户的所有未过期且按过期工夫排序的积分记录,而后遍历这些记录,优先扣除最早到期的积分。当所需兑换积分数量减为0时进行扣除。如果最初仍有残余的兑换积分需要,则抛出积分有余的异样。 ...

February 18, 2024 · 1 min · jiezi

关于后端:sensitivewordadmin-v130-发布-如何支持敏感词控台分布式部署

拓展浏览sensitive-word-admin v1.3.0 公布 如何反对分布式部署? sensitive-word-admin 敏感词控台 v1.2.0 版本开源 sensitive-word 基于 DFA 算法实现的高性能敏感词工具介绍 更多技术交换 业务背景如果咱们的敏感词部署之后,不会变动,那么其实不必思考这个问题。 然而理论业务,敏感词总是随着工夫一直变动的,所以咱们须要反对敏感词的动静批改。 整体设计pull vs push以数据库存储自定义场景为例,如果页面批改了敏感词信息,那么如何告诉到部署的多台敏感词客户端呢? 个别告诉形式有两大类: 1)push 推送形式 批改时同时告诉敏感词产生了变动,每个敏感词客户端接管到告诉后,从新初始化敏感词信息。 长处是实时性比拟高,毛病是须要引入额定的告诉机制,须要告诉的服务比拟多时,也比拟麻烦。 2)pull 拉取形式 批改后,间接落库数据库,每一个敏感词客户端本人定时拉取变更的信息。 这种形式有点是非常简单,毛病是存在肯定的提早性。 思考到咱们的场景能够容许分钟级的提早,所以这里先实现定时拉取形式。 如何晓得敏感词是否产生了变动?定时拉取的形式比较简单,然而每一次拉取的话,如何晓得是否须要从新初始化呢? 尽管每次的初始化的耗时还好,然而思考到变更不是很频繁,所以有没有方法定时拉取时晓得有没有变动呢? 回顾一下上一篇文章,咱们设计的 word 表 create table word( id int unsigned auto_increment comment '利用自增主键' primary key, word varchar(128) not null comment '单词', type varchar(8) not null comment '类型', status char(1) not null default 'S' comment '状态', remark varchar(64) not null comment '配置形容' default '', operator_id varchar(64) not null default 'system' comment '操作员名称', create_time timestamp default CURRENT_TIMESTAMP not null comment '创立工夫戳', update_time timestamp default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新工夫戳') comment '敏感词表' ENGINE=Innodb default charset=UTF8 auto_increment=1;create unique index uk_word on word (word) comment '惟一索引';依据更新工夫能够吗?如果咱们所有的数据都不执行物理删除,那么间接依据 word 表的 update_time 即可判断。 ...

February 18, 2024 · 3 min · jiezi

关于后端:深入了解-Java-方法和参数的使用方法

Java 办法简介办法是一块仅在调用时运行的代码。您能够将数据(称为参数)传递到办法中。办法用于执行特定的操作,它们也被称为函数。 应用办法的起因重用代码:定义一次代码,屡次应用。进步代码的结构化和可读性。将代码分解成更小的模块,易于保护和了解。创立办法办法必须在类内申明。它的定义包含办法的名称,后跟括号()。Java提供了一些预定义方法,如 System.out.println(),但您也能够创立本人的办法来执行特定的操作: public class Main { static void myMethod() { // 要执行的代码 }}示例解释: myMethod() 是办法的名称。static 示意该办法属于 Main 类而不是 Main 类的对象。void 示意此办法没有返回值。调用办法要在Java中调用一个办法,写出办法的名称,后跟两个括号()和一个分号; public class Main { static void myMethod() { System.out.println("I just got executed!"); } public static void main(String[] args) { myMethod(); }}输入: I just got executed!参数办法能够承受参数,参数就像占位符,容许您在调用办法时传递不同的值。 示例: public class Main { static void myMethod(String name) { System.out.println("Hello, " + name + "!"); } public static void main(String[] args) { myMethod("John Doe"); myMethod("Jane Doe"); }}输入: ...

February 18, 2024 · 2 min · jiezi

关于后端:MySQL持久化不为人知的一面⭐️卡顿现象的根源与对策

MySQL长久化鲜为人知的一面⭐️卡顿景象的本源与对策2024新年新气象,小菜同学又踏上了求职之路,但求职路艰苦,新年第一次面试又被面试官给问住了 面试官:你有没有遇到过因为长久化,把线程的查问、批改申请卡住的状况? 小菜(得意的笑,还想给我挖坑):长久化时写redo log的,利用写redo log的程序性来晋升性能,防止随机IO,因而不会卡住其余线程的申请的 ... 面试官:好,那咱们明天的面试就到这里吧 经验本次面试,小菜同学又重新整理缓冲池、长久化相干的知识点终于搞懂卡顿的本源和对策 文章导图如下: 缓冲池缓冲池的组成缓冲池是一块内存区域,用于将磁盘中的页加载到内存,放慢访问速度 当拜访数据页时须要先判断页是否在缓冲池中,如果不在则须要从磁盘加载到缓冲池(内存)中 那如何判断某个页是否存在于缓冲池中呢?难度去遍历吗?(遍历是不可能遍历的,工夫复杂度太高) 理论是通过Key:表空间 + 页号 Value:页 的形式建设散列表,达到O(1)的查找速度 数据页被加载到缓冲池后称为缓存页,每个缓存页对应一个管制块,管制块上记录数据页的相干信息 缓存页和对应的管制块组成chunk,chunk是申请间断空间的根本单位(当这片空间被缓存页、管制块没占满时还会剩下碎片) 为了防止扩容时从新分配内存,还要将数据从旧的空间迁徙到新的空间,应用chunk进行扩容 拜访缓冲池的线程会加锁,如果并发量大且只有一个缓冲池,开销会很大 应用分段锁的思维:将一个缓冲池分为多个实例,每个实例相当于有一把锁(页hash到实例),每个实例存在数个chunk 调整缓冲池参数如下:应用 innodb_buffer_pool_instances 调整缓冲池实例的数量应用 innodb_buffer_pool_chunk_size 设置每个实例中的chunk数量应用 innodb_buffer_pool_size 规定缓冲池大小,并且其值必须是 innodb_buffer_pool_instanes 和 innodb_buffer_pool_chunk_size 的倍数链表治理缓存页有三种状态: 闲暇:当还未从磁盘加载数据页时,缓存页是闲暇的已应用页洁净:当从磁盘加载数据页到缓冲池时,对应缓存页被占用,但未在页上进行写操作(页不脏)已应用脏页:当有写操作对页中某些记录进行批改时,页并不会立马写回磁盘(这样开销太大),而是通过写redo log的模式保障长久化(后文再说),这种被批改但未写回磁盘的页称为脏页应用不同的链表管理控制块(对应缓存页): 闲暇链表:治理闲暇缓存页的管制块脏页链表:治理脏页缓存页的管制块留神:链表管理控制块相当于治理对应的缓存页 缓冲池的容量始终是无限的,当缓冲池满时须要将命中不高的页换出,将须要的页换进缓冲池 因而为了晋升缓存命中率,应用LRU链表(LRU算法)治理缓存页 当一个页被查问时,LRU算法无论页是否存在都会放到链表头,如果链表已满,则将最初一个节点移除 这种场景下,如果进行范畴扫描(页数量多),将会把大量页移除链表,全表扫描场景下状况会更蹩脚,这会大大降低缓存命中率 为了防止以上场景产生,MySQL对LRU算法进行优化: 将链表分为冷(old)热(young)数据区,首次拜访的页只放到old区的头部 应用 innodb_old_blocks_pct 规定old区占比 (默认37%) 全表扫描可能屡次拜访同一页,所以在规定工夫内屡次拜访某页,不会把它对应管制块放到young区头部 应用 innodb_old_blocks_time 规定该工夫ms (默认1000ms) 如果页对应管制块就在young头部左近就不挪动(规定在1/4) 留神:LRU链表中也可能存储脏页 长久化redo log在聊脏页刷新前须要先搞懂innodb如何长久化 redo log是Innodb存储引擎用于长久化、奔溃复原的重要日志 前文说过,当数据页遇到写操作变成脏页时须要写入磁盘进行长久化 如果对每一条记录都这么做,遇到一个写操作就写入磁盘,而且写回磁盘时,因为页的无序此时会是随机IO,开销十分大 如果想要存一段时间,等该页的脏记录多了再同时刷盘性价比会高一些,然而如果该期间宕机了,那岂不是会产生数据失落?(因为此时还没刷入磁盘) 为了避免数据失落,在宕机时可能进行数据恢复,应用redo log记录页中批改的数据并以程序写入的形式进行IO(程序IO) 当脏页被真正刷入磁盘后,对应的redo log就没有用了,因而redo log被设计成环形文件,以笼罩的形式进行追加日志 redo log通常以ib\_logfile 0...x命名(开端为0-x) ...

February 18, 2024 · 2 min · jiezi

关于后端:Java-Spi是如何找到你的实现的-Java-SPI原理与实践

什么是SPISPI的全称是Service Provider Interface,顾名思义即服务提供者接口,相比API Application Programming Interface他们的不同之处在于API是利用提供给内部的性能,而SPI则更偏向于是规定好标准,具体实现由应用方自行实现。 为什么要应用SPISPI提供方提供接口定义,应用方负责实现,这种形式更有利于解藕代码。在有统一标准,然而不确定应用场景的场合十分实用。 怎么应用SPI接下来我会用一个简略的例子来介绍如何应用SPI: 首先咱们在二方包中定义一个接口Plugin: public interface Plugin { String getName(); void execute();}而后将二方包编译打包后在本人的利用我的项目中引入,之后实现二方包中的接口Plugin,上面我写了三个不同的实现: public class DBPlugin implements Plugin { @Override public String getName() { return "database"; } @Override public void execute() { System.out.println("execute database plugin"); }}public class MqPlugin implements Plugin { @Override public String getName() { return "mq"; } @Override public void execute() { System.out.println("execute mq plugin"); }}public class RedisPlugin implements Plugin { @Override public String getName() { return "redis"; } @Override public void execute() { System.out.println("execute redis plugin"); }}之后在resources目录下的META-INF.services目录中增加以接口全限定名命名的文件。最初在这个文件中增加上述三个实现的全限定名就实现了配置。 ...

February 18, 2024 · 3 min · jiezi

关于后端:Thinkphp6Uniapp微信小程序上传图片到阿里云OSS

阿里云对象存储 OSS(Object Storage Service)是一款海量、平安、低成本、高牢靠的云存储服务。本实例微信小程序直传文件参考官网文档:https://help.aliyun.com/zh/oss/use-cases/use-wechat-mini-prog...,应用STS长期拜访凭证拜访OSS官网文档:https://www.alibabacloud.com/help/zh/oss/developer-reference/...,另外应用STS进行长期受权之PHP受权拜访参考官网文档:https://help.aliyun.com/zh/oss/developer-reference/authorize-...。应用STS受权用户间接拜访OSS的流程如下:开明阿里云OSS开明阿里云oss试用版:https://free.aliyun.com/?pipCode=oss&spm=5176.7933691.J_52537...创立存储空间Bucket存储空间(Bucket)是用于存储对象(Object)的容器创立Bucket存储目录文件列表新建test目录作为图片寄存地位获取Bucket名称和Bucket域名点击浏览进入Bucket根本信息,保留存储空间名称、Endpoint地区节点、Bucket域名创立RAM用户与角色云账号 AccessKey 是您拜访阿里云 API 的密钥,具备账户的齐全权限,应用 RAM 用户(而不是云账号)的 AccessKey 进行 API 调用获取AccessKey ID和AccessKey Secret为RAM用户增加权限:AliyunOSSFullAccess、AliyunSTSAssumeRoleAccess,在左侧搜寻框输出AliyunOSSFullAccess与AliyunSTSAssumeRoleAccess进行增加,而后点确定进行保留。创立角色:第一步抉择阿里云账号第二步配置角色创立实现之后点击“为角色受权”还是增加AliyunOSSFullAccess、AliyunSTSAssumeRoleAccess权限,在左侧搜寻框输出AliyunOSSFullAccess与AliyunSTSAssumeRoleAccess进行增加,而后点确定进行保留。获取角色ARN为角色授予上传文件的权限在创立权限策略页面,单击脚本编辑,而后在策略文档输入框中赋予角色向指标存储空间examplebucket下的目录上传文件的权限。具体配置示例如下。 创立Bucket受权策略配置Bucket跨域拜访客户端进行表单直传到OSS时,会从浏览器向OSS发送带有Origin头的申请音讯。OSS对带有Origin头的申请音讯会进行跨域规定(CORS)的验证。因而须要为Bucket设置跨域规定以反对Post办法。微信小程序配置域名白名单为微信小程序配置域名白名单,以实现微信小程序和OSS Bucket之间的失常通信。登录微信小程序平台,将上传和下载的非法域名填写为Bucket的外网拜访域名。服务端生成签名应用服务端签名时,须要先搭建一个签名服务,而后由客户端调用签名服务生成签名。本例应用Thinkphp6生成签名。首先装置thinkphp6: C:\phpstudy_pro\WWW> composer create-project topthink/think tp应用composer require alibabacloud/sts-20150401命令装置STS依赖,应用composer require alibabacloud/sdk命令装置PHP SDK依赖。 C:\phpstudy_pro\WWW>tp> composer require alibabacloud/sts-20150401C:\phpstudy_pro\WWW>tp> composer require alibabacloud/sdk创立生成签名控制器api.php、配置文件upload.phpupload.php文件配置阿里云oss参数 <?phpreturn ['storage' => '0','oss_ak' => '',//阿里云AccessKeyId 'oss_sk' => '',//阿里云AccessKeySecret''oss_host' => '',//阿里云Bucket 域名'oss_endpoint' => 'oss-cn-hangzhou.aliyuncs.com',//阿里云 Endpoint(地区节点)'oss_bucket' => '',//bucket名称'oss_role_arn' => '', // 角色访问控制RoleArn'oss_role_session_name' => 'stahangdeng', // 长期凭证名称,随便];后端代码实现 <?phpnamespace app\controller;use think\Request;use think\facade\Config;use AlibabaCloud\Client\AlibabaCloud;use AlibabaCloud\Client\Exception\ClientException;use AlibabaCloud\Client\Exception\ServerException;use app\BaseController;class Api extends BaseController{ private $ak=''; private $sk=''; private $host=''; private $bucket=''; private $endpoint=''; private $roleArn=''; private $roleSessionName=''; public function __construct(Request $request){ //配置阿里云参数 empty($this->ak) && $this->ak = Config::get('upload.oss_ak'); empty($this->sk) && $this->sk = Config::get('upload.oss_sk'); empty($this->host) && $this->host = Config::get('upload.oss_host'); empty($this->bucket) && $this->bucket = Config::get('upload.oss_bucket'); empty($this->endpoint) && $this->endpoint = Config::get('upload.oss_endpoint'); empty($this->roleArn) && $this->roleArn = Config::get('upload.oss_role_arn'); empty($this->roleSessionName) && $this->roleSessionName = Config::get('upload.oss_role_session_name'); } /** * 阿里云Sts凭证 */ public function getStsToken(){ AlibabaCloud::accessKeyClient($this->ak, $this->sk) ->regionId('cn-hangzhou') ->asDefaultClient(); try { $result = AlibabaCloud::rpc() ->product('Sts') ->scheme('https') // https | http ->version('2015-04-01') ->action('AssumeRole') ->method('POST') ->host('sts.aliyuncs.com') ->options([ 'query' => [ 'RegionId' => "cn-hangzhou", 'RoleArn' => $this->roleArn, 'RoleSessionName' => $this->roleSessionName, ], ]) ->request(); $resultObj = $result->toArray(); $credentials = $resultObj['Credentials']; $credentials['host'] = $this->host; return json($credentials); } catch (ClientException $e) { return error($e->getErrorMessage()); } catch (ServerException $e) { return error($e->getErrorMessage()); } }uniapp搭建小程序创立我的项目把我的项目运行到微信开发者工具运行到小程序模拟器 ...

February 18, 2024 · 3 min · jiezi

关于后端:Spring事务实现原理

1、引言spring的spring-tx模块提供了对事务管理反对,应用spring事务能够让咱们从简单的事务处理中失去解脱,无须要去解决取得连贯、敞开连贯、事务提交和回滚等这些操作。 spring事务有编程式事务和申明式事务两种实现形式。编程式事务是通过编写代码来治理事务的提交、回滚、以及事务的边界。这意味着开发者须要在代码中显式地调用事务的开始、提交和回滚。申明式事务是通过配置来治理事务,您能够应用注解或XML配置来定义事务的边界和属性,而无需显式编写事务管理的代码。 上面咱们逐渐剖析spring源代码,了解spring事务的实现原理。 2、编程式事务2.1 应用示例// transactionManager是某一个具体的PlatformTransactionManager实现类的对象private PlatformTransactionManager transactionManager;// 定义事务属性DefaultTransactionDefinition def = new DefaultTransactionDefinition();// 获取事务TransactionStatus status = transactionManager.getTransaction(def);try { // 执行数据库操作 // ... // 提交事务 transactionManager.commit(status);} catch (Exception ex) { // 回滚事务 transactionManager.rollback(status);}在应用编程式事务处理的过程中,利用 DefaultTransactionDefinition 对象来持有事务处理属性。同时,在创立事务的过程中失去一个 TransactionStatus 对象,而后通过间接调用 transactionManager 对象 的 commit() 和 rollback()办法 来实现事务处理。 2.2 PlatformTransactionManager外围接口 PlatformTransactionManager是Spring事务管理的外围接口,通过 PlatformTransactionManager 接口设计了一系列与事务处理非亲非故的接口办法,如 getTransaction()、commit()、rollback() 这些和事务处理相干的对立接口。对于这些接口的实现,很大一部分是由 AbstractTransactionManager 抽象类来实现的。 AbstractPlatformManager 封装了 Spring 事务处理中通用的解决局部,比方事务的创立、提交、回滚,事务状态和信息的解决,与线程的绑定等,有了这些通用解决的反对,对于具体的事务管理器而言,它们只须要解决和具体数据源相干的组件设置就能够了,比方在DataSourceTransactionManager中,就只须要配置好和DataSource事务处理相干的接口以及相干的设置。 2.3 事务的创立PlatformTransactionManager的getTransaction()办法,封装了底层事务的创立,并生成一个 TransactionStatus对象。AbstractPlatformTransactionManager提供了创立事务的模板,这个模板会被具体的事务处理器所应用。从上面的代码中能够看到,AbstractPlatformTransactionManager会依据事务属性配置和以后过程绑定的事务信息,对事务是否须要创立,怎么创立 进行一些通用的解决,而后把事务创立的底层工作交给具体的事务处理器实现,如:DataSourceTransactionManager、HibernateTransactionManager。 public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException { TransactionDefinition def = (definition != null ? definition : TransactionDefinition.withDefaults()); Object transaction = doGetTransaction(); boolean debugEnabled = logger.isDebugEnabled(); if (isExistingTransaction(transaction)) { return handleExistingTransaction(def, transaction, debugEnabled); } if (def.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) { throw new InvalidTimeoutException("Invalid transaction timeout", def.getTimeout()); } if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) { throw new IllegalTransactionStateException( "No existing transaction found for transaction marked with propagation 'mandatory'"); } else if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED || def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW || def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) { SuspendedResourcesHolder suspendedResources = suspend(null); if (debugEnabled) { logger.debug("Creating new transaction with name [" + def.getName() + "]: " + def); } try { return startTransaction(def, transaction, false, debugEnabled, suspendedResources); } catch (RuntimeException | Error ex) { resume(null, suspendedResources); throw ex; } } else { if (def.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) { logger.warn("Custom isolation level specified but no actual transaction initiated; " + "isolation level will effectively be ignored: " + def); } boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS); return prepareTransactionStatus(def, null, true, newSynchronization, debugEnabled, null); }}private TransactionStatus startTransaction(TransactionDefinition definition, Object transaction, boolean debugEnabled, @Nullable SuspendedResourcesHolder suspendedResources) { boolean newSynchronization = this.getTransactionSynchronization() != SYNCHRONIZATION_NEVER; DefaultTransactionStatus status = this.newTransactionStatus(definition, transaction, true, newSynchronization, debugEnabled, suspendedResources); this.doBegin(transaction, definition); this.prepareSynchronization(status, definition); return status;}事务创立的后果是生成一个TransactionStatus对象,通过这个对象来保留事务处理须要的根本信息,TransactionStatus的创立过程如下: ...

February 18, 2024 · 6 min · jiezi

关于后端:掌握高性能SQL的34个秘诀多维度优化与全方位指南

把握高性能SQL的34个秘诀多维度优化与全方位指南本篇文章从数据库表结构设计、索引、应用等多个维度总结出高性能SQL的34个秘诀,助你轻松把握高性能SQL 表结构设计字段类型越小越好满足业务需要的同时字段类型越小越好 字段类型越小代表着记录占用空间可能就越小,页中存在的记录就可能越多,雷同IO次数加载的数据就可能更多 字段越小建设索引时消耗的空间就越小,如果该字段是主键那么它还会在二级索引上存储,因而主键也是越小越好 数字类型的抉择数字类型包含整形、浮点型、定点数类型 在不同的场景下能够抉择不同的类型 整形整形通常是tinyint ~ bigint 依据越小越好的准则,对于存储枚举类型的字段应用tinyint进行存储(0-x),而不用应用字符串进行存储 int(1) 和 int(10) 占用的空间无区别,只是int(10)在数据不满10位时进行补零 善用无符号 UNSIGNED 能够进步一倍的容量,比方一些不须要正数的场景(主键、人的年龄 tinyint unsigned 255够用) 浮点型浮点型罕用于存储有小数局部的数据 其中包含float、double类型 留神应用浮点数类型时可能产生精度失落,如果不想失落精度能够抉择定点数类型 定点数类型decimal 罕用于存储有小数、须要计算且不能产生精度失落的数据 字符类型的抉择罕用的字符类型有char和varchar char存储固定字符,当存储字符长度未满时应用空格填充,因而它无奈存储开端空格,在批改时它可能在原记录上进行批改 varchar相当于char空间换工夫的版本,它是可变长字段会多应用1-2个字节记录可变长长度 varchar(255)前1个字节,255后2个字节,但也不是长度不超过255就全副都应用255,在某些存储引擎下会依据长度间接调配空间(如memory),应用长期表默认应用memory,因而在长期表排序时可能会导致占用空间太多 varchar在面对频繁的批改时,还可能造成重建记录、页决裂等问题 固定长度、频繁的批改能够抉择char 不定长、开端要存储空格时能够抉择varchar,varchar长度也要尽量小 留神存表情应用utf8mb4字符编码 在某些场景下,整形替换字符存储会更省空间,也能够思考整形 比方存储IP 具体内容感兴趣的同学能够查看这篇文章:千万数据下varchar和char性能居然相差30% 工夫类型的抉择依据越小越好准则,只须要年、日期、工夫时抉择year、date、time 须要具体日期时能够抉择datetime和工夫戳的形式 datetime固定工夫、无时区、可视化较好 timestamp工夫戳,有时区(依据服务端时区)、有工夫范畴限度、应用零碎时区并发下性能没那么好、可视化不好 应用整形存储工夫戳,性能好,能够自在转换时区,可视化不好 不思考时区、可视化要好大部分场景下能够应用datetime 思考时区(须要自在转换时区)、谋求性能、不重视可视化能够抉择整形存储工夫戳(无符号int 目前够用) 具体内容感兴趣的同学能够查看这篇文章:工夫类型该如何抉择?千万数据下性能晋升10%~30% 文本、文件类型的抉择文本相干能够抉择TEXT相干类型,应用时最好与罕用列进行垂直拆分,防止内容太多影响其余列的查问 文件相干能够存储到文件服务器后,在数据库中应用字符类型(varchar)进行存储文件所在地址 如果肯定要存则应用BLOB相干类型存储二进制数据 尽量满足主键递增主键最好思考是递增的,因为聚簇索引须要保障主键值的有序 当主键递增时,只须要在开端减少记录即可 当入库的主键值无序时,可能会导致页决裂,须要保护有序性的开销 单机下能够应用主键自增,分布式下能够应用全局自增的算法(雪花算法等) 思考突破范式减少冗余个别表构造的设计是遵循三范式的 在某些场景下,能够给一些须要关联的表减少冗余,从而防止联表查问 比方一条记录是由某个设施生成的,该记录必定须要保留字段去关联设施, 需要是晓得该记录由哪个设施生成的即可,因而查问时只须要关联查问设施名称,而设施名称又不会常常扭转 对于谋求性能的场景,能够将设施名称冗余存储在记录上,从而防止联表查问 计算量太大思考两头表对于须要大量计算的场景(比方统计数据、每日排行榜等),每次查问都通过大量计算来统计数据是不事实的 通过减少两头表的形式先进行统计,后续查问时间接查两头表 比方定时工作统计每天数据量、每日排行,计算后,将后果(不同类型的数据量、排行榜TOP100)记录在两头表上,后续有申请则间接查两头表 索引为罕用于查问的列建设索引索引带来的益处是在大数据量下可能疾速检索到满足查问条件的记录 索引会依据抉择的列构建成一颗索引列有序的B+树,比方依据age,student_name建设索引 索引(age,student_name)中只存储索引列(age、student_name)和主键(id) 并且索引中须要把age、student_name、id保护成有序 (整体上age有序,age相等时student_name有序,student_name相等时id有序) 列有较多where条件查问的语句时思考为其建设索引 为常要排序(order by、group by)列创立索引索引会保护列的有序性,为 order by 的列建设索引时,在索引上列自身就是放弃有序的,不会再应用长期表进行排序 ...

February 18, 2024 · 2 min · jiezi

关于后端:开工大吉秀一下我们假期の战绩

动工大吉,新年新气象首先祝大家动工大吉,新年新气象。 祝我的粉丝股东们都能:顺利上岸,升职加薪,日进斗金! 动工就要冲冲冲!春节假期我是好好放松了,在致力克服本人不要像之前那么拼,踏踏实实过好假期,张弛有度。 明天我刷了一下 Go待业训练营 和升职加薪常识星球 的打卡和答疑还是让我既快慰又拜服的: (没想到咱们放假的状态也这么燃,可能个别人哪怕不放假也赶不上咱们吧,哈哈。) 春节期间每天都在打卡待业训练营 的寸铁同学太猛了,不仅打卡一天没中断,期间还问了我好几个很有含金量的问题。 大家能够围观一下 寸铁同学的每日打卡,灰常励志,灰常赞! (还没退出升职加薪星球的敌人,能够私信我领优惠券后再退出。) 元旦大元旦的还有人在退出我的星球,感激反对和信赖呀! 初一“阳哥经验丰富” 截图这位同学的执行力是真的好,给个大大的赞 初二春节期间咱们也在推动微服务实战我的项目的开发和学习 (微服务实战我的项目文章前面有具体介绍,感兴趣的敌人能够私信我详聊) 开始对接拼多多开放平台啦: 初三凌晨3点还在看我B站的视频教程学习,比我还“肝” 初四还有提前返校的同学,曾经从新进入战斗状态了: 初五新退出训练营的同学也开始了学习,开始做思维导图啦 初六学习,就是要有这种持之以恒的精力: 初七都快早晨11点,还在钻研容器: 初八咱们又从新梳理了一下“GoZero微服务实战我的项目”,解决了大家在假期学习和开发过程中碰到的问题。 我也和你再介绍一下这个我的项目: 我的项目特点以企业开发方式和企业我的项目规范带大家进行我的项目的开发,我的项目业务和服务拆分包含: 音讯服务抽奖服务订单服务商城服务上传服务微信服务问卷服务答题服务投票服务晒单服务领取服务用户服务根底服务登录服务我的项目简介整个我的项目应用了go-zero开发的微服务,根本蕴含了go-zero以及相干go-zero作者开发的一些中间件,所用到的技术栈根本是go-zero项目组的自研组件,根本是go-zero全家桶。 测试环境、线上部署应用支流的阿里云devops:流水线+docker+k8s搭建和部署。 我的项目技术栈Tips : 如果你不相熟这外面很多技术栈也不要怕,只有你会mysql、redis能够先启动这两个中间件在启动我的项目先跑起来我的项目,其余能够缓缓学。dockerk8s阿里云devops流水线go-zeronginx网关filebeatkafkago-stashelasticsearchkibanaprometheusgrafanajaegergo-queueasynqasynqmondtmdockerdocker-composemysqlredismoddjenkinsgitlabharbor动工啦,冲冲冲!不论春节放假有没有学习,明天动工都要给本人开个好头,和咱们一起冲冲冲! 如果你还没方法踏踏实实的进入工作状态,没方法踏踏虚浮的学进去,能够退出咱们 Go待业训练营 和 升职加薪常识星球。 当然,可欢送你在咱们交换群里唠一唠,分享分享新年的趣事,新年的指标。 或者私信我聊一聊,给你加油打气,聊聊将来! 新的一年,咱们一起冲鸭! 欢送关注 ❤我的文章都首发在同名公众号:王中阳Go 须要就业辅导或者简历优化,能够间接加我微信:wangzhongyang1993

February 18, 2024 · 1 min · jiezi

关于后端:糟糕被SimpleDateFormat坑到啦-京东云技术团队

1. 问题背景问题的背景是这样的,在最近需要开发中遇到须要将给定指标数据通过某一固定的计量规定进行过滤并打标生成明细数据,其中发现存在一笔指标数据的工夫在不合乎现有日期规定的条件下,还是通过了规定引擎的匹配打标操作。故而须要对该谬误匹配场景进行排查,定位其根本原因所在。 2. 排查思路2.1 数据定位在开始排查问题之初,先假设现有的Aviator规定引擎可能对现有的数据进行失常的匹配打标,查问在存在问题数据(图中红框所示)同一时刻进行规定匹配时的数据都有哪些。发现存在五笔数据在同一时刻进行规定匹配落库。 持续查问具体的匹配规定表达式,发现针对loanPayTime工夫区间在[2022-07-16 00:00:00, 2023-05-11 23:59:59]的范畴内进行匹配,指标数据的工夫为2023-09-19 11:27:29,实践上应该不会被匹配到。 然而观测匹配打标的明细数据发现的确打标胜利了(如红框所示)。 所以从新回到最后的和指标数据同时落库的五笔数据发现,这五笔数据的loanPayTime工夫的确在规定[2022-07-16 00:00:00, 2023-05-11 23:59:59]之内,所以在想有没有可能是在指标数据匹配规定引擎前,其它的五笔数据中的其中一笔对该数据进行了批改导致误匹配到了这个规定。顺着这个思路,首先须要确认下Aviator规定引擎在并发场景下是否线程平安的。 2.2 规定引擎因为在需要中应用到用于给数据匹配打标的是Aviator规定引擎,所以第一直觉是狐疑Aviator规定引擎在并发的场景中可能会存在线程不平安的状况。 首先简略介绍下Aviator规定引擎是什么,Aviator是一个高性能的、轻量级的java语言实现的表达式求值引擎,次要用于各种表达式的动静求值,相较于其它的开源可用的规定引擎而言,Aviator的设计指标是轻量级和高性能 ,相比于Groovy、JRuby的轻便,Aviator十分小,加上依赖包也才450K,不算依赖包的话只有70K; 当然,Aviator的语法是受限的,它不是一门残缺的语言,而只是语言的一小部分汇合。其次,Aviator的实现思路与其余轻量级的求值器很不雷同,其余求值器个别都是通过解释的形式运行,而Aviator则是间接将表达式编译成Java字节码,交给JVM去执行。简略来说,Aviator的定位是介于Groovy这样的重量级脚本语言和IKExpression这样的轻量级表达式引擎之间。(具体Aviator的相干介绍不是本文的重点,具体可参见) 通过查阅相干材料发现,Aviator中的AviatorEvaluator.execute() 办法自身是线程平安的,也就是说只有表达式执行逻辑和传入的env是线程平安的,实践上是不会呈现并发场景下线程不平安问题的。(详见) 2.3 匹配规定引擎的env 通过后面Aviator的相干材料发现传入的env如果在多线程场景下不平安也会导致最终的后果是谬误的,故而定位应用的env发现应用的是HashMap,该汇合类的确是线程不平安的(具体可详见),然而线程不平安的前提是多个线程同时对其进行批改,定位代码发现在每次调用形式时都会从新生成一个HashMap,故而应该不会是因为这个线程不安全类导致的。 持续定位发现,loanPayTime这个字段在进行Aviator规定引擎匹配前应用SimpleDateFormat进行了格式化,所以有可能是因为该类的线程不平安导致的数据错乱问题,然而这个类应该只是对日期进行格式化解决,难不成还能影响最终的数据。带着这个疑难查问材料发现,emm的确是线程不平安的。 好家伙,嫌疑对象目前曾经有了,当初就是寻找相干证据来佐证了。 3. SimpleDateFormat 还能线程不平安?3.1 先写个demo试试话不多说,间接去测试一下在并发场景下,SimpleDateFormat类会不会对须要格式化的日期进行错乱格式化。先模仿一个场景,对多线程并发场景下格式化日期,即在[0,9]的数据范畴内,在偶数状况下对2024年1月23日进行格式化,在奇数状况下对2024年1月22日进行格式化,而后观测日志打印成果。 import java.text.SimpleDateFormat;import java.time.Duration;import java.time.LocalDateTime;import java.util.Date;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.TimeUnit;public class ThreadSafeDateFormatDemo { static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); public static void main(String[] args) { ExecutorService executor = Executors.newFixedThreadPool(10); LocalDateTime startDateTime = LocalDateTime.now(); Date date = new Date(); for (int i = 0; i < 1000; i++) { int finalI = i; executor.submit(() -> { try { if (finalI % 2 == 0) { String formattedDate = dateFormat.format(date); //第一种// String formattedDate = DateUtil.formatDate(date); //第二种// String formattedDate = DateSyncUtil.formatDate(date); //第三种// String formattedDate = ThreadLocalDateUtil.formatDate(date); System.out.println("线程 " + Thread.currentThread().getName() + " 工夫为: " + formattedDate + " 偶数i:" + finalI); } else { Date now = new Date(); now.setTime(now.getTime() - TimeUnit.MILLISECONDS.convert(1, TimeUnit.DAYS)); String formattedDate = dateFormat.format(now); //第一种// String formattedDate = DateUtil.formatDate(now); //第二种// String formattedDate = DateSyncUtil.formatDate(now); //第三种// String formattedDate = ThreadLocalDateUtil.formatDate(now); System.out.println("线程 " + Thread.currentThread().getName() + " 工夫为: " + formattedDate + " 奇数i:" + finalI); } } catch (Exception e) { System.err.println("线程 " + Thread.currentThread().getName() + " 呈现了异样: " + e.getMessage()); } }); } executor.shutdown(); try { executor.awaitTermination(30, TimeUnit.SECONDS); } catch (InterruptedException e) { e.printStackTrace(); } // 计算总耗时 LocalDateTime endDateTime = LocalDateTime.now(); Duration duration = Duration.between(startDateTime, endDateTime); System.out.println("所有工作执行结束,总耗时: " + duration.toMillis() + " 毫秒"); }}具体demo代码如上所示,执行后果如下,实践上来说应该是2024年1月23日和2024年1月22日打印日志的次数各5次。理论后果发现在偶数的场景下依然会呈现打印格式化2024年1月22日的场景。显著呈现了数据错乱赋值的问题,所以到这里大略能够根本确定就是SimpleDateFormat类在并发场景下线程不平安导致的。 ...

February 18, 2024 · 3 min · jiezi

关于后端:122K-Star开箱即用后台管理系统

Hi,骚年,我是大 G,公众号「GitHub指北」会举荐 GitHub 上乏味有用的我的项目,一分钟 get 一个优良的开源我的项目,开掘开源的价值,欢送关注。 明天举荐一款开源收费且开箱即用的中后盾管理系统,齐全采纳 ECMAScript 模块(ESM)标准来编写和组织代码,应用了最新的 Vue3、Vite、Element-Plus、TypeScript、Pinia、Tailwindcss 等支流技术开发,兼容挪动端。 成果预览在线体验地址:https://yiming_chang.gitee.io/vue-pure-admin PC 端 挪动端 首页 流程编辑 文本编辑器 各种组件 源码地址在公众号「GitHub指北」后盾发消息「后盾零碎」即可获取。

February 17, 2024 · 1 min · jiezi

关于后端:OpenAI又出王炸Sora是否要开启视频AI新时代

OpenAI又出王炸,Sora是否要开启视频AI新时代?关注微信公众号 DeepGoAI前几天咱们还在探讨 如何让ChatGPT3.5变得更聪慧 明天OpenAI就带着新王炸呈现了 如同ChatGPT个别 在计算机领域掀起轩然大波 开启真正视频AI新时代 那就是 Sora 很多同学可能还不晓得Sora 它是由OpenAI公司推出的全新视频AI生成模型 相较于其余现有的AI生成视频存在的问题 Sora都提出了相应的优化降级 首先让咱们来看两个官网给出的视频片段 给定提醒内容:一位时尚女性走在充斥和煦霓虹灯和动画城市标牌的东京街道上。她衣着彩色皮夹克、红色长裙和彩色靴子,拎着彩色钱包。她戴着太阳镜,涂着红色口红。她走路自信又随便。街道湿润且反光,在黑白灯光的照耀下造成镜面成果。许多行人走来走去。 给定提醒内容:参观艺术画廊,外面有许多不同格调的漂亮艺术品。 Sora最显著的特点是基于自然语言生成的,用户只有给出根底的文本指令,形容出所须要的视觉场景,就能失去时长可达60秒的视频。不须要提供任何的视频或图片素材为根底,便能失去绝对晦涩、残缺、真切且不存在显著bug的视频。 隐隐感觉很多人在就业边缘 疯狂彷徨 然而Sora目前也仍存在一些不欠缺的中央,比方它没方法齐全理清故事的背景逻辑关系,一些细节的解决也还不到位,同时AI生成的一个重大问题也仍存在,那就是它无法控制主人公形象保持一致,可能呈现多个人物形象抵触的画面。 目前对于Sora的评估在网络上也出现显著的两极分化 有局部网友认为 Sora的推出 将以致许多视觉相干从业者就业 也将对视频AI畛域引起触动 对AIGC畛域倒退的速度 望洋兴叹 也有局部网友认为 Sora并没有传说中那么厉害 存在的问题不可胜数 AI想要取代人类工作还有很久 那你是怎么认为的呢? 小编认为 Sora的推出 的确对视频AI畛域带来了有限可能 对于集体和自媒体而言 Sora无异于最佳帮手 而对于视觉相干从业者 这也将是一个微小的挑战 让咱们一起期待 Sora带来的新倒退 Happy New Year! 欢送关注和分享 关注微信公众号 DeepGoAI本文由mdnice多平台公布

February 16, 2024 · 1 min · jiezi

关于后端:大厂的供应链采购系统设计

<article class=“article fmt article-content”><p><strong>关注我,紧跟本系列专栏文章,咱们下篇再续!</strong></p><blockquote><p>作者简介:魔都技术专家兼架构,多家大厂后端一线研发教训,各大技术社区头部专家博主,编程严选网创始人。具备丰盛的引领团队教训,深厚业务架构和解决方案的积攒。</p><p>负责:</p><ul><li>地方/分销预订零碎性能优化</li><li>流动&优惠券等营销中台建设</li><li><p>交易平台及数据中台等架构和开发设计</p><p>目前主攻升高软件复杂性设计、构建高可用零碎方向。</p></li></ul></blockquote><p>参考:</p><ul><li>编程严选网</li></ul><h2>0 前言</h2><p>公司倒退面临商业环境变动,如流量模式、竞争格局和公共卫生事件。洽购零碎作为供应端外围零碎之一,做好顶层设计并继续进行零碎演进,能力适应激烈的业务变动,服务好最终用户。本文从<strong>定义宏观</strong>、<strong>设计蓝图</strong>、<strong>落地零碎</strong>、<strong>继续演进</strong>开展整个洽购零碎架构过程,看业务零碎架构设计过程。</p><h2>1 定义宏观</h2><p></p><p>一直聚焦,推演洽购零碎的底层架构关键点。</p><h3>1.1 最大的变动和不变</h3><p>商业定位,确定架构底层逻辑:</p><ul><li>变动:企业面临商业环境变动及本身倒退诉求。企业商业定位面临调整,业务范围可能扩张或膨胀,业务模式可能微调或颠覆。架构重心产生极大变动,需提前布局调整,不然零碎和业务倒退间隙越大</li><li>不变:商业定位决定公司长期走向,商业定位一旦确立有长期稳定性,以一个明确定位来霸占用户心智,同时业务都围绕定位开展</li></ul><p>如定位平台模式和品牌模式的电商公司,业务特点和架构特点匹配如下:</p><table><thead><tr><th> </th><th>业务特点</th><th>架构特点</th></tr></thead><tbody><tr><td>平台模式(如:天猫)</td><td>撮合大量商家和消费者,关注交易量,关注GMV。入驻品牌多,品类广,更关注商品交易属性,根本不关注生产制作</td><td>起量快,得确保零碎设计易扩大,无论表拆分、机器扩容。营销玩法多变,为疾速响应业务,需灵便前台设计和松软中后盾</td></tr><tr><td>品牌模式(如:严选)</td><td>关注虔诚用户,关注利润率,以品为核,从设计制作环节抓起,到商品交付给用户,乃至售后都兼顾。但品类数量增长慢,资产重</td><td>需向多渠道铺货,业务前端要匹配各平台玩法。业务后端从商品企划到设计、生产、制作、运输、仓储的链条极长,流程联动,数据准确性保障都要思考。为匹配业务前端,往往要做渠道库存、渠道订单这样的形象设计</td></tr></tbody></table><h3>1.2 全链路视角:深度协同 &双向驱动</h3><ul><li><strong>商业链条极长</strong>,选品,洽购溯源,打算下单,合同签订,备料协同,生产制作,品质管控,物流运输,仓储治理,退供翻新,金融结算等环环相扣</li><li><strong>协同角色极多</strong>,从商品开发,洽购,打算,品控,关务,财务等密切合作</li><li><strong>档次盘根错节</strong>,从传统的供应链三流:实物流、信息流、资金流和商流,犬牙交错</li></ul><p><img src=“https://javaedge.oss-cn-shanghai.aliyuncs.com/773008fa5dd89f0f1bf266ffa8fe890f.webp" style=“zoom: 67%;” /></p><p>供应链业务和技术是互咬齿轮:</p><ul><li>后期业务驱动,大量场景需线上化,实现初期流程闭环和数据积攒</li><li>倒退肯定阶段,大量技术驱动场景,展示数智化特色,如服务供需平衡的销量预测、智能补货,服务库存均衡的洽购分仓、仓间调拨</li></ul><p>整体供应链洽购倒退是技术和业务双驱。架构设计过程,要认清以后零碎和业务的倒退阶段,均衡好以后诉求和将来倒退,做好业务撑持同时,开掘数智化机会,为变动留有余地同时回绝过渡设计。</p><h3>1.3 找准系统演进要害特色</h3><p>以准确性、可用性为基:</p><p><img src=“https://javaedge.oss-cn-shanghai.aliyuncs.com/1ee0e2ee7cf59c60f9a0fe82e2d9ccee.png" alt=“img” style=“zoom: 67%;” /></p><p>理清业务特点后,需圈出洽购零碎关注的技术特色及这些要害特色的演进指标:</p><ul><li>可用性。作为履约外围链路,多角色日常工作需频繁操作在线零碎,能全天候残缺为用户提供服务能力是根底和要害</li><li>准确性。业务链路长(从打算下单到洽购请款结算两头要经多个要害流程),业务完结周期长(短则几天,长则一年多),数据精确有很大挑战。又因洽购是要害的老本结算链路,所以对数据准确性有很高要求</li></ul><p>需进一步量化这些架构特色,用以察看和保证系统是向指标方向拉动。如关注服务可用性,可用在线率、故障率俩指标。指标构建落地要联合公司技术,若有SLA/SLO/SLI相干服务质量平台,可间接借力,把指标纳入架构察看大盘,而非反复构建。相似也可借力自动化测试平台,构建一些性能、安全性的架构特色的量化察看指标。</p><h2>2 设计蓝图</h2><p>确定阶段性指标架构。理清要害底层逻辑后,可开始确定阶段性指标架构蓝图。如RUP 4+1视图,本文谈如下视角</p><h3>2.1 限界高低图</h3><p>分治之基、扯皮之盾:</p><p></p><p><strong>分治,大零碎小做</strong>。洽购零碎蕴含跨境洽购、洽购执行、退供/翻新等大量业务,同时要和大量内部零碎如商品核心、供应商、财务等交互,这种业务场景多,和内部联动多的零碎,只有界定好内外部边界,能力将零碎和人员职责拆分到位。</p><p>零碎的服务化粒度可间接映射参考外部子域划分。如零碎大小适合,零碎负责人和零碎之间一对一配比最好。</p><h3>2.2 业务架构图</h3><p>业务场景和零碎能力平滑匹配:</p><p></p><p>业务架构图要将业务、零碎思考清,图要明确<strong>横向</strong>和<strong>纵向</strong>的用意。</p><h4>① 横向:表白业务流程</h4><ul><li>利益相关者:可通过用户利益关注点不同做用户群体划分,可通过角色来形象划分后的用户</li><li>横向业务闭环:业务最终必然服务用户,所有利益相关者的关注点应该在每个横向档次上失去承载和体现</li></ul><h4>② 纵向:表达能力分层</h4><ul><li>纵向关注拆解,从“业务愿景”一直拆解到一个个细小的‘业务能力’载体</li><li>分层,对拆解过程进行形象,演绎,提炼 4 层表白构造:场景层、产品性能层、零碎能力层、业务模型层</li></ul><p><strong>场景剖析是要害</strong>。业务架构产出靠不靠谱,其中一个因素就是业务域下的作为输出场景是否思考清晰,是否笼罩全面,即‘场景剖析’是否到位。该层是根底,至于分层业务架构产出,如L0,L1,L2层可在该根底做形象和结构化。</p><h2>3 落地零碎</h2><p>有档次,有节奏的构建零碎:</p><h3>3.1 一层:横向扩张</h3><p>以域为外围,打造零碎幅员:</p><p></p><p><strong>搭建业务和零碎大的框架结构,做业务域级别的笼罩和服务零碎级别的落地。</strong>供应链洽购作为绝对成熟的业务,可参考业务侧整体幅员来预判零碎状态。</p><p>而后联合以后零碎和业务现状,规划系统倒退门路。若新需要不在以后子域,可思考将新的零碎间接构建进去,承接这块业务需要,以满足将来倒退。若有板块内的要害子域落入其余板块,可边界治理,划回业务和零碎能力,划出不属于洽购零碎的,以保障布局整体性和零碎内聚。</p><h3>3.2 二层:垂直深挖</h3><p>精细化场景笼罩:</p><p><img src=“https://javaedge.oss-cn-shanghai.aliyuncs.com/image-20240215201024705.png" style=“zoom: 33%;” /></p><p><strong>多角度验证场景完整性,做场景级业务笼罩和零碎能力级别的补全。</strong>业务域初步搭建成型后,在撑持根本业务流程根底上,一直开掘用户在老本管制、提效、体验的深度诉求,迭代细分场景以丰盛零碎。如审批域:</p><ul><li>可提供专门服务紧急场景的紧急审批能力,除了几个要害节点审批,其余日常审批节点都绕过,极速实现审批</li><li>也可依据便携化审批诉求,提供挪动审批</li></ul><h3>3.3 三层:自动化 &数智化</h3><p>以后的终极阶段,需长期思考摸索。在精细化做了段时间后,零碎有肯定成熟度根底,团队也对业务有深刻了解,可开掘自动化&数智化机会。</p><p>如摸索个性化流程场景:为不同业务方个体搭建个性化洽购流程。要害思路,洽购是重流程零碎,而有些流程节点的设计是在危险管制和效率间博弈,如某些审批节点。而每个业务人员个体靠谱度不同,若能为某些靠谱业务人员跳过某些次要基于危险管制考量的节点,极大晋升流程效率。</p><h2>4 继续演进:动态平衡</h2><p><img src=“https://javaedge.oss-cn-shanghai.aliyuncs.com/942b46ec935ddecf9682d743735e5c84.webp" alt=“img” style=“zoom: 67%;” /></p><p>指标架构,只是某工夫对架构的现实状态的判断,当一些关键因素变动,指标架构需及时调整,而变动是继续的,所以指标架构其实也是间断变动的。当指标架构变动后,会开启新一轮定义、设计和落地,所以零碎能力和需要的匹配始终处于一个动态平衡中。如双十一阐明市场环境变动导致业务变动,而业务变动后零碎侧须要做出调整:</p><ul><li>市场变动:本年双十一销售顶峰除当天,还有‘11.1-11.3’,造成 2 个销售波峰,波峰之间有 7 天缓冲</li><li><p>业务变动:对洽购侧业务方,这市场变动,多‘一次复盘,一次补货’</p><ul><li>一次复盘:‘11.1-11.3’大促后,可疾速复盘下以后洽购量和指标偏差,调整要害数据如大促系数(大促期间比照平销期洽购量倍数)</li><li>一次补货:复盘后发现一些洽购量偏差、一些爆品缺货危险</li></ul></li><li>零碎变动:一波大促变两波,对流量、零碎容量需从新评估设计。可提供一些数据辅助决策工具帮忙业务疾速‘11.1-11.3’复盘,和‘11.11’洽购量从新预测。最初提供紧急补货工具,缩短洽购履约工夫,实现偏差洽购量补货</li></ul><h2>5 总结</h2><p>供应链这种B端系统门槛高,对架构师业务深度、技术深度提出双向要求,埋头做零碎可不行。将业务敏感度和架构方法论联合,用倒退动静眼光看,能力发现真正技术价值和业务价值。</p><blockquote>本文由博客一文多发平台 OpenWrite 公布!</blockquote></article>

February 15, 2024 · 1 min · jiezi

关于后端:正月初五迎财神

大家好,我是小悟 正月初五,人们在这一天迎接财神,期求财运亨通、事业顺利。依照风俗,家家户户都会燃放鞭炮、点灯笼、陈设祭品,以示虔诚。 晚上,太阳刚刚升起,大家便早早起床,开始筹备迎接财神的典礼。家庭主妇们忙着在厨房里烹制丰硕的祭品,如鱼、肉、蔬菜等,寓意五谷丰登、六畜兴旺。同时,还会在门口挂上红灯笼,象征着吉祥如意、红红火火。 鞭炮声此起彼伏,震耳欲聋。随着鞭炮声的响起,大家纷纷走出家门,手持香火,来到寺庙或家中设定的祭台前,虔诚地祷告。默默地期求财神保佑本人和家人财运亨通、事业顺利。在这一刻,心灵失去了污染,懊恼和发愁也被抛到了九霄云外。 除了燃放鞭炮和点灯笼外,还有一些中央会举办隆重的财神巡游流动。大家抬着财神像,敲锣打鼓,沿着街道巡游。沿途的人们纷纷驻足观看,为财神送上祝愿和贡品。这种流动不仅展现了中国文化的博大精深,也增强了人们之间的交换与互动。 商家也会在这一天举办各种流动,以期求生意兴隆。一些商家会在店门口燃放鞭炮,以驱走霉运,迎接财神。同时,商家还会邀请舞龙舞狮队来表演,以削减喜庆氛围。 除了传统的典礼和流动外,也通过一些新的形式来迎接财神。例如,一些人会抉择在这一天去银行办理贷款、理财等金融业务,以期求财运亨通。还有一些人会抉择在这一天进行投资或者守业,以期取得更多的财产和机会。 随着夜幕的来临,大家还会在自家的门前燃放烟花。五彩斑斓的烟花在夜空中绽开,犹如一朵朵盛开的花朵。在这一刻,心中充斥了喜悦和心愿。 迎财神的文化外延丰盛,除了对财产的谋求,还体现了大家对美好生活的向往和对传统的尊重。相互道贺新年发财,分享彼此的喜悦和祝愿。这种团结和互助的精力,也是迎财神文化的重要组成部分。 正月初五迎财神是中国传统文化的重要组成部分。它不仅是一种期求财产的传统典礼,更是一种凝聚人心的文化传承。通过这一天的流动,不仅表白了对财产的渴望和对美好生活的向往,更传递了团结、互助、友爱的精神力量。 您的一键三连,是我更新的最大能源,谢谢 山水有相逢,来日皆可期,谢谢浏览,咱们再会 我手中的金箍棒,上能通天,下能探海

February 14, 2024 · 1 min · jiezi

关于后端:EECS-370-C语言linker解答

Project 2 EECS 370 (Fall 2023)Worth: 100 Points Point AllocationAssigned: Saturday, September 16thPart 2A Due: 11:55 PM ET, Thursday, October 5th 40 PointsPart 2L Due: 11:55 PM ET, Thursday, October 26th 60 Points 0. Starter CodeFor Project 2A, the assembler, you have 2 choices: build off your project 1a assembler OR startwith the starter code, which will be updated after all project 1a submissions have been collected.For project 2L, the LC2K linker starter code is meant to help you read in and parse object files. Itis probably a good idea to break it up into different functions, but is a good place to get started. ...

September 28, 2023 · 8 min · jiezi

关于后端:Java如何解决浮点数计算不精确问题

有的时候博客内容会有变动,首发博客是最新的,其余博客地址可能会未同步,认准https://blog.zysicyj.top首发博客地址 面试题手册 系列文章地址 1. 什么是浮点数计算不准确问题?在 Java 中,浮点数计算不准确问题指的是应用浮点数进行运算时,因为浮点数的外部示意形式和十进制数的示意形式存在差别,导致计算结果可能呈现误差。这种误差次要是因为浮点数的二进制示意无奈精确地示意某些十进制小数。 2. 为什么须要解决浮点数计算不准确问题?浮点数计算不准确问题会影响到程序的计算结果的准确性。特地是在波及到金融、科学计算等畛域,对计算结果的精度要求较高的状况下,浮点数计算不准确问题就显得尤为重要。 3. Java 如何解决浮点数计算不准确问题?Java 提供了一些办法来解决浮点数计算不准确问题: 3.1 应用 BigDecimal 类BigDecimal 类是 Java 提供的用于解决任意精度的十进制数的类。它能够防止浮点数计算不准确问题,但相应地也减少了计算的复杂性。 import java.math.BigDecimal;public class BigDecimalExample { public static void main(String[] args) { BigDecimal num1 = new BigDecimal("0.1"); BigDecimal num2 = new BigDecimal("0.2"); BigDecimal sum = num1.add(num2); System.out.println(sum); // 输入 0.3 }}3.2 应用 DecimalFormat 类DecimalFormat 类是 Java 提供的用于格式化数字的类。通过指定适合的格局,能够将浮点数转换为字符串,并保留指定的小数位数。 import java.text.DecimalFormat;public class DecimalFormatExample { public static void main(String[] args) { double num1 = 0.1; double num2 = 0.2; double sum = num1 + num2; DecimalFormat df = new DecimalFormat("#0.00"); String formattedSum = df.format(sum); System.out.println(formattedSum); // 输入 0.30 }}4. 浮点数计算不准确问题的应用示例上面是一个简略的示例,演示了浮点数计算不准确问题以及如何应用 BigDecimal 来解决: ...

September 27, 2023 · 1 min · jiezi

关于后端:Java浮点运算为什么不精确

有的时候博客内容会有变动,首发博客是最新的,其余博客地址可能会未同步,认准https://blog.zysicyj.top首发博客地址 面试题手册 系列文章地址 1. 什么是 Java 浮点运算?在 Java 中,浮点运算指的是对浮点数进行加减乘除等根本运算操作。Java 提供了两种浮点类型:float 和 double。 2. 为什么 Java 浮点运算不准确?Java 浮点运算不准确次要是因为浮点数的外部示意形式以及计算机硬件的限度所导致的。 2.1 浮点数的外部示意浮点数在计算机中采纳二进制迷信计数法来示意,行将一个实数合成为尾数和指数两个局部,并应用无限位数的二进制数来近似示意。例如,0.1 无奈准确地用二进制示意,因而在计算机中会存在肯定的误差。 2.2 计算机硬件的限度计算机硬件对浮点数的存储和计算都有肯定的限度。通常状况下,计算机应用固定长度的字节来示意浮点数,如 32 位或 64 位。这就意味着浮点数的有效位数是无限的,超过该位数的局部会被截断或舍入,从而引入了误差。 另外,计算机解决浮点数时还须要进行舍入操作,以适应无限的存储空间。舍入操作会导致肯定的精度损失。 3. Java 浮点运算的实现原理Java 浮点数的外部示意采纳 IEEE 754 规范,该规范定义了浮点数的二进制格局以及根本运算规定。在进行浮点运算时,Java 会依照 IEEE 754 规范对浮点数进行解决。 具体来说,Java 应用有符号位、指数位和尾数位来示意浮点数。其中,指数位用于示意浮点数的数量级,尾数位用于示意浮点数的精度。通过调整指数位和尾数位的值,能够示意不同范畴和精度的浮点数。 在进行浮点运算时,Java 会依据运算符和操作数的类型抉择相应的运算规定。例如,加法运算会将两个浮点数的尾数对齐,并依据指数位的差别进行弥补,而后再进行相加。这样的解决形式能够保障运算后果的有效性和正确性。 4. Java 浮点运算的应用示例上面是一个简略的 Java 浮点运算示例: double a = 0.1;double b = 0.2;double c = a + b;System.out.println(c);输入后果为: 0.30000000000000004上述代码中,因为 0.1 和 0.2 无奈准确示意,所以在进行加法运算时会引入肯定的误差,导致最终后果不是 0.3。 5. Java 浮点运算的长处可能解决大范畴和高精度的数值计算需要。提供了标准化的浮点数示意形式和运算规定,保障了跨平台的兼容性。6. Java 浮点运算的毛病精度无限,可能存在舍入误差。对于要求准确计算的场景(如金融畛域),须要应用 BigDecimal 等其余数据类型来代替浮点数。7. Java 浮点运算的应用注意事项防止间接比拟浮点数是否相等,应该应用误差范畴判断。在波及到累加或累减操作时,尽量避免屡次运算,能够先将所有操作数累加或累减后再进行运算,以缩小舍入误差的积攒。8. 总结Java 浮点运算不准确次要是因为浮点数的外部示意形式以及计算机硬件的限度所导致的。尽管存在肯定的精度损失,但 Java 提供了标准化的浮点数示意形式和运算规定,可能满足大多数数值计算需要。在须要准确计算的场景下,能够应用 BigDecimal 等其余数据类型来代替浮点数。 ...

September 27, 2023 · 1 min · jiezi

关于后端:Java包装类与自动拆箱装箱

有的时候博客内容会有变动,首发博客是最新的,其余博客地址可能会未同步,认准https://blog.zysicyj.top首发博客地址 面试题手册 系列文章地址 1. 什么是 Java 包装类和主动拆箱装箱?Java 中的根本数据类型(如 int、char、boolean 等)是不具备面向对象个性的,不能直接参与面向对象的操作。为了解决这个问题,Java 提供了对应的包装类来将根本数据类型转换为对象。 Java 的包装类是一组用于封装根本数据类型的类,每种根本数据类型都有对应的包装类。例如,Integer 是 int 的包装类,Character 是 char 的包装类,Boolean 是 boolean 的包装类等。 主动拆箱和装箱是指在根本数据类型和其对应的包装类之间进行主动转换的过程。当须要应用包装类时,能够间接应用根本数据类型,而无需手动创立包装类对象;反之,当须要应用根本数据类型时,能够间接应用包装类对象,而无需手动进行类型转换。 2. 为什么须要 Java 包装类和主动拆箱装箱?Java 的包装类和主动拆箱装箱次要有以下几个起因: 面向对象:Java 是一门面向对象的编程语言,但根本数据类型不具备面向对象的个性。通过应用包装类,能够将根本数据类型转换为对象,从而使得根本数据类型也可能参加面向对象的操作。泛型反对:泛型只能应用援用类型,不能应用根本数据类型。通过应用包装类,能够将根本数据类型转换为对应的援用类型,从而在泛型中应用。汇合框架:Java 的汇合框架只能存储对象,不能间接存储根本数据类型。通过应用包装类,能够将根本数据类型转换为对应的对象,从而在汇合中存储。3. Java 包装类和主动拆箱装箱的实现原理?Java 的包装类是通过封装根本数据类型的值来实现的。每个包装类都有一个与之对应的构造方法,用于创立包装类对象,并将根本数据类型的值传递给该构造方法。 主动拆箱和装箱是由编译器在编译时进行的操作。当须要将根本数据类型赋值给包装类对象时,编译器会主动调用对应的构造方法创立包装类对象;反之,当须要将包装类对象赋值给根本数据类型时,编译器会主动调用包装类的xxxValue()办法获取根本数据类型的值。 例如,以下代码演示了主动装箱和拆箱的过程: int num = 10; // 主动装箱,将int类型的值赋值给Integer对象Integer obj = num;int result = obj + 5; // 主动拆箱,将Integer对象的值赋值给int类型的变量4. Java 包装类和主动拆箱装箱的应用示例以下是 Java 包装类和主动拆箱装箱的一些应用示例: // 主动装箱Integer num1 = 10;Double num2 = 3.14;// 手动装箱Integer num3 = new Integer(20);Double num4 = new Double(5.6);// 主动拆箱int result1 = num1 + 5;double result2 = num2 - 2.0;// 手动拆箱int result3 = num3.intValue() * 2;double result4 = num4.doubleValue() / 2.0;5. Java 包装类和主动拆箱装箱的长处提供了根本数据类型与对象之间的转换,使得根本数据类型也可能参加面向对象的操作。反对泛型,使得能够在泛型中应用根本数据类型。不便汇合框架的应用,能够将根本数据类型转换为对应的对象进行存储。6. Java 包装类和主动拆箱装箱的毛病包装类占用更多的内存空间,因为每个包装类都须要额定的对象头和实例变量来保留值。包装类的创立和销毁会产生额定的开销,影响性能。主动拆箱和装箱可能导致一些隐式的类型转换谬误,须要留神类型匹配的问题。7. Java 包装类和主动拆箱装箱的应用注意事项在进行包装类与根本数据类型之间的比拟时,该当应用equals()办法而不是==运算符。在进行包装类与根本数据类型之间的赋值时,要留神类型匹配的问题,避免出现隐式的类型转换谬误。留神包装类对象的空指针问题,防止在空对象上调用办法导致空指针异样。8. 总结Java 的包装类和主动拆箱装箱提供了根本数据类型与对象之间的转换性能,使得根本数据类型也可能参加面向对象的操作。通过主动拆箱和装箱,能够不便地在根本数据类型和包装类之间进行转换,并反对泛型和汇合框架的应用。然而,包装类占用更多内存并且可能影响性能,须要留神类型匹配和空指针等问题。 ...

September 27, 2023 · 1 min · jiezi

关于后端:面试题精讲Java包装类缓存机制

有的时候博客内容会有变动,首发博客是最新的,其余博客地址可能会未同步,认准https://blog.zysicyj.top首发博客地址 面试题手册 系列文章地址 1. 什么是 Java 包装类缓存机制?Java 中的包装类(Wrapper Class)是为了将根本数据类型转换为对象而存在的。在 Java 中,每个根本数据类型都有对应的包装类,如 Integer、Double 等。 Java 包装类缓存机制指的是,在某些状况下,Java 会对肯定范畴内的包装类对象进行缓存,以进步性能和节俭内存空间。 2. 为什么须要 Java 包装类缓存机制?应用包装类能够使根本数据类型具备面向对象的个性,同时也不便了在汇合类中存储根本数据类型。然而,因为包装类是对象,相比于根本数据类型,它们占用更多的内存空间。 为了解决这个问题,Java 引入了包装类缓存机制,通过缓存肯定范畴内的包装类对象,缩小反复创建对象的开销,从而进步性能和节俭内存空间。 3. Java 包装类缓存机制的实现原理Java 包装类缓存机制是通过动态成员变量来实现的。在 Integer、Long、Short、Byte、Character 这五个包装类中,定义了一个动态数组 cache[],用于缓存罕用的数值。 Integer 类:默认缓存了-128 到 127 之间的整数。Long 类:默认缓存了-128 到 127 之间的长整数。Short 类:默认缓存了-128 到 127 之间的短整数。Byte 类:默认缓存了-128 到 127 之间的字节。Character 类:默认缓存了 0 到 127 之间的字符。当应用 valueOf()办法创立包装类对象时,会先查看该值是否在缓存范畴内。如果是,则间接返回缓存中的对象;否则,创立一个新的对象并放入缓存中。 4. Java 包装类缓存机制的应用示例Integer a = Integer.valueOf(100); // 缓存中不存在,创立新对象Integer b = Integer.valueOf(100); // 缓存中存在,间接返回缓存对象System.out.println(a == b); // 输入true,示意a和b援用同一个对象上述示例中,通过调用Integer.valueOf()办法创立两个 Integer 对象。因为 100 在缓存范畴内,第二次创立时间接返回了缓存中的对象,所以 a 和 b 援用同一个对象,输入后果为 true。 ...

September 27, 2023 · 1 min · jiezi

关于后端:面试题精讲Java中有哪些基础类型

有的时候博客内容会有变动,首发博客是最新的,其余博客地址可能会未同步,认准https://blog.zysicyj.top首发博客地址 面试题手册 系列文章地址 Java 中有以下根底类型: 整数类型:byte、short、int、long。它们别离示意不同范畴的整数值,占用的内存空间也不同。浮点类型:float、double。它们用于示意带小数局部的数字,其中 double 精度更高。字符类型:char。它用于示意单个字符,例如字母、数字或符号。布尔类型:boolean。它只有两个取值 true 和 false,用于示意逻辑值。这些根底类型在 Java 中是间接反对的,能够间接应用,无需导入其余包。每种根底类型都有对应的默认值,如果没有显式赋值,则会被初始化为其默认值。 为什么须要根底类型?根底类型是编程语言中最根本的数据类型,用于存储和操作各种数据。它们提供了一种简略而无效的形式来解决常见的数据类型,如整数、浮点数、字符和布尔值。应用根底类型能够节俭内存空间,并且执行速度较快。 根底类型的实现原理根底类型在 Java 虚拟机中以二进制模式进行存储和计算。每种根底类型都有固定的位数和范畴,依据不同的类型,采纳不同的编码方式。例如,整数类型应用补码示意,浮点类型应用 IEEE 754 规范进行编码。 根底类型的应用示例以下是根底类型的一些应用示例: int age = 25;double salary = 5000.50;char grade = 'A';boolean isStudent = true;在下面的示例中,咱们定义了一个整数变量age,一个浮点数变量salary,一个字符变量grade和一个布尔变量isStudent。能够依据须要对这些变量进行赋值和操作。 根底类型的长处效率高:根底类型间接存储数据的二进制示意模式,不须要额定的内存空间和计算开销。占用内存少:根底类型在内存中占用的空间较小,节俭内存资源。简略易用:根底类型提供了一种简略而直观的形式来解决常见的数据类型。根底类型的毛病精度无限:因为根底类型的位数和范畴是固定的,因而可能无奈满足某些非凡需要,如大数字计算或高精度计算。不反对面向对象个性:根底类型不能直接参与面向对象的操作,如继承、多态等。根底类型的应用注意事项防止不必要的类型转换:在进行根底类型之间的运算或赋值时,须要留神数据类型的匹配和范畴是否正当。审慎解决精度问题:浮点类型存在精度损失的问题,对于波及到准确计算的场景,应该应用 BigDecimal 等类来解决。总结:Java 中有 byte、short、int、long、float、double、char 和 boolean 这些根底类型。它们提供了一种简略而高效的形式来解决常见的数据类型,并且占用内存较少。然而根底类型的精度无限,不能直接参与面向对象的操作。在应用根底类型时,须要留神类型转换和精度问题。 <!-- md tj.md --> 本文由mdnice多平台公布

September 27, 2023 · 1 min · jiezi

关于后端:面试题精讲continuebreak和return的区别是什么

有的时候博客内容会有变动,首发博客是最新的,其余博客地址可能会未同步,认准https://blog.zysicyj.top首发博客地址 面试题手册 系列文章地址 continue、break 和 return 是在编程中罕用的控制流语句,它们有不同的作用和应用场景。 continue:当程序执行到 continue 语句时,会跳过以后循环中残余的代码,并开始下一次循环。通常用于在循环中遇到某些条件时,跳过以后迭代,间接进入下一次迭代。 例如,在一个 for 循环中,如果须要跳过某些特定的值,能够应用 continue 语句: for (int i = 0; i < 10; i++) { if (i == 5) { continue; } System.out.println(i);}输入后果为:0 1 2 3 4 6 7 8 9 break:当程序执行到 break 语句时,会立刻终止以后所在的循环或者 switch 语句,并跳出该构造体内部的代码块。通常用于在满足某个条件时,提前结束循环或者跳出 switch 语句。 例如,在一个 while 循环中,当满足某个条件时,能够应用 break 语句来终止循环: int i = 0;while (true) { if (i == 5) { break; } System.out.println(i); i++;}输入后果为:0 1 2 3 4 ...

September 27, 2023 · 1 min · jiezi

关于后端:面试题精讲Java自增自减运算符

有的时候博客内容会有变动,首发博客是最新的,其余博客地址可能会未同步,认准https://blog.zysicyj.top首发博客地址 面试题手册 系列文章地址 1. 什么是自增自减运算符?自增自减运算符是一种用于对变量进行加 1 或减 1 操作的非凡运算符。在大多数编程语言中,自增运算符示意将变量的值减少 1,而自减运算符示意将变量的值缩小 1。 在 Java 中,自增自减运算符有两种模式: 前缀模式:++i 或 --i后缀模式:i++ 或 i--其中,前缀模式会先执行自增或自减操作,而后返回后果;后缀模式会先返回原始值,而后再执行自增或自减操作。 2. 为什么须要自增自减运算符?自增自减运算符能够不便地对变量进行加 1 或减 1 操作,罕用于循环、计数器和条件判断等场景。应用自增自减运算符能够简化代码,并进步代码的可读性和易维护性。 3. 自增自减运算符的实现原理?自增自减运算符的实现原理与编程语言相干。在大多数编程语言中,自增自减运算符都是通过批改变量的值来实现的。 以 Java 为例,当应用自增自减运算符时,编译器会生成相应的字节码指令来执行操作。对于前缀模式的自增自减运算符,编译器会先将变量的值加 1 或减 1,而后再返回后果;对于后缀模式的自增自减运算符,编译器会先返回原始值,而后再将变量的值加 1 或减 1。 4. 自增自减运算符的应用示例上面是 Java 中自增自减运算符的应用示例: int i = 0;System.out.println(++i); // 输入: 1System.out.println(i++); // 输入: 1System.out.println(i); // 输入: 2在上述示例中,首先定义了一个整型变量i并初始化为 0。而后通过前缀模式的自增运算符将i的值加 1,并输入后果为 1。接着通过后缀模式的自增运算符将i的值再次加 1,并输入后果为 1(留神此时输入的是原始值)。最初输入i的值为 2。 5. 自增自减运算符的长处简化代码:应用自增自减运算符能够简化对变量进行加 1 或减 1 操作的代码。进步可读性:自增自减运算符可能更清晰地表白对变量的递增或递加操作,进步代码的可读性。6. 自增自减运算符的毛病容易引起误会:自增自减运算符的应用可能会导致代码逻辑不清晰,特地是在简单的表达式中。可能影响性能:某些编程语言对于自增自减运算符的实现可能存在性能问题,尤其是在循环中频繁应用时。7. 自增自减运算符的应用注意事项防止适度应用:尽管自增自减运算符能够简化代码,但适度应用可能会升高代码的可读性和维护性。应该依据具体情况审慎抉择是否应用自增自减运算符。留神前缀与后缀模式的区别:前缀模式的自增自减运算符会先执行操作再返回后果,而后缀模式则相同。在应用时要留神这种差别,以防止产生意外的后果。8. 总结自增自减运算符是一种用于对变量进行加 1 或减 1 操作的非凡运算符。它能够简化代码,并进步代码的可读性和易维护性。在应用自增自减运算符时,须要留神前缀与后缀模式的区别,以及防止适度应用。 ...

September 27, 2023 · 1 min · jiezi

关于后端:面试题精讲Java移位运算符

有的时候博客内容会有变动,首发博客是最新的,其余博客地址可能会未同步,认准https://blog.zysicyj.top首发博客地址 面试题手册 系列文章地址 1. 什么是移位运算符?在 Java 中,移位运算符用于对二进制数进行位移操作。它们能够将一个数的所有位向左或向右挪动指定的位数。 Java 提供了三种移位运算符: 左移运算符(<<):将一个数的所有位向左挪动指定的位数,并在低位补 0。右移运算符(>>):将一个数的所有位向右挪动指定的位数,并依据原来最高位的值,在高位补上雷同的值。无符号右移运算符(>>>):将一个数的所有位向右挪动指定的位数,并在高位补 0。2. 为什么须要移位运算符?移位运算符次要用于解决二进制数据和优化某些计算过程。它们能够疾速地进行乘法、除法和取模等运算,同时也能够用于位掩码和位标记的设置与革除。 3. 移位运算符的实现原理移位运算符的实现原理是基于二进制数的位操作。具体来说,左移运算符(<<)将一个数的所有位向左挪动指定的位数,右移运算符(>>)将一个数的所有位向右挪动指定的位数,并依据原来最高位的值,在高位补上雷同的值,无符号右移运算符(>>>)将一个数的所有位向右挪动指定的位数,并在高位补 0。 4. 移位运算符的应用示例上面是一些移位运算符的应用示例: int a = 10; // 二进制示意为 00001010// 左移运算符(<<)int b = a << 2; // 后果为 40,二进制示意为 00101000// 右移运算符(>>)int c = a >> 1; // 后果为 5,二进制示意为 00000101// 无符号右移运算符(>>>)int d = a >>> 3; // 后果为 1,二进制示意为 000000015. 移位运算符的长处移位运算符具备以下长处: 疾速进行乘法、除法和取模等运算。能够用于位掩码和位标记的设置与革除。在某些状况下能够进步代码的性能和效率。6. 移位运算符的毛病移位运算符的毛病次要包含: 容易引起谬误,特地是对正数进行右移操作时可能会导致意外后果。不够直观,须要了解二进制数的位操作规定能力正确应用。7. 移位运算符的应用注意事项在应用移位运算符时,须要留神以下事项: 对于有符号的整数类型(如 int),右移运算符(>>)会保留原来最高位的值,并在高位补上雷同的值。而无符号右移运算符(>>>)则会在高位补 0。移位操作可能导致溢出或失落精度,特地是当挪动的位数超过了数据类型的范畴时。在进行位掩码和位标记的设置与革除时,须要应用适当的移位运算符和位操作技巧。8. 总结移位运算符是 Java 中用于对二进制数进行位移操作的工具。它们能够将一个数的所有位向左或向右挪动指定的位数,并依据规定在低位或高位补上相应的值。移位运算符次要用于解决二进制数据和优化某些计算过程,但在应用时须要留神溢出、精度失落和位操作等问题。 <!-- md tj.md --> ...

September 27, 2023 · 1 min · jiezi

关于后端:Goland中的一些tips

1. control+tab 疾速切换/抉择文件 command+E,疾速抉择最近编辑的文件 2.插件 插件 Presentation Assistant 能够显示每个快捷键操作. 如果用Win,在应用某快捷键时,能够显示在Mac上对应的快捷键; 反之亦然. 3.F1 输出一段字符串, 当呈现多个各种package里的函数, 呈现好多种抉择时,能够应用F1查看具体内容,会新开一个小窗口. 4.有用更多可视空间 左下角的按钮,能够收起侧边栏和底边栏的各种工具按两次command+1,收起左侧我的项目文件区域演示模式:会全屏且使字体十分大免打搅模式:会只剩下代码 5.智能的补齐举荐 补齐举荐是依照光标所在的地位,而不是以后打出的字符 6.error.nn疾速打出判断是否为nil的区块 在一个error类型的变量后用.nn,能够疾速打出如下判断块. if error != nil { }输出error.panic,会主动变为panic(err) 7.command+R 8.show intention action快捷键为Enter 9.查找帮忙 或者按两下 shift,进行(万能)搜寻 10.疾速重构 选中某段代码,control+T,选method,会新生成一个办法,并把选中的代码移动过来.. 之后批改某些变量,抉择第二项,也十分有用 11.y 选中某段代码,control+T,选method,会新生成一个办法,并把选中的代码移动过来.. 之后批改某些变量,抉择第二项,也十分有用 本文由mdnice多平台公布

September 27, 2023 · 1 min · jiezi

关于后端:听GPT-讲gotext源代码internal2

File: text/internal/language/compact/gen_parents.go在Go的text我的项目中,text/internal/language/compact/gen_parents.go文件的作用是生成语言树中每个节点的父节点。 具体介绍如下: 该文件是text包中解决自然语言的一个外部包,用于压缩和解析语言标签的数据结构。gen_parents.go文件是用于生成语言树(Language tree)中每个节点的父节点。 语言树是一个有向无环图,用于示意不同语言和其子语言之间的关系。每个节点代表一个语言标签,例如"en"代表英语。而父节点则代表该语言标签的间接父级语言。 gen_parents.go文件中的main函数用于生成语言树中每个节点的父节点。具体的实现形式如下: main函数首先定义了一个数据结构lang,用于存储每个语言标签及其对应的父节点。接下来,应用lang.add函数,将须要生成父节点的语言标签作为参数传入。add函数会依照语言树的定义,为该语言标签生成相应的父节点。在main函数的开端,依据lang数据结构中的内容,生成父节点并输入。main函数中的几个辅助函数的作用如下: expand函数用于将语言标签进行拆分,并返回语言标签中的第二个元素。languageParent函数依据语言标签的定义,返回该语言标签的间接父级语言。normalize函数用于规范化父节点的示意形式。writeCompact函数用于将父节点信息写入文件。总结起来,gen_parents.go文件的作用是生成语言树中每个节点的父节点,以辅助text我的项目中自然语言的解决和压缩。文件中的main函数及其辅助函数用于实现这一目标,包含获取语言标签的父节点、拆分语言标签、规范化父节点示意形式、以及将父节点信息写入文件。 File: text/internal/language/compact.gotext/internal/language/compact.go文件是Go的text我的项目中的一个外部语言包文件,它提供了一种压缩的形式来存储和检索语言数据,以实现更高效的文本处理。 CompactCoreInfo构造体是压缩语言数据的外围信息,它蕴含了语言数据的元信息,如语言ID、版本、最小代码点和最大代码点。这些信息用来描述语言数据的范畴和特色。 GetCompactCore函数用于获取给定语言的压缩外围数据信息。它接管一个语言ID作为输出参数,并返回一个CompactCoreInfo构造体,其中蕴含了该语言的压缩外围信息。 Tag函数用于获取给定代码点的语言数据标签。它接管一个代码点和语言ID作为输出参数,并返回一个示意该代码点在给定语言中的标签。这个标签能够表白出字符的语言特色,如大小写、字母、数字等。 总之,text/internal/language/compact.go文件中的CompactCoreInfo构造体和相干函数次要用于压缩语言数据的存储和检索,通过无效地存储语言信息和字符标签,实现了高效的文本处理。 File: text/internal/language/language.go在Go的text我的项目中,text/internal/language/language.go文件是一个外部包,定义了语言和地区标签的解析和处理函数。 errPrivateUse、errInvalidArguments、errNoTLD是在该文件中定义的谬误变量。errPrivateUse示意应用了公有用处的标签,errInvalidArguments示意参数有效,errNoTLD示意没有顶级域名。 Tag是一个代表语言标签的构造体,蕴含根本子标签和可选的扩大标签和变体标签。 Variant是一个代表变体标签的构造体,记录变体的标识符。 Make函数用于依据指定的语言和地区信息创立一个Tag对象,并验证其合法性。 Raw函数将Tag示意为原始字符串。 equalTags函数比拟两个Tag对象是否相等。 IsRoot函数判断一个Tag是否是根标签。 IsPrivateUse函数判断一个Tag是否是公有用处标签。 RemakeString函数依据给定的原始字符串重建一个Tag对象。 genCoreBytes函数生成一组外围字节。 String函数返回Tag对象的字符串示意。 MarshalText函数将Tag对象编码为文本格式。 UnmarshalText函数将文本格式的Tag解码为Tag对象。 Variants函数返回Tag对象的变体标签列表。 VariantOrPrivateUseTags函数返回Tag对象的变体标签和公有用处标签列表。 HasString函数查看一个Tag对象是否有字符串示意。 Parent函数返回Tag对象的父标签。 ParseExtension函数解析Tag对象中的扩大标签。 HasVariants函数查看Tag对象是否具备变体标签。 HasExtensions函数查看Tag对象是否具备扩大标签。 Extension函数返回指定键的扩大标签。 Extensions函数返回Tag对象的扩大标签列表。 TypeForKey函数返回指定键的语言标签。 SetTypeForKey函数为指定的键设置语言标签。 findTypeForKey函数依据键查找相应的语言标签。 ParseBase函数解析Tag对象中的根本子标签。 ParseScript函数解析Tag对象中的脚本标签。 EncodeM49函数将Tag对象编码为M49格局。 ParseRegion函数解析Tag对象中的地区标签。 IsCountry函数查看Tag对象是否示意国家。 IsGroup函数查看Tag对象是否示意地区群组。 Contains函数查看一个Tag对象是否蕴含另一个Tag对象。 TLD函数返回Tag对象的顶级域名标签。 Canonicalize函数对Tag对象进行规范化。 ParseVariant函数解析Tag对象中的变体标签。 File: text/internal/language/compact/parents.gotext/internal/language/compact/parents.go是Go语言规范库中text包的外部语言压缩组件的父节点映射文件。该文件的作用是定义了一种压缩语言模式的构造,用于示意语言的压缩模式。 其中,parents这几个变量具备以下作用: parents变量是一个映射,它示意了各个语言的父节点。每个语言都有一个惟一的父节点,示意该语言的间接下级语言。这种关系的定义有助于组织和了解不同语言之间的关系。parentsByType变量是一个映射,它示意依据语言类型来查找父节点的关系。每个语言类型都与其父节点类型相关联,这样能够依据语言类型查找对应的间接下级语言类型。dist15Parents变量是一个映射,它用于示意语言在Unicode 15.0版本中的父节点。Unicode是一种国内字符编码标准,因而在text包中,通过这个映射来解决字符的父节点关系。具体来说,parents变量是一个"Map[int]compact.LanguageID"类型的映射,键是一个整数,示意语言的编码,值是compact.LanguageID,示意语言的标识符。 parentsByType变量是一个"map[compact.LanguageType]compact.LanguageType"类型的映射,键是compact.LanguageType,示意语言的类型,值也是compact.LanguageType,示意间接下级语言的类型。 dist15Parents变量是一个"compact.UnicodeVersion15Parents"类型的映射,用于示意Unicode 15.0版本中语言之间的父节点关系。 总之,parents变量及其相干变量在Go的text我的项目中,用于定义语言压缩模式中的父节点关系,有助于组织和治理不同语言之间的档次关系。 File: text/language/parse.gotext/language/parse.go是Go的text我的项目中的一个文件,它定义了语言标签的解析器和一些相干的函数和构造体。 errInvalidArgument、errInvalidWeight、errTagListTooLarge、acceptFallback是在解析器中用于示意不同谬误状况的变量: errInvalidArgument用于示意有效的参数谬误。errInvalidWeight用于示意有效的权重谬误。errTagListTooLarge用于示意标签列表过大的谬误。acceptFallback用于示意在没有找到匹配的语言标签时,是否容许应用默认的语言标签作为回退。ValueError是一个构造体,用于示意谬误的值。tagSort是一个构造体,用于依照特定规定对语言标签进行排序。 Parse函数依据给定的字符串解析为语言标签。Compose函数用于将语言标签的表达形式合并为一个字符串。Update函数用于更新Accept-Language标头中的语言标签列表。ParseAcceptLanguage函数用于解析Accept-Language标头中的语言标签列表。consume函数用于从字符串中生产解析的标签。split函数用于将字符串依照特定的分隔符宰割成多个子字符串。Len、Less、Swap函数是用于实现tagSort构造体的sort.Interface接口的办法,用于排序语言标签。 以上是text/language/parse.go文件中的一些要害函数和构造体的作用介绍。 File: text/internal/language/compose.gotext/internal/language/compose.go文件是Go语言中text包中的一个外部文件,属于语言合成(language compose)的功能模块。它的作用是提供文本合成的相干函数和构造体,以及一些辅助的办法。次要用于合成多语言环境下的文本。 ...

September 27, 2023 · 2 min · jiezi

关于后端:听GPT-讲gotext源代码internal1

File: text/internal/cldrtree/testdata/test2/output.go在Go的text我的项目中,text/internal/cldrtree/testdata/test2/output.go 文件的作用是生成用于测试的输入数据。 在该文件中,以下变量和构造体起到了不同的作用: tree:示意一个CLDRTree对象,用于存储CLDR树的构造。locales:示意一个LocaleSet对象,用于存储反对的语言区域设置。indices:示意一个Indices对象,用于存储索引的信息。buckets:示意一个BucketSet对象,用于存储数据的桶汇合。bucket0:示意一个Bucket对象,是数据桶的一部分。bucket1:示意另一个Bucket对象,也是数据桶的一部分。enumMap:示意一个EnumMap对象,用于存储枚举类型的映射关系。这些变量和构造体是生成测试数据所必须的组成部分。它们通过应用不同的数据结构和算法来存储和示意测试数据,以满足测试需要。 至于具体的构造体的作用,能够通过查看代码来理解更多细节。各个构造体可能示意不同的数据类型,例如:width可能示意文本的宽度,context可能示意文本的上下文信息,month可能示意月份,cycleType可能示意周期类型,relative可能示意相对性的信息等。具体的性能和用处须要依据具体代码和上下文进行进一步剖析。 File: text/internal/cldrtree/tree.go在Go的text我的项目中,text/internal/cldrtree/tree.go文件的作用是用于实现CLDR(Common Locale Data Repository)树的性能,该树用于反对国际化和本地化的文本处理。 以下是对Tree和indexBuilder构造体的介绍: Tree构造体是CLDR树的次要构造,它蕴含了一个树节点(node),并提供了一系列公共办法用于查找和增加数据。 indexBuilder构造体是用于构建索引的辅助构造,它蕴含了一些辅助变量和办法,用于在构建树的过程中生成索引和记录节点的层级关系。 以下是对Lookup、LookupFeature、lookup、build和add函数的介绍: Lookup函数是用于在CLDR树中查找给定关键字的数据。它承受一个关键字参数,并返回一个LookupResult构造体,其中蕴含了与关键字匹配的数据信息。 LookupFeature函数用于解析和解决CLDR树中的个性(features)。它承受一个个性参数,并返回一个featureSet构造体,其中蕴含了与个性匹配的数据信息。 lookup函数是一个公有函数,用于实现查找性能。它承受一个节点和一个关键字参数,并递归查找与关键字匹配的数据。 build函数是用于构建CLDR树的入口函数。它承受一个已解析的CLDR数据,并通过调用indexBuilder的办法来构建树和生成索引。 add函数用于向CLDR树中增加节点和数据。它承受一个节点参数,并依据节点的的层级关系和父节点来增加节点到树中。 总的来说,text/internal/cldrtree/tree.go文件中的构造体和函数实现了CLDR树的构建、索引和查找性能,用于反对文本国际化和本地化解决的需要。 File: text/internal/cldrtree/cldrtree.go文件cldrtree.go位于text/internal/cldrtree包中,是Go的text我的项目中用于解决CLDR(Unicode Common Locale Data Repository)树的文件。 CLDR是一个公共的语言和区域设置数据存储库,蕴含了各种语言文本和相干元数据。cldrtree.go文件的次要作用是构建并操作CLDR树的数据结构。 上面对文件中提到的变量和构造体以及函数进行具体介绍: 变量aliasRe:这个变量是一个正则表达式,用于匹配CLDR树中的别名节点。别名节点是指一个节点能够作为另一个节点的别名,用于指向同一个值。构造体Builder:这个构造体是CLDR树的构建器,用于构建CLDR树。它蕴含了一个stringInfo字典,用于存储字符串类型的CLDR节点。构造体stringInfo:这个构造体示意一个字符串类型的CLDR节点,蕴含了locale、Index和keyValue等字段。它用于存储CLDR树中的字符串节点的信息。构造体locale:这个构造体示意一个区域设置,用于标识语言和地区。它蕴含了语言码、脚本码、国家码等字段,用于惟一标识一个区域设置。构造体Index:这个构造体示意CLDR树的索引节点,用于存储索引节点的信息。构造体keyValue:这个构造体示意一个键值对,用于存储CLDR树中的键值节点的信息。构造体Element:这个构造体示意一个CLDR树的节点,蕴含了NodeType、Value、SubTags和Elements等字段。它用于示意一个CLDR树的节点。函数setError(error):这个函数用于设置错误信息。函数addString(key []byte, value string):这个函数用于向Builder中的stringInfo字典中增加一个字符串类型的CLDR节点。函数addStringToBucket(bucket map[string]string, key string, value string): 这个函数用于将一个键值对增加到指定的bucket中,用于存储CLDR树中的键值节点。函数makeString(node *Element) string: 这个函数用于依据给定的CLDR树节点生成对应的字符串。函数New() *Builder: 这个函数用于创立一个新的CLDR树构建器。函数Gen(testDataPath string, targetDir string) error: 这个函数用于生成CLDR树数据的测试文件,输入到目标目录中。函数GenTestData() error: 这个函数用于生成CLDR树数据的测试文件。函数Locale(lang, script, region string) *locale: 这个函数用于依据给定的语言码、脚本码和国家码创立一个区域设置对象。函数Index(typ, name string) *Index: 这个函数用于依据给定的类型和名称创立一个索引节点对象。函数IndexWithName(typ, name string, keys ...string) *Index: 这个函数用于依据给定的类型、名称和键创立一个索引节点对象。函数IndexFromType(typ string) *Index: 这个函数用于依据给定的类型创立一个索引节点对象。函数IndexFromAlt(typ, name string) *Index: 这个函数用于依据给定的类型和名称创立一个索引节点对象,并且设置其为"alt"类型。函数subIndexForKey(key string) (string, string): 这个函数用于依据给定的键,返回子索引的类型和名称。函数SetValue(node *Element, value string): 这个函数用于为给定的CLDR树节点设置值。函数setValue(node *Element, key []byte, value string): 这个函数用于给指定的CLDR树节点的子节点设置键值对。File: text/internal/cldrtree/type.go在Go的text我的项目中,text/internal/cldrtree/type.go文件的作用是定义国际化数据的类型和构造。 ...

September 27, 2023 · 2 min · jiezi

关于后端:听GPT-讲gotext源代码collate

File: text/feature/plural/tables.go在Go的text我的项目中,text/feature/plural/tables.go文件是一个蕴含了复数规定和索引的数据表文件。该文件定义了用于确定给定语言中的复数模式的规定和索引。 具体而言,该文件的作用是为文本处理提供针对不同语言的复数模式的规定和信息,使文本在处理过程中可能正确处理不同语言的复数。它包含了两个次要局部:ordinal(序数)和cardinal(基数)。 在该文件中,以下变量具备以下作用: ordinalRules: 该变量是一个切片,蕴含了语言中用于确定序数模式的规定。每个规定是一个字符串,示意该规定的表达式。ordinalIndex: 该变量是一个映射,它将语言代码映射到对应语言的ordinal规定的索引。它被用于查找给定语言的ordinal规定。ordinalLangToIndex: 该变量是一个字典,用于将语言名称映射到对应语言的ordinal规定的索引。它也被用于查找给定语言的ordinal规定。ordinalInclusionMasks: 该变量是一个映射,将语言代码映射到对应语言的ordinal规定的蕴含掩码。它被用于确定给定语言的ordinal规定中哪些类型的数值被蕴含。cardinalRules: 该变量是一个切片,蕴含了语言中用于确定基数模式的规定。每个规定是一个字符串,示意该规定的表达式。cardinalIndex: 该变量是一个映射,它将语言代码映射到对应语言的cardinal规定的索引。它被用于查找给定语言的cardinal规定。cardinalLangToIndex: 该变量是一个字典,用于将语言名称映射到对应语言的cardinal规定的索引。它也被用于查找给定语言的cardinal规定。cardinalInclusionMasks: 该变量是一个映射,将语言代码映射到对应语言的cardinal规定的蕴含掩码。它被用于确定给定语言的cardinal规定中哪些类型的数值被蕴含。这些变量一起形成了一个复数模式规定和索引的数据表,依附这些数据,text我的项目可能精确地确定语言的复数模式,并进行相应的解决。 File: text/encoding/traditionalchinese/maketables.gotext/encoding/traditionalchinese/maketables.go文件是Go语言中text/encoding/traditionalchinese包的一个辅助文件,该文件用于生成用于传统中文编码(Big5编码)的索引和转换表。 在该文件中,interval和byDecreasingLength是两个构造体,用于存储用于传统中文编码的索引表。interval构造体示意一个字符集的索引范畴,包含起始码位和完结码位。byDecreasingLength构造体是一个排序构造体,用于依照字符集长度递加的程序对字符集进行排序。 main函数是该文件的入口函数,用于调用各个性能函数生成传统中文编码的索引和转换表。len函数用于计算字符集的长度。Len函数用于返回一个字符集列表的长度。Less函数用于依照字符集长度递加的程序进行排序。Swap函数用于替换字符集列表中的两个元素的地位。 这些函数和构造体的目标是为了生成一个无效的传统中文编码索引表,以便进行字符集的转换和解决。通过这些索引表,能够在传统中文编码和其余编码之间进行字符集的映射和转换。 File: text/collate/tools/colcmp/colcmp.go文件colcmp.go的作用是实现了一个用于比拟排序后果的工具。该工具用于验证text/collate包中的排序算法的正确性。 以下是这些变量和构造体的具体介绍: 变量: doNorm:一个bool类型的变量,示意是否要对输出进行Unicode规范化。cases:一个蕴含不同大小写变换的字符串切片,用于在比拟时思考不同大小写的状况。verbose:一个bool类型的变量,示意是否输入具体的比拟信息。debug:一个bool类型的变量,示意是否输入调试信息。locales:一个蕴含要测试的不同locale的字符串切片。col:一个字符串,示意要测试的collator类型。gold:一个蕴含用于验证排序后果的golden文件的门路字符串切片。usecmp:一个字符串,示意要应用的比拟函数类型。cpuprofile:一个字符串,示意保留CPU profile的文件门路。exclude:一个蕴含要排除的测试的字符串切片。limit:一个整数,示意要限度的测试数量。lastLen:一个整数,示意上一次运行的输出长度。commands:一个字符串切片,示意要运行的命令。cmdSort:一个bool类型的变量,示意是否运行sort命令。cmdBench:一个bool类型的变量,示意是否运行bench命令。cmdRegress:一个bool类型的变量,示意是否运行regress命令。构造体: Test:用于保留测试的后果的构造体。蕴含排序前和排序后的输出字符串切片。testCompare:用于保留比拟后果的构造体。蕴含一个测试和理论的比拟后果。testRestore:用于保留还原后果的构造体。蕴含一个测试和还原后的后果。Context:用于保留上下文信息的构造体。蕴含比拟函数和unicode规范化函数。Command:用于保留命令信息的构造体。蕴含命令名称和帮忙信息。函数: failOnError:用于输入错误信息并返回谬误状态码的函数。clear:用于革除缓冲区的函数。SetStatus:用于设置状态的函数。Start:用于开始计时的函数。Stop:用于进行计时并输入后果的函数。generateKeys:用于生成key的函数。Sort:对字符串切片进行排序的函数。Swap:用于替换切片中元素地位的函数。Less:用于比拟两个元素大小的函数。Len:用于获取切片长度的函数。GenerateInput:用于生成输出的函数。Printf:用于输入格式化字符串的函数。Print:用于输入字符串的函数。assertBuf:用于断言缓冲区中的内容是否与预期雷同的函数。flush:用于清空缓冲区的函数。parseTests:用于解析测试文件的函数。Test:对输出字符串切片进行排序并返回后果的函数。parseInput:用于解析输出字符串的函数。Name:用于获取测试名称的函数。runSort:运行sort命令的函数。runBench:运行bench命令的函数。keyStr:用于将排序的后果转换为字符串的函数。runRegress:运行regress命令的函数。runHelp:运行help命令的函数。main:工具的入口函数。依据命令行参数执行不同的命令。File: text/collate/tools/colcmp/chars.go在Go的text我的项目中,text/collate/tools/colcmp/chars.go文件的作用是实现字符比拟性能。该文件中定义了一些变量和构造体,用于示意字符比拟时的规定和个性。 在这个文件中,exemplarCharacters变量是一个字符汇合,它蕴含了用于排序和比拟文本时的例示字符。这些字符代表了特定区域或语言中的重要字符,用于确定字符的排序程序。 exemplarType构造体是用来示意字符的类型的。它蕴含了两个字段:Type和Chars。Type字段示意字符的类型,能够是次要类型(primary type)或辅助类型(secondary type),用于决定字符的排序优先级。Chars字段则示意了该类型所对应的字符汇合。 构造体中定义了以下几个exemplarType变量: primaryExemplarTypes: 这是一个次要类型的字符集。它蕴含了非法字符、字母、数字和符号等次要类型的字符。secondaryExemplarTypes: 这是一个辅助类型的字符集。它蕴含了一些特殊字符,比方重音符号、变音符号、距离符号等。variantsExemplarTypes: 这是一个变体类型的字符集。它蕴含了一些具备变体模式的字符,比方大小写变体、附加符号变体等。这些exemplarType构造体的作用是为字符比拟提供规定和个性。它们定义了字符的类型,以及每个类型所蕴含的字符汇合。在字符比拟过程中,依据字符的类型和字符汇合的程序,确定字符的排序优先级,从而实现正确的字符比拟性能。这些规定和个性的定义在理论的排序算法中起到了重要的作用。 File: text/collate/tools/colcmp/darwin.go在Go的text/collate/tools/colcmp/darwin.go文件中,次要定义了与Mac OS X平台相干的字符比拟器。 osxCollator、osx8Collator、osx16Collator 构造体: osxCollator 构造体用于存储 macOS 上的原生 CollatorRef 对象,用于比拟和排序字符串。osx8Collator 构造体用于在 macOS 上解决 UTF-8 编码的字符串比拟。osx16Collator 构造体用于在 macOS 上解决 UTF-16 编码的字符串比拟。init() 函数: init() 函数会在包加载时执行,会初始化 collatorBundle 和 collatorBundleMutex 变量。osxUInt8P() 函数: osxUInt8P() 函数将 Go 语言的 []byte 类型转换为 C 语言的 *C.UInt8 类型。osxCharP() 函数: ...

September 27, 2023 · 2 min · jiezi

关于后端:面试题精讲标识符和关键字的区别是什么

有的时候博客内容会有变动,首发博客是最新的,其余博客地址可能会未同步,认准https://blog.zysicyj.top首发博客地址 面试题手册 系列文章地址 1. 什么是标识符和关键字?标识符:在编程语言中,标识符是用来示意变量、函数、类等命名实体的名称。它由一系列字符组成,能够蕴含字母、数字和下划线,并且必须以字母或下划线结尾。例如,在 Java 中,myVariable就是一个标识符。关键字:关键字是编程语言中预约义的具备非凡意义的单词。这些单词被保留,不能用作标识符来命名变量、函数或类等。关键字通常用于控制程序的构造、定义数据类型、申明变量等。例如,在 Java 中,if、for、class等都是关键字。2. 标识符和关键字的区别含意不同:标识符是用来给变量、函数、类等命名的,而关键字是编程语言中预约义的具备非凡意义的单词。应用形式不同:标识符能够依据须要自由选择,但要遵循肯定的命名规定;而关键字是编程语言中固定的,不能用作标识符。数量不同:每个编程语言中的关键字数量是固定的,而标识符的数量取决于程序员的需要。作用范畴不同:标识符只在特定的上下文中起作用,例如变量名只在其所属的代码块内无效;而关键字具备全局性质,在整个程序中都有非凡含意。3. 标识符和关键字的应用示例以下是一个 Java 程序中的标识符和关键字的应用示例: public class MyClass { public static void main(String[] args) { int myVariable = 10; // 标识符 if (myVariable > 5) { // 关键字 System.out.println("Hello, World!"); } }}在下面的示例中,myVariable是一个标识符,用来示意一个整数类型的变量。if是一个关键字,用于控制程序的流程。 4. 标识符和关键字的长处标识符: 能够依据须要自由选择命名,使代码更易读、了解和保护。进步了代码的可重用性,能够在不同的上下文中应用雷同的标识符。关键字: 确保编程语言的语法规定失去正确利用,避免出现语法错误。提供了一种对立的形式来定义数据类型、控制程序构造等,使代码更加规范化。5. 标识符和关键字的毛病标识符: 如果命名不标准,可能导致代码可读性差、易混同。过多或过长的标识符可能减少代码的复杂度。关键字: 关键字是固定的,不能用作标识符,有时会限度了程序员的自由度。不同编程语言中的关键字可能存在差别,须要相熟具体语言的关键字列表。6. 标识符和关键字的应用注意事项标识符: 命名要遵循肯定的规定,如驼峰命名法、下划线命名法等。防止应用与关键字雷同的名称作为标识符。尽量抉择有意义的名称,进步代码的可读性。关键字: 相熟所应用编程语言的关键字列表,防止将其作为标识符。在编辑器中关键字通常会有非凡的色彩显示,便于辨识。7. 总结标识符是用来给变量、函数、类等命名的,而关键字是编程语言中预约义的具备非凡意义的单词。它们在含意、应用形式、数量和作用范畴等方面有所区别。标识符和关键字的正确应用能够进步代码的可读性、规范性和维护性,但如果使用不当可能会导致代码凌乱或呈现语法错误。因而,在编程中须要留神抉择适合的标识符,并相熟所应用编程语言的关键字列表。 <!-- md tj.md --> 本文由mdnice多平台公布

September 27, 2023 · 1 min · jiezi

关于后端:面试题精讲注释有哪几种形式

有的时候博客内容会有变动,首发博客是最新的,其余博客地址可能会未同步,认准https://blog.zysicyj.top首发博客地址 面试题手册 系列文章地址 1. 什么是 Java 正文?Java 正文是一种用于在代码中增加阐明和解释的非凡文本。它们不会被编译器解决,因而对程序的运行没有任何影响。Java 正文次要有三种类型:单行正文、多行正文和文档正文。 单行正文以双斜线(//)结尾,能够在一行中增加正文。多行正文以斜线星号(/_)开始,以星号斜线(_/)完结,能够逾越多行。文档正文以斜线星号两个间断的星号(/*_)开始,以星号斜线(_/)完结,能够蕴含多行形容,并且能够通过工具生成 API 文档。2. 为什么须要 Java 正文?Java 正文是一种良好的编程实际,有以下几个重要起因: 提供代码的可读性:正文能够帮忙其他人了解你的代码,尤其是当代码变得复杂或难以了解时。不便代码保护:正文能够记录代码的目标、逻辑和设计思路,使得后续的批改和保护更加容易。主动生成文档:文档正文能够通过工具主动生成 API 文档,不便其余开发人员应用你的代码。团队合作:正文能够促成团队成员之间的沟通和单干,缩小代码了解上的困惑。3. Java 正文的应用办法单行正文单行正文用于在一行中增加简短的正文。它们能够呈现在任何中央,并且不会影响程序的执行。 int x = 10; // 定义一个整数变量x并赋值为10多行正文多行正文用于逾越多行的正文内容。它们罕用于对较长的代码块进行解释或临时禁用一段代码。 /*这是一个多行正文示例。它能够蕴含多行形容,以及对代码的具体解释。*/int y = 20;文档正文文档正文用于生成 API 文档,并提供给其余开发人员应用你的代码。它们应该放在类、办法和字段的后面,并应用特定的标记来形容各个局部。 /** * 这是一个文档正文示例。 * 它能够蕴含多行形容, * 并应用标记阐明类、办法和字段的作用。 */public class MyClass { /** * 这是一个办法的文档正文。 * @param x 参数x的阐明 * @return 返回值的阐明 */ public int myMethod(int x) { return x + 1; }}4. Java 正文的长处进步代码可读性:正文能够帮忙其他人了解你的代码,尤其是当代码变得复杂或难以了解时。不便代码保护:正文能够记录代码的目标、逻辑和设计思路,使得后续的批改和保护更加容易。主动生成文档:文档正文能够通过工具主动生成 API 文档,不便其余开发人员应用你的代码。5. Java 正文的毛病可能适度正文:如果正文过多或不精确,会导致代码冗余和凌乱。正文可能过期:如果代码产生了扭转而正文没有及时更新,就会产生误导。6. Java 正文的应用注意事项正文应该清晰明了:正文应该简洁明了,用简略的语言形容代码的用意和性能。防止无用的正文:删除不再须要的正文,防止给阅读者造成困惑。及时更新正文:当代码发生变化时,要记得更新相应的正文,放弃正文与代码的一致性。7. 总结Java 正文是一种用于在代码中增加阐明和解释的非凡文本。它们提供了代码的可读性、不便代码保护、主动生成文档等益处。Java 正文有三种类型:单行正文、多行正文和文档正文。应用时须要留神清晰明了、防止适度正文和及时更新的准则。 ...

September 27, 2023 · 1 min · jiezi

关于后端:探析-Spring-容器内部事件发布

其实在 JDK 中曾经提供相应的自定义事件公布性能的根底类: java.util.EventObject类 :自定义事件类型java.util.EventListener接口:事件的监听器首先理解几个概念: Spring 事件类构造 1. 事件类事件类也就是定义发送的内容,比方能够通过继承ApplicationContextEvent来自定义一个特定事件类。 1.1 ApplicationEvent类首先是继承 EventObject的ApplicationEvent,通过source来指定事件源: public abstract class ApplicationEvent extends EventObject { /** * Constructs a prototypical Event. * * @param source The object on which the Event initially occurred. * @throws IllegalArgumentException if source is null. */ public ApplicationEvent(Object source) { super(source); }}1.2 ApplicationContextEvent类是次要的容器事件,它有容器启动、刷新、进行以及敞开各种事件的子类。 public class ApplicationContextEvent extends ApplicationEvent { /** * Constructs a prototypical Event. * * @param source The object on which the Event initially occurred. * @throws IllegalArgumentException if source is null. */ public ApplicationContextEvent(Object source) { super(source); } /** * Get the <code>ApplicationContext</code> that the event was raised for. */ public final ApplicationContext getApplicationContext() { return (ApplicationContext) getSource(); }}public class ContextClosedEvent extends ApplicationContextEvent{ /** * Constructs a prototypical Event. * * @param source The object on which the Event initially occurred. * @throws IllegalArgumentException if source is null. */ public ContextClosedEvent(Object source) { super(source); }}public class ContextRefreshedEvent extends ApplicationContextEvent{ /** * Constructs a prototypical Event. * * @param source The object on which the Event initially occurred. * @throws IllegalArgumentException if source is null. */ public ContextRefreshedEvent(Object source) { super(source); }}咱们能够通过继承该类来实现,特定的事件类型需要,比方要实现一个邮件发送事件。只须要继承ApplicationContextEvent即可: ...

September 27, 2023 · 4 min · jiezi

关于后端:EECS-461模拟转换数字算法

EECS 461 Fall 2023Lab 3: Analog-To-Digital Conversion 1 OverviewIn this lab you will learn how to use the analog to digitalconverters on the NXP S32K144 microcontroller.You will then sample a sine wave produced by the signal generator and display the result on a virtualoscilloscope to study the phenomenon of aliasing. See Chapter42 in the S32K144 Reference Manual:“Analog-to-Digital Converter (ADC).” A block diagram of the ADC isfound in Figure 1.Figure 1: Block diagram of the ADC module.EECS 461: Embedded Control Systems 1 Fall 2023Lab 3 Analog-To-Digital Conversion ANinPotentiometer(Turning Knob)PotJump (Connector)Figure 2: Pin connection matrix between external signals and S32K144microcontroller. ...

September 27, 2023 · 8 min · jiezi

关于后端:常见面试题-如何设计Google-Docs

常见面试题 - 如何设计Google Docs?一图胜千言。明天咱们来看看设计Google Docs的几个次要模块。 首先咱们来看看功能性需要: 在线编辑合作编辑 - 容许多人同时编辑同一个文档。文件存储 - 反对文件系统,容许查看文档、增加文档、批改文档、删除文档。咱们先简化一下问题。如果是一个单机版的在线文档,没有多人合作的要求,那其实只有将本地的文档同步到远端就能够了。如下图所示,设计中的难点在于放弃本地文档和远端文档的数据同步。如果发送到文件服务的过程中丢了数据,那么就有点难堪了。所以不论是给各种文件操作定序,还是给文档内容设置CRC校验,都能够保证数据一致性。 那么如果退出多人合作编辑呢? 下图先将各个组件串联在一起以便与咱们剖析问题: 客户端编辑器和 WebSocket 服务器建设长连贯,以便及时向 WebSocket 服务器发送文档编辑操作。WebSocket 服务器会解决文档编辑操作,并将它们发送到音讯队列中。文档操作服务器会从音讯队列耗费客户端的操作事件,并应用合作算法生成转换后的操作。这个过程叫做操作转换(Operational Transformation),就是依据多人对文档的批改状况来失去最终的后果,并更新每个人的操作。为了给用户更好的实时编辑体验,最近的操作会先应用缓存来存储。文档最终会存储在数据库或其余文件系统中。存储的数据分为三个局部:文件元数据,文件内容和文件编辑操作。 退出多人合作后,最大的挑战之一是须要实时解决编辑抵触。解决抵触的常见的合作算法包含: 操作转换 (OT, Operational transformation)差分同步 (DS, Differential Synchronization)无抵触复制数据类型 (CRDT, Conflict-free replicated data type)依据维基百科,Google Docs 应用的是 OT,而 CRDT 是实时并发编辑的一个沉闷钻研畛域。 OT的根本思维和Git相似。服务器晓得每个用户的批改是基于哪一个版本的,会尝试把各人的操作合并。 如果你对这些算法感兴趣,能够在后盾通知我。 【关注公众号ByteByteGo获取高清图】

September 27, 2023 · 1 min · jiezi

关于后端:用shell批量修改文件名

场景一 给这些文件都加上.png后缀 #!/bin/bashfor i in *;domv "$i" "$i.png";done 场景二 给某些文件按某种规定重命名,如依照1,2,3,4..命名,保留原格局 cd imagedeclare -i j=1 for i in * ;do #echo $i; x=${i##*.}#echo $j.$xmv "$i" "$j.$x";j+=1done 注: Shell中实现整数自增的几种办法示例,此处用于申明是数字类型的declare -i必须增加,否则会认为是字符串;必须j+=1,而不能用j++,否则后果会为拼接字符串shell获取文件扩展名 场景三 删除某些反复文件;如下图,想将所有带(x)的全副删掉 #!/bin/bashfor i in * ;do#echo ${i:1:2}; #最罕用的字符串截取办法,输入前两个字符if [[ $i =~ '(' ]]then echo $i; rm "$i"; #如果用rm $i会分为两局部: #ia_800000110 (2).jpg #rm: ia_800000110: No such file or directory #rm: (2).jpg: No such file or directoryfidone ...

September 26, 2023 · 1 min · jiezi

关于后端:听GPT-讲gotext源代码cmd

File: text/internal/cldrtree/generate.go在Go的text我的项目中,text/internal/cldrtree/generate.go文件的次要作用是生成CLDR数据的Go代码。CLDR(Common Locale Data Repository)是一个蕴含各种语言和地区相干数据(如日期格局、货币符号、时区等)的开放式规范数据集。 该文件中定义了一些构造体和函数来解决和生成CLDR数据。以下是对每个相干局部的具体介绍: enumData构造体:这些构造体定义了用于生成CLDR数据的信息,蕴含了标识符、类型、值等字段。例如,enumData的一个实例能够示意一个语言的国家列表。generate函数:这个函数是整个文件的入口函数,它解析CLDR的XML数据文件,并调用其余函数生成相应的Go代码。generateTestData函数:这个函数生成用于测试的虚构CLDR数据,并将其写入Go代码中。toCamel函数:这个函数将字符串转换为驼峰命名格局。例如,将"test_string"转换为"TestString"。stats函数:这个函数用于统计CLDR数据中各个类型的数量,例如,统计有多少个语言、货币等。printEnums函数:这个函数依据给定的enumData生成对应的Go代码,其中包含enum类型的申明和字符串到enum值的映射。printEnumValues函数:这个函数打印enum值的申明,用于将字符串转换为对应的enum值。getEnumData函数:这个函数从CLDR数据中解析出特定类型的enumData。例如,从CLDR数据中解析出所有的语言。insert函数:这个函数用于将解析失去的enumData插入到生成的Go代码中。总的来说,generate.go文件的作用是将CLDR数据转换为Go代码,不便在Go我的项目中应用和操作该数据。它应用一些构造体和函数来解析和解决数据,生成相应的Go代码,以便开发人员能够应用该代码来获取和操作CLDR数据。 File: text/cmd/gotext/extract.go在Go的text我的项目中,text/cmd/gotext/extract.go文件的次要作用是从源代码中提取出待翻译的字符串,并生成相应的音讯目录文件(.po文件)。以下是对extract.go文件的具体介绍: cmdExtract变量:该变量是一个构造体类型,用于存储提取操作的相干配置信息和状态。其中蕴含以下字段: outputDir:指定生成的音讯目录文件(.po文件)的输入目录。funcExp:函数表达式,用于匹配待提取的函数调用。filePatterns:须要扫描的源代码文件的模式,能够应用通配符指定多个文件或目录。extracted:存储已提取的音讯。makeTarget:要生成的指标音讯目录文件(.po文件)的名称。initExtract函数:该函数是cmdExtract变量的初始化函数,用于设置提取操作的默认配置。runExtract函数:该函数是提取操作的主函数。它依照指定的配置信息,扫描源代码文件并提取出待翻译的字符串。次要蕴含以下步骤: 遍历指定的源代码文件。通过正则表达式匹配待提取的函数调用,并提取出字符串参数。将提取的字符串存储到cmdExtract.extracted中。依据提取的字符串生成音讯目录文件(.po文件)并保留到指定的输入目录。总结来说,extract.go文件中的cmdExtract变量存储了提取操作的配置信息,initExtract函数用于初始化配置,runExtract函数执行提取操作并生成音讯目录文件。 这些组件的作用是为了不便开发者在编写多语言利用时,可能主动提取待翻译的字符串,并生成相应的音讯目录文件,以便后续的翻译工作。 File: text/internal/export/unicode/doc.go在Go的text/internal/export/unicode/doc.go文件是该包的文档文件,它具体形容了该包的性能、用法、类型和函数等详细信息。 文档文件的作用是提供对包的详尽阐明和导航,使开发人员可能理解如何正确应用这个包,并且晓得如何依据本人的需要应用其中的函数和类型。 该文件中通常蕴含以下几个方面的内容: 包概述:文档会首先提供对包的简要概述,包含包的名称、导入门路以及该包的性能和用处。类型定义:文档会介绍该包中的各种类型定义,包含构造体、接口和根本类型等。对于每个类型,文档将提供其名称、形容、办法等信息,帮忙开发人员了解如何应用这些类型。函数定义:文档会列出该包中的各种函数定义,包含函数名称、参数和返回值等信息。对于每个函数,文档会提供函数的用处、注意事项和示例等,以便开发人员可能正确地调用和了解这些函数。常量和变量定义:如果该包还定义了一些常量或者全局变量,文档会提供这些定义的具体阐明,包含名称、类型和取值范畴等。文件导航:文档还会提供对其余文件的导航链接,不便开发人员间接跳转到相干的文件,并持续浏览相干内容。总的来说,文档文件的作用是为了提供清晰的、具体的和易于了解的包信息,帮忙开发人员正确地应用这个包,缩小犯错的可能性,并进步开发效率。 File: text/cmd/gotext/rewrite.go在Go的text我的项目中,text/cmd/gotext/rewrite.go文件的作用是实现重写规定的解析和利用。 该文件中定义了一个名为cmdRewrite的构造体,该构造体用于示意重写规定。cmdRewrite构造体的字段包含Pattern(匹配模式)、Source(源字符串)、Dest(指标字符串)、PreserveCase(是否保留原始字符串的大小写)、Regex(是否应用正则表达式匹配)等。cmdRewrite构造体的定义如下: type cmdRewrite struct { Pattern string Source string Dest string PreserveCase bool Regex bool compiledRegex *regexp.Regexp}其中,Pattern字段示意匹配模式,能够是一般字符串或正则表达式。Source字段示意待替换的字符串,Dest字段示意替换后的字符串。PreserveCase字段决定是否保留原始字符串的大小写,Regex字段示意是否应用正则表达式进行匹配。compiledRegex字段存储已编译的正则表达式。 该文件中还定义了以下函数: initRewrite:用于初始化重写规定。该函数会解析重写规定文件,依据文件中的规定创立cmdRewrite构造体的实例,并将这些实例存储在全局变量rewriteRules中。重写规定文件的默认门路为~/.gotext_rewrite。runRewrite:用于利用重写规定。该函数会遍历rewriteRules中的每个重写规定实例,并对给定的字符串利用这些规定。如果匹配到了某个规定的Pattern,就会执行对应的替换规定,将字符串中的Source替换为Dest。如果PreserveCase字段为真,则放弃原始字符串的大小写。总之,rewrite.go文件实现了重写规定的解析和利用性能,容许用户定义自定义的替换规定,并在须要时对字符串利用这些规定。 File: text/cmd/gotext/examples/rewrite/printer.go在Go的text我的项目中,text/cmd/gotext/examples/rewrite/printer.go文件的作用是依据源代码文件生成一个规范的源代码示意。 该文件中定义了一个名为printer的包,用于提供将源代码文件转换为规范源代码示意的性能。它应用了Go语言的go/ast、go/token和go/parser等规范库。 上面是该文件中重要的局部代码解释: printer类型:代表了代码打印器,它蕴含了将AST节点打印为字符串的办法。printConfig类型:存储了代码打印器的配置选项,如缩进、空白符等。Fprint函数:是打印器的入口函数,用于将AST节点打印为字符串。buffer类型:外部保护了一个字节切片,用于存储最终代码。Print办法:将传入的AST节点转换为规范的源代码示意并存储到buffer中。而printer这几个变量的作用如下: astPrintConfig:打印AST节点时应用的配置选项,包含缩进、空白符等。tokenPrintConfig:打印标记时应用的配置选项,包含缩进、空白符等。nodeIndent:代表了节点的缩进级别,用于在打印时进行缩进解决。这些变量在代码打印器中用于管制打印过程中的格局和款式。通过调整这些变量的值,能够定制化打印器的性能和输入后果,使其适应各种不同的需要。 File: text/cmd/gotext/examples/extract_http/catalog_gen.go在Go的text我的项目中,text/cmd/gotext/examples/extract_http/catalog_gen.go是一个用于生成翻译目录(catalog)的示例文件。它的作用是读取一个HTTP接口的API定义,并从中提取出须要翻译的文本,并生成一个翻译目录文件。 上面咱们一一解释一下相干变量和函数的作用: messageKeyToIndex是一个字典(map),用于将音讯的键(message key)映射到在翻译目录中的索引值。这个索引值是一个整数,用来疾速定位翻译目录中对应音讯的地位。enIndex是一个整数,示意英文音讯在翻译目录中的索引地位。zhIndex是一个整数,示意中文音讯在翻译目录中的索引地位。这些变量的作用是为了记录每个音讯在翻译目录中的地位,不便后续的翻译和查找。 而对于dictionary构造体,这是一个用来示意翻译目录的数据结构。它蕴含了一个数组,用于存储所有的音讯翻译。每个音讯翻译又蕴含了键(key)、英文文本(enText)和中文文本(zhText)等字段。 Lookup函数是用来依据音讯的键在翻译目录中查找对应的翻译信息。它承受一个键作为输出,并返回对应的翻译信息(Message)。如果该键不存在,将返回一个空的翻译信息。 init函数是程序的入口点。它会读取HTTP接口的API定义,提取须要翻译的文本,并生成翻译目录文件。在生成翻译目录文件时,会依据音讯的键生成对应的索引,并记录在messageKeyToIndex字典中。 总而言之,catalog_gen.go文件通过解析HTTP接口的API定义,提取须要翻译的文本,并生成一个翻译目录文件。翻译目录文件会记录每个翻译音讯的键、英文翻译和中文翻译等信息,并提供了一个疾速查找的形式。 File: text/cmd/gotext/examples/extract_http/pkg/pkg.go在Go的text我的项目中,text/cmd/gotext/examples/extract_http/pkg/pkg.go文件的作用是提供一个示例用法,演示如何应用gotext包从HTTP申请和响应中提取本地化文本。 matcher是一个全局变量,它用于匹配蕴含本地化文本的字符串。它是一个正则表达式,用于解析HTTP申请和响应中的文本。 matcherHTTPRequest用于匹配HTTP申请中的本地化文本。matcherHTTPResponse用于匹配HTTP响应中的本地化文本。Generize函数用于将提取到的本地化文本通用化。它接管一个本地化文本字符串,并返回一个带有{#}占位符的通用本地化字符串。此函数的目标是将具体的本地化字符串转换为相似于{#}的通用模式,以不便后续进行国际化。 GenerizeHTTPLocalizer函数是一个实现了gotext.Localizer接口的自定义类型的办法,它代表一个HTTP本地化器。该函数用于从HTTP申请和响应中提取文本,并对其进行通用化解决。它通过调用Generize函数来替换HTTP音讯中的本地化文本。 总结:pkg/pkg.go文件是示例代码文件,展现了如何应用gotext包从HTTP申请和响应中提取本地化文本,并进行通用化解决。其中,matcher用于匹配蕴含本地化文本的字符串,Generize函数用于将本地化文本通用化,而GenerizeHTTPLocalizer函数则是对提取到的文本进行解决的办法。 File: text/cmd/gotext/examples/extract/catalog.go在Go的text我的项目中,text/cmd/gotext/examples/extract/catalog.go文件的作用是实现目录的提取和治理。该文件定义了一些变量、构造体和函数,用于解决目录中的音讯。 messageKeyToIndex变量是一个map,用于将音讯键映射到索引值。deIndex、en_USIndex和zhIndex变量别离是用于德语、美式英语和中文目录的索引。 dictionary构造体代表一个目录,蕴含了该目录的所有音讯。其中Msgs字段是一个map,将音讯键映射到音讯对象。Plurals字段是一个map,将音讯键映射到复数音讯对象。 Lookup函数接管一个目录和一个音讯键作为参数,返回对应的音讯对象。init函数是一个初始化函数,它读取目录中的音讯,构建索引和字典。 该文件的性能是提供了一种不便的形式来治理和索引目录中的音讯。它通过应用变量来存储索引,应用构造体来组织目录中的音讯,并提供了函数来检索音讯。这样能够简化在Go应用程序中的多语言反对和国际化解决。 ...

September 26, 2023 · 1 min · jiezi

关于后端:听GPT-讲gotext源代码cases

File: text/cases/context.go在Go的text我的项目中,text/cases/context.go文件的作用是为文本操作提供上下文和状态信息。它定义了一些构造体和函数,用于反对文本的大小写转换、字符串前缀匹配等操作。 上面是对于context.go中的各个构造体和函数的具体介绍: 构造体:Reset:用于保留以后上下文的快照,以便在后续应用时能够重置到该快照状态。ret:用于保留字符转换后果的缓冲区。retSpan:用于保留字符串转换后果的缓冲区。与ret不同的是,它能够解决多个间断字符的转换后果。checkpoint:用于保留以后地位的上下文快照。当须要长期扭转上下文时,能够应用它来保留以后状态,以便在之后复原到这个状态。unreadRune:用于保留最初一个读取的rune字符,以便下次读取时能够从unreadRune中获取。函数:next:用于从输出文本中获取下个rune字符,并将其保留到unreadRune中。writeBytes:用于将字节数组写入到ret中。writeString:用于将字符串写入到ret中。copy:用于将源切片的内容复制到指标切片中。copyXOR:相似于copy,然而在复制过程中还会执行异或操作。hasPrefix:用于判断字符串是否以指定的前缀结尾。caseType:用于判断字符的大小写类型,如大写、小写、题目等。lower:将字符转换为小写。isLower:判断字符是否为小写。upper:将字符转换为大写。isUpper:判断字符是否为大写。title:将字符转换为题目格局(首字母大写,其它字母小写)。isTitle:判断字符是否为题目格局。foldFull:将字符转换为齐全折叠格局。isFoldFull:判断字符是否为齐全折叠格局。这些函数和构造体的组合应用,能够实现文本的大小写转换、前缀匹配等各种性能。它们在文本处理过程中起到了关键作用,并且容许用户自定义解决逻辑。 File: text/internal/export/idna/tables11.0.0.gotext/internal/export/idna/tables11.0.0.go 文件是Go语言中 text 包外部的一个模块,是针对 Unicode 11.0.0 版本的国际化域名(IDNA)规范编码所应用的数据表。 上面对每个变量和函数进行具体解释: mappings:这是一个固定大小的数组,用于保留 Unicode 字符的映射值。在 IDNA 规范编码中,每个字符都须要被映射为一个整数值。xorData:这是一个固定大小的数组,用于保留异或运算的数据。在 IDNA 规范编码中,一些字符的编码须要通过与特定的异或位运算来产生。idnaValues:这是一个固定大小的数组,用于保留 Unicode 字符对应的 IDNA 属性值。在 IDNA 规范编码中,每个字符都有一个属性值来批示其是否容许在域名中应用。idnaIndex:这是一个固定大小的数组,保留了每个字符对应的索引值。这些索引值用于在其余数组中查找对应的属性和映射值。idnaSparseOffset:这是一个固定大小的数组,用于保留稠密数组的偏移量。稠密数组是一种只保留无限数量元素的数组构造。idnaSparseValues:这是一个固定大小的数组,用于保留稠密数组中非零元素的值。在 IDNA 规范编码中,为了减速查问,由这些变量组成了一个数据结构: idnaTrie:这是一个外部应用的数据结构,它是一个压缩的字典树。在字典树中,每个字符都示意一个门路中的子节点。idnaTrie 构造体中蕴含了一个 root 节点和一组查找办法。 lookup:这是 idnaTrie 构造体的一个办法,用于依据提供的字符序列在字典树中查找对应的索引值。lookupUnsafe:这是一个相似于 lookup 的办法,然而它不进行边界查看,因而在应用时须要保障提供的索引值在非法范畴内。lookupString:这是一个相似于 lookup 的办法,然而它接管字符串作为输出,而后调用 lookup 办法进行查找。lookupStringUnsafe:这是一个相似于 lookupUnsafe 的办法,接管字符串作为输出并调用 lookupUnsafe 办法进行查找。newIdnaTrie:这是一个构造函数,用于创立一个新的 idnaTrie 构造体实例。lookupValue:这是 idnaTrie 构造体的另一个办法,用于依据提供的索引值查找对应的属性和映射值。这些变量和函数的作用是为了提供一个高效的查找机制,用于将 Unicode 字符转换为 IDNA 编码所需的属性和映射值。这些数据和办法是为了在 text 包中实现 IDNA 编码相干的性能。 File: text/internal/export/idna/gen.go在Go的text我的项目中,text/internal/export/idna/gen.go 文件是用于生成 IDNA (Internationalized Domain Names in Applications) 相干的数据表和代码供其余模块应用的。该文件通过读取 Unicode 组织的 IDNA 映射数据文件和罕用字符数据文件,并依据一些算法进行解决和转换,最终生成 IDNA 相干的数据表和代码。 ...

September 26, 2023 · 2 min · jiezi

关于后端:听GPT-讲Istio源代码tools

File: istio/tools/docker-builder/crane.go在Istio我的项目中,crane.go文件位于istio/tools/docker-builder/目录下。该文件是用于构建Docker镜像的工具,次要应用了crane工具(https://github.com/google/go-containerregistry)。 该文件中的RunCrane函数是用于运行crane工具的函数。在该函数中,首先依据给定的参数创立crane工具的命令行参数列表,并执行该命令,最初返回执行后果。 translate函数用于将本地的Docker镜像援用转换为crane工具反对的援用格局。crane工具在操作Docker镜像时,应用的是Docker V2援用,而不是传统的image:tag格局。因而,translate函数将本地Docker镜像援用转换为Docker V2援用格局。 absPath函数用于获取给定门路的绝对路径。该函数首先判断给定的门路是否为相对路径,如果是则将其绝对于当前工作目录转换为绝对路径;如果曾经是绝对路径,则间接返回。 总结来说,crane.go文件中的RunCrane函数是用于运行crane工具的函数,translate函数用于解决Docker镜像援用的格局转换,absPath函数用于获取绝对路径。这些函数一起提供了构建Docker镜像的性能。 File: istio/tools/docker-builder/builder/tar.go在Istio我的项目中,istio/tools/docker-builder/builder/tar.go文件是一个用于操作tar文件的工具文件。它提供了用于创立和提取tar归档文件的函数。 WriteTime是一个用于示意文件的批改工夫的变量。它通常用于设置将要写入tar归档文件中的文件的批改工夫。 WriteArchiveFromFiles是一个函数,用于将给定的文件列表写入tar归档文件中。它承受要写入的文件列表以及指标tar文件的门路作为输出,并将这些文件增加到tar归档文件中。 WriteArchiveFromFS是一个函数,用于从给定的文件系统门路提取文件,并将这些文件写入tar归档文件中。它承受文件系统门路和指标tar文件的门路作为输出,并将这些文件从文件系统中读取并增加到tar归档文件中。 IsExecOwner是一个函数,用于查看文件的权限位,判断文件是否属于可执行者。它承受文件的权限位作为输出,并返回一个布尔值,用来示意文件是否属于可执行者。 这些函数的作用是为了帮忙构建tar归档文件,其中WriteArchiveFromFiles和WriteArchiveFromFS用于将文件增加到tar归档文件中,而IsExecOwner用于判断文件是否可执行。同时,WriteTime变量用于设置文件的批改工夫。这些性能都是为了不便构建和治理tar归档文件,使其成为一个有用的工具。 File: istio/tools/docker-builder/docker.go在Istio我的项目中,istio/tools/docker-builder/docker.go 文件是用于构建和打包 Docker 镜像的实用程序代码。上面是对每个函数的具体介绍: RunDocker 函数:该函数用于在指定的目录中运行 Docker CLI 命令,并返回运行后果的输入。runDocker 函数:这是一个辅助函数,用于运行 Docker CLI 命令,并返回运行后果。CopyInputs 函数:该函数用于将指定目录中的文件复制到 Docker 上下文目录中。它被用来将构建所需的文件复制到 Docker 镜像中。RunSave 函数:该函数依据指定的 Docker 镜像生成和保留一个 tarball 文件。这个 tarball 文件能够通过 docker load 命令加载到 Docker 中,用于创立镜像。RunBake 函数:该函数用于运行 Docker buildx bake 命令,该命令依据指定的配置构建和导出多个镜像。createBuildxBuilderIfNeeded 函数:这个函数查看 Docker 环境中是否曾经存在一个 buildx 构建器,如果不存在则会创立一个。ConstructBakeFile 函数:该函数依据给定的构建配置(通常是 YAML 文件)生成一个 Docker buildx bake 配置文件。Copy 函数:该函数用于将指定目录下的文件复制到 Docker 镜像中的指定地位。这些函数一起提供了一组工具办法,用于在 Istio 我的项目中构建和操作 Docker 镜像。这些函数容许用户从指定的文件或配置中构建镜像,并执行其余与 Docker 相干的操作,以反对 Istio 我的项目的开发和部署工作。 ...

September 26, 2023 · 1 min · jiezi

关于后端:优刻得大模型技术实践四|参数高效微调技术解析及AdaLoRA的应用

在上一期的大模型技术实际中,咱们为大家介绍了基于“LangChain+LLM”框架疾速搭建常识加强后的问答机器人,并探讨了晋升模型内容了解和执行能力的潜在优化方向。本期内容UCloud将为您解析参数高效微调技术(PEFT),即对已预训练好的模型,固定住其大部分参数,而仅调整其中小局部或额定的参数,以达到与全副参数微调相近的成果。参数高效微调办法,可大抵分为三个类别:减少式办法、抉择式办法和从新参数化式办法[1]。1 减少式办法(Additive methods)减少式办法通过减少额定的参数或层来扩大现有的预训练模型,且仅训练新减少的参数。目前,这是PEFT办法中被利用最宽泛的类别。在减少式办法中,大抵分为Adapter类办法和软提醒(Soft Prompts)。2019年1月至2022年3月期间,Adapter类的办法Adapter Tuning,软提醒类的办法Prefix Tuning、P-Tuning、Prompt Tuning、P-Tuning v2相继呈现。1.1 Adapter Tuning[2]Adapter的架构如下:在每一个Transformer层中的每个子层之后插入两个串行的Adapter。在Adapter微调期间,绿色层是依据上游数据进行训练的,而预训练模型的原参数放弃不变。1.1.1 Adapter的特点Adapter 模块次要由两个前馈(Feed-forward)子层组成。 第一个前馈子层将原始特色的维度d投影到一个更小的维度m,利用非线性函数,再投影回维度d的特色(作为Adapter模块的输入)。总参数量为2md + d + m。通过设置m < d,咱们限度了每个工作增加的参数数量。当投影层的参数初始化靠近零时,依据一个skip-connection,将该模块就初始化为近似恒等函数,以确保微调的有效性。 1.1.2 Adapter的试验后果应用公开的预训练BERT作为根底模型。Adapter微调具备高参数效率,能够生成性能强劲的紧凑模型,与齐全微调相比体现相当。Adapter通过应用原始模型0.5-5%大小的参数量来微调,性能与BERT-LARGE上具备竞争力的后果相差不到1%。1.2 Soft Prompts晚期的提醒微调通过批改输出文原本管制语言模型的行为,称为硬提醒(Hard Prompts)微调。这些办法很难优化,且受到最大模型输出长度的限度。下图为离散的人工设计的Prompt示例:比方扭转输出模式去询问模型:软提醒(Soft Prompts)将离散的“提醒”问题转为间断的“提醒”问题,通过过反向流传和梯度降落更新参数来学习Prompts,而不是人工设计Prompts。有仅对输出层进行训练,也有对所有层进行训练的类型。上面将介绍几种热门的Soft Prompts微调办法。1.2.1 Prefix Tuning其构造如下:只优化前缀(红色前缀块),该前缀增加到每一个Transformer Block中。1.2.1.1 Prefix Tuning的特点解冻预训练语言模型的参数,为每个工作存储特定的间断可微的前缀,节俭空间。2.训练间减少MLP层以达到稳固。对于不同模型结构不同的Prefix。 1.2.1.2 Prefix Tuning的试验后果对于表格到文本工作,应用GPT-2MEDIUM和GPT-2LARGE模型。在表格到文本工作上,Prefix Tuning优于Fine-Tuning(全量微调)和Adapter-Tuning。对于摘要工作,应用BART-LARGE模型。在摘要工作上,Prefix Tuning比全量微调弱。1.2.2 P-Tuning其构造如下: 1.2.2.1 P-Tuning的特点 P-Tuning只在输出层退出可微的Virtual Token,其会主动插入到文本提醒的离散Token嵌入中。Virtual Token不肯定作为前缀,其插入地位是可选的。 1.2.2.2 P-Tuning的试验后果应用的是GPT系列和BERT系列的模型。P-Tuning与全参数成果相当,且在一些工作上优于全参数微调,能够显著进步GPT模型在自然语言了解方面的性能,并且BERT格调的模型也能够取得较小的增益.1.2.3 Prompt Tuning其构造如下:上图中,仅Virtual Token局部会由梯度降落法去更新参数。1.2.3.1 Prompt Tuning的特点只在输出层退出Prompt,并且不须要退出MLP进行调整来解决难训练的问题。提出了Prompt Ensembling,即通过在同一工作上训练N个提醒,也就是在同一个批次中,对同一个问题增加不同的Prompt,相当于为工作创立了N个独立的“模型”,同时依然共享外围语言建模参数。 1.2.3.2 Prompt Tuning的试验后果应用的是预训练的各种T5模型。在风行的SuperGLUE基准测试中,Prompt Tuning的工作性能与传统的模型调优相当,且随着模型规模的减少,差距逐步减小。在零样本畛域迁徙中,Prompt Tuning能够改善泛化性能。1.2.4 P-Tuning v2其构造如下:1.2.4.1 P-Tuning v2的特点P-Tuning v2每一层的输出都退出了Tokens,容许更高的工作容量同时放弃参数效率;且增加到更深层的提醒对模型的预测有更间接的影响。1.2.4.2 P-Tuning v2的试验后果应用的是BERT系列和GLM系列模型。P-Tuning v2是一种在不同规模和工作中都可与微调相媲美的提醒办法。在NLU工作中,整体上P-Tuning v2与全量微调的性能相差很小。2 抉择式办法选择性办法对模型的现有参数进行微调,能够依据层的深度、层类型或者甚至是个别参数进行抉择。2.1 BitFit2022年9月5日,BitFit呈现,这是一种稠密微调办法,仅批改模型的Bias(偏置项)或其中的子集。2.1.1 BitFit的特点 解冻大部分Transformer编码器的参数,只训练偏置项和工作特定的分类层。优化的偏置项参数包含Attention模块中计算Query、Key、Value时,计算MLP层时,计算Layernormalization层时遇到的偏置项参数。每个新工作只须要存储偏置项参数向量(占总参数数量的不到0.1%)和工作特定的最终线性分类器层。 2.1.2 BitFit的试验后果应用公开可用的预训练BERTBASE、BERTLARGE和RoBERTaBA模型。BitFit微调后果不迭全量参数微调,但在极少数参数可更新的状况下,远超Frozen(解冻模型参数)形式。3 从新参数化办法基于从新参数化的高效微调办法利用低秩示意来最小化可训练参数的数量,其中包含2021年10月到2023年3月间呈现的LoRA和AdaRoLA办法。3.1 LoRA该办法认为模型权重矩阵在特定微调后具备较低的本征秩,故基于秩合成的概念,将预训练模型的现有权重矩阵分成两个较小的矩阵。3.1.1 LoRA的特点将矩阵乘积BA加到原模型参数矩阵W上能够防止推理提早。可插拔的低秩合成矩阵模块,不便切换到不同的工作。3.1.2 LoRA的试验后果**应用的模型是RoBERTa、DeBERTa、GPT-2、GPT-3 175B。在多个数据集上,LoRA在性能上能和全量微调相近,且在某些工作上优于全量微调。**3.2 AdaLoRA3.2.1 AdaLoRA的特点**该办法基于权重矩阵的重要性而自适应调整不同模块的秩,节俭计算量,可了解为LoRA的升级版。AdaLoRA的做法是让模型学习SVD合成的近似。在损失函数中减少了惩办项,避免矩阵P和Q偏离正交性太远,以实现稳固训练。3.2.2 AdaLoRA的试验后果应用的模型是DeBERTaV3-base 和BART-large模型。AdaLoRA的性能通常高于参数量更高的办法。其中,AdaLoRA在0.32M微调参数时,在CoLA数据集上达到了70.04的Mcc分数。4 参数微调办法小结以上几类参数高效微调办法,各有千秋。Adapter办法在预训练模型的层中插入可训练模块的模式简略,但减少推理延时。Soft Prompts办法防止了人工“硬提醒”的局限性,却可能难收敛。Soft Prompts办法中,Prefix Tuning率先提出可用梯度降落法优化的的Tokens,而 P-Tuning、Prompt Tuning、P-Tuning v2相继作出不同的扭转,比方:退出的Tokens:P-Tuning仅限于输出层,而Prefix-Tuning在每一层都加。P-Tuning和Prompt Tuning仅将间断提醒插入到输出嵌入序列中,而Prefix Tuning的“软提醒”增加在每一个Transformer Block中。Prompt Tuning不须要额定的MLP来解决难训练的问题,P-Tuning v2移除了重参数化的编码器。 BitFit办法只更新模型外部偏置项参数所以训练参数量很渺小,但整体成果比LoRA、Adapter等办法弱。LoRA办法不存在推理延时,但无奈动静更新增量矩阵的秩,不过改进版AdaLoRA解决了这个问题。**5 AdaLoRA办法的试验5.1 试验模型为ChatGLM2-6B**官网代码在Git Clone https://github.com/THUDM/ChatGLM2-6B,可去Hugging Face下载其模型文件。利用AdaLoRA之后的模型训练参数仅占总参数的0.0468%。5.2 试验数据为中文医疗问答数据下载链接为https://github.com/Toyhom/Chinese-medical-dialogue-data,包含儿科、内科等问答数据,数据中会有倡议去医院看病之类的文字。此处选取儿科和内科的数据别离10000条数据作为训练数据集,将文件保留为json格局。5.2.1 结构数据集文件为dataset.py。5.2.2 训练代码文件为FT.py。配置文件config_accelerate.yml执行文件run.sh5.2.3 测试代码后果为:6 结语除了以上3大类办法之外,还有混合参数高效微调办法,其是综合了多种PEFT类别思维的办法。比方MAM Adapter同时联合了Adapter和Prompt-Tuning的思维,UniPELT综合了LoRA、Prefix Tuning和Adapter的思维。混合参数高效微调办法大概率优于单个高效微调办法,但训练参数和推理延时的都减少了。下次将会对大模型的减速并行框架进行探讨,欢送大家继续关注!相干文章[1]《Scaling Down to Scale Up: A Guide to Parameter-Efficient Fine-Tuning》[2]《Parameter-Efficient Transfer Learning for NLP》[3]《Prefix-Tuning: Optimizing Continuous Prompts for Generation》[4]《GPT Understands, Too》[5]《The Power of Scale for Parameter-Efficient Prompt Tuning》[6]《P-Tuning v2: Prompt Tuning Can Be Comparable to Fine-tuning Universally Across Scales and Tasks》[7]《BitFit: Simple Parameter-efficient Fine-tuning for Transformer-based Masked Language-models》[8]《LoRA: LOW-RANK ADAPTATION OF LARGE LANGUAGE MODELS》[9]《ADAPTIVE BUDGET ALLOCATION FOR PARAMETEREFFICIENT FINE-TUNING》

September 26, 2023 · 1 min · jiezi

关于后端:AnsibleFATE部署过程

前言基本上依照官网文档就行了,先做before deploy,再做three side guide.md。 以下是可能呈现的问题这个AnsibleUndefinedVariable: ‘ansible_ssh_host‘ is undefined.是必定会遇到的,参考我这篇 安全性限度ansible提醒 warning: now open files is 1024, and need to turn up tp 64000,warning: now max user process is 1024, and need to turn up tp 64000依据官网手册,在(每一个机器的)配置文件/etc/security/limits.conf和/etc/security/limits.d/20-nproc.conf写入``即可。我关上的时候文件外面排列的整整齐齐的,我倡议也手动空格跟他们一样参差。 批改实现后有可能虚拟机的内存不够大,依然会呈现这个warning,此时须要把虚拟机内存调大,18G左右就够用了。 sudo passwordansible日志呈现 msg:missing sudo password批改增加Ansible_project_path/environment/prod/hosts中的ansible_become_pass=为sudo的明码(不是root明码,是转换为sudo的本账户明码)。如果你是装置官网文档新建的app用户的话,那app应该是不在sudoer file外面的,这个都加进去sudoer就行了,能够参考这个。 呈现no erlang package matchingansible日志呈现 no package matching erlang found available。 yum install epel-release,或者用其余办法装置epel即可。 python tools报错报错信息no module named pkg_resources日志信息failed to import the required python libarary(seuptools) on xx's python /usr/bin/python. please read the module documentation and install it in the appropriate location. If the required library is installed, but Ansible is using the wrong Python interpreter, please consult the document on ansible_python_interpreter ...

September 26, 2023 · 1 min · jiezi

关于后端:LeetCode-mysql-刷题六指定日期的产品价格3种方法处理未查询到日期

题目题目链接:指定日期的产品价格 编写一个解决方案,找出在 2019-08-16 时全副产品的价格,假如所有产品在批改前的价格都是 10 。 以 任意程序 返回后果表。 后果格局如下例所示。 输出:Products 表:+------------+-----------+-------------+| product_id | new_price | change_date |+------------+-----------+-------------+| 1 | 20 | 2019-08-14 || 2 | 50 | 2019-08-14 || 1 | 30 | 2019-08-15 || 1 | 35 | 2019-08-16 || 2 | 65 | 2019-08-17 || 3 | 20 | 2019-08-18 |+------------+-----------+-------------+(product_id, change_date) 是此表的主键(具备惟一值的列组合)。这张表的每一行别离记录了 某产品 在某个日期 更改后 的新价格。输入:+------------+-------+| product_id | price |+------------+-------+| 2 | 50 || 1 | 35 || 3 | 10 |+------------+-------+Create table If Not Exists Products (product_id int, new_price int, change_date date);Truncate table Products;insert into Products (product_id, new_price, change_date) values ('1', '20', '2019-08-14');insert into Products (product_id, new_price, change_date) values ('2', '50', '2019-08-14');insert into Products (product_id, new_price, change_date) values ('1', '30', '2019-08-15');insert into Products (product_id, new_price, change_date) values ('1', '35', '2019-08-16');insert into Products (product_id, new_price, change_date) values ('2', '65', '2019-08-17');insert into Products (product_id, new_price, change_date) values ('3', '20', '2019-08-18');解析这题考查的点是如何查出 product_id 为 3 的数据,因为这个产品在 2019-08-16 之前没有批改过价格 ...

September 26, 2023 · 3 min · jiezi

关于后端:JDK安装与配置教程来啦

JDK装置与配置教程如下:1.从Oracle公司官网下载JDK安装文件。官网地址为:http://www.oracle.com/technetwork/java/javase/downloads/index...目前最新版本是JDK21,上面就以JDK21举例。 2.须要登录Oracle账户,没有的注册一下就行了。 3.在确认装置的盘符(例如:E盘)新建文件夹,取名为Java。 4.双击下载的JDK安装文件进行装置。 5.配置JAVA环境变量,点击我的电脑,找到高级零碎设置,点击环境变量。 6.在零碎变量中,新建JAVA_HOME变量名"JAVA_HOME",变量值"E:\Program Files(X86)\Java\jdk-21"(即你方才装置JDK的装置门路)。 7.新建CLASSPATH变量名"CLASSPATH",变量值".;%JAVA_HOME%\lib;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar"。 8.找到变量名Path,点击编辑,点击新建,而后输出:“%JAVA_HOME%\bin”,点击确定,再次点击"新建",而后输出上"%JAVA_HOME%\jre\bin",点击确定。

September 26, 2023 · 1 min · jiezi

关于后端:Redis类型Type与编码Encoding

本文已收录至GitHub,举荐浏览 Java随想录 微信公众号:Java随想录 原创不易,重视版权。转载请注明原作者和原文链接Redis是一款开源的高性能key-value数据库,广泛应用于各种场景。在Redis中, 数据类型(Type)和编码(Encoding) 是十分重要的概念。本篇博客将具体介绍Redis反对的数据类型以及相应的编码方式和底层实现原理。 要查看Redis某个key的外部编码,能够应用Redis自带的命令OBJECT ENCODING key。 其中,key是你想要查问的键名。例如,如果你想要查问名为mykey的键的外部编码,能够执行以下命令: 127.0.0.1:6379> object encoding mykey // 查看某个Redis键值的编码redisObject在Redis中,redisObject 是一个十分重要的数据结构,它用于保留字符串、列表、汇合、哈希表和有序汇合等类型的值。以下是对于 redisObject 构造体的定义: typedef struct redisObject { unsigned type:4; unsigned encoding:4; unsigned lru:24; /* lru time (relative to server.lruclock) */ int refcount; void *ptr;} robj;各个属性解析如下: type:用于标识对象所属的类型,别离是 REDIS_STRING、REDIS_LIST、REDIS_SET、REDIS_ZSET 和 REDIS_HASH 等。encoding: 用于标识对象外部的编码方式, 如 REDIS_ENCODING_INT、REDIS_ENCODING_HT、REDIS_ENCODING_ZIPMAP 等。lru:这个字段记录了对象被命令调用的工夫, 它是缓存淘汰策略(LRU)的一部分。refcount:援用计数,当 refcount 缩小到0时,对象就能够被清理并回收内存。ptr:一个指针,依据对象的类型和编码方式的不同,这个指针可能会指向各种不同的类型,比方整数、动静字符串、链表、字典等。其中,redisObject的encoding取值有如下几种: #define OBJ_ENCODING_RAW 0 //简略动静字符串,用于保留键值对的键和配置文件中的参数。#define OBJ_ENCODING_INT 1 //整型值,用于优化小整数的内存应用。#define OBJ_ENCODING_HT 2 //哈希表,用于存储一般哈希对象的字段和值。#define OBJ_ENCODING_ZIPMAP 3 //缩字典,这是一种非凡类型的哈希表,用于优化小哈希对象的内存应用。#define OBJ_ENCODING_LINKEDLIST 4 //双端链表,用于存储列表键。#define OBJ_ENCODING_ZIPLIST 5 //压缩列表,用于优化小列表或者小哈希对象的内存应用。#define OBJ_ENCODING_INTSET 6 //整数汇合,用于优化只蕴含整数元素的汇合的内存应用。#define OBJ_ENCODING_SKIPLIST 7 //跳跃表和字典,用于存储有序汇合键。#define OBJ_ENCODING_EMBSTR 8 //对于长度小于44字节的字符串,Redis抉择应用此非凡的编码方式。#define OBJ_ENCODING_QUICKLIST 9 //对于列表对象(list object)的一种编码方式。quicklist是ziplist和双向链表的混合体。Type与Encoding介绍Redis反对五种次要的数据类型:字符串(String)、列表(List)、汇合(Set)、有序汇合(Sorted Set)和哈希(Hash)。 ...

September 26, 2023 · 1 min · jiezi

关于后端:面试题精讲Java-和-C-的区别

有的时候博客内容会有变动,首发博客是最新的,其余博客地址可能会未同步,认准https://blog.zysicyj.top首发博客地址 文章更新打算 系列文章地址 1. Java 和 C++ 是什么?Java 和 C++都是风行的编程语言,用于开发各种类型的应用程序。它们具备不同的特点和用处。 Java:Java 是一种面向对象的高级编程语言,最后由 Sun Microsystems 开发,并且当初由 Oracle 保护。Java 被设计为可移植、跨平台的语言,能够在不同的操作系统上运行。它宽泛用于 Web 应用程序、企业级应用程序、挪动应用程序等畛域。C++:C++是一种通用的编程语言,扩大自 C 语言。它反对面向对象编程和底层零碎编程,并提供了更多的管制和性能优化选项。C++被宽泛用于游戏开发、嵌入式零碎、高性能计算等畛域。2. Java 和 C++ 的次要区别Java 和 C++之间存在以下几个次要区别: 内存治理:Java 应用主动内存管理机制(垃圾回收器),开发者无需手动调配和开释内存。而 C++须要手动治理内存,包含显式地调配和开释内存,这可能导致内存透露和悬挂指针等问题。安全性:Java 具备弱小的安全性机制,包含字节码验证、平安沙箱和访问控制等。这使得 Java 在网络环境中更加平安,能够避免恶意代码的执行。C++没有内置的安全性机制,开发者须要本人解决平安问题。跨平台性:Java 是一种齐全可移植的语言,编写的 Java 程序能够在不同的操作系统上运行。而 C++的可移植性较差,因为它依赖于底层操作系统和硬件个性。面向对象编程:Java 是一种纯正的面向对象编程语言,所有的代码都必须位于类中。C++也反对面向对象编程,但同时也容许应用传统的过程式编程格调。性能:因为 Java 的垃圾回收机制和其余运行时个性,绝对于 C++来说,Java 的性能可能会稍低一些。然而,随着 JVM(Java 虚拟机)的改良和优化,Java 的性能正在逐步晋升。3. Java 和 C++ 的实用场景Java 和 C++在不同的应用领域有各自的劣势: Java:因为其跨平台性、安全性和易学性,Java 广泛应用于 Web 开发、企业级应用程序、挪动应用程序等畛域。它也是 Android 利用开发的次要语言。C++:因为其性能和底层零碎编程能力,C++罕用于游戏开发、嵌入式零碎、高性能计算等须要对硬件进行间接管制的畛域。4. Java 和 C++ 的共同点只管 Java 和 C++有很多不同之处,但它们也有一些共同点: 面向对象编程:Java 和 C++都反对面向对象编程范式,并提供类、继承、多态等个性。丰盛的规范库:Java 和 C++都有丰盛的规范库,提供了各种性能和工具,不便开发者应用。宽泛的社区反对:Java 和 C++都有宏大的开发者社区,能够取得丰盛的资源、文档和反对。无论抉择 Java 还是 C++,都取决于我的项目需要、开发团队的技术背景以及集体偏好。 ...

September 26, 2023 · 1 min · jiezi