math toolkit for real-time development读书笔记一-三角函数快速计算(1)
一、基础知识
根据高中知识我们知道,很多函数都可以用泰勒级数展开。正余弦泰勒级数展开如下:
将其进一步抽象为公式可知:
正弦和余弦的泰勒级数具有高度结构化的模式,可拆解为以下核心特征:
1. 符号交替特性
- 正弦级数:项的符号以
交替,即 +,−,+,−,…
- 余弦级数:符号同样由
控制,但首项为正(n=0 时),即 +,−,+,−,…
作用:正负项交替抵消了部分累积误差,避免数值无意义地发散(如大角度场景中,若所有项同号,和会迅速溢出)。
2. 幂次规律
- 正弦:包含 x 的奇次幂(
…),对应通项中的 2n+1。
- 余弦:包含 x 的偶次幂(
…),对应通项中的 2n(注意
=1 为首项)。
直观理解:正弦是奇函数(仅含奇次幂),余弦是偶函数(仅含偶次幂),与函数的奇偶性代数定义一致。
3. 分母的阶乘主导
- 分母为分子指数的阶乘,即奇次幂项分母为 (2n+1)!,偶次幂项为 (2n)!。
- 阶乘的超指数增长:例如 10!=3,628,800,20!≈
,远快于
的增长(即使 x 较大)。
关键作用:确保级数对任意 x 收敛,且小角度下项值急剧衰减(如 x=π/6 时,第 3 项已小于)。
在任何计算机数学的教科书或手册中,你也都会找到这些函数的定义和相关性质。然而仅有公式并不足以在实际应用中解决问题。公式是基础,但只有结合计算特性的优化,才能真正解决现实问题。
如果直接利用泰勒级数进行计算,将遇到几方面的问题:
- 阶乘的计算边界:在编程中,n! 很快会超出数值类型范围(如 32 位整数最大表示 20!),需使用浮点类型或大数库,或通过递推避免显式计算阶乘。
- 机器精度的限制:计算机无法表示无限精度,当项值小于机器的最小精度时,其对总和的贡献在数值上为零,此时截断级数是合理的。
无穷级数的问题在于它们…… 嗯…… 是无穷的。如果我有一台无限算力的计算机和无限的时间,我现在就可以结束跳过后续的内容,关上电脑愉快的下班各回各家各找各妈了。
但在现实世界中,你不可能等待计算无穷多项。计算机也无法处理无限项计算。以 sin(1000) 为例,直接展开需数千项才能使阶乘主导项衰减,而单精度浮点数在计算前几项时就会因 xn 过大而溢出(如 =
,已接近单精度上限
)。幸运的是,你也不需要无限的精度。计算机中的任何实数都只是一个近似值,受限于计算机的字长。当计算机依次计算级数中的高阶项时,这些项最终会变得小于计算机的位分辨率。在那之后,计算更多的项就毫无意义了。
在这个级数中,随着 n 的增大,各项变得越来越小,但级数的和却是无穷大。数学家们必然且确实会关注幂级数的收敛性;不过请放心,如果有人给出一个如 sin (x) 这样的函数的级数展开式,他们必定已确保其收敛性。对于正弦和余弦函数,符号交替的特性确保了小项不会累积成大的数值。
如果高阶项变得可以忽略不计,你可以截断级数以获得多项式近似。处理任何无穷级数时都必须这样做。有时你可以估算引入的误差,但大多数情况下,程序员只需保留足够多的项,以确保误差控制在合理范围内。
通过一个例子来理解可能更直观。表 5.1计算了 x=30∘(即 π/6 弧度)的正弦和余弦值。在所示的精度范围内,两个级数在第五项后均已收敛(由于余弦项的每一项比正弦项少一个 x 的幂次,其收敛速度通常稍慢)。正如预期,由于分母中阶乘的存在,各项的绝对值迅速减小。
项数n | 正弦项 | 正弦项累加和 |
0 | 0.52359878 | |
1 | 0.49980235 | |
2 | 0.50013697 | |
3 | 0.50013440 | |
4 | 0.50013441 | |
真实值 | sin(π/6)=0.5 | 误差: |
项数n | 余弦项 | 余弦项累加和 |
0 | 1 | |
1 | 0.86292813 | |
2 | 0.86571844 | |
3 | 0.86568546 | |
4 | 0.86568585 | |
真实值 | cos(π/6)=0.8660254 | 误差: |
对于三角函数的任何实际计算,最终结果都要求我必须限制 x 的范围,就像我对平方根函数所做的那样。显然,范围越小,所需的项数就越少。我还没有向你展示如何限制范围,但暂时假设这是可以做到的。那么需要多少项呢?
在这种情况下,计算所需的项数相当直接。由于级数中的项具有交替的符号,我不必担心诸如许多小数项累加为大数之类的潜在问题。正如你在表 5.1 中看到的,中间结果围绕最终结果振荡。因此,我可以确定误差总是小于(有时远小于)第一个被忽略项的大小。我需要做的就是为角度范围的代表性值计算方程中每个项的值,然后将结果与我所使用的数值表示中的最低有效位(LSB)精度进行比较。由于我无法预先知道你可能使用的数值格式,因此最好将这两个步骤分开。项值如表 5.2 和 5.3 所示。请注意,对于更小的范围,误差减小得有多显著。
在表 5.4 和 5.5 中,我使用这些结果计算了典型计算机表示所需的项数。通常,预期尾数范围为 24 位(32 位浮点数)或 56 位(C 语言双精度使用的八字节格式)。较小的数值有时在专用嵌入式系统中有用,而最大的数值对应双精度和数值协处理器的字长。同样,只需看一眼这些表格,你就会相信,花一些计算能力来减少输入参数的范围是值得的。
既然我已经知道需要在截断级数中包含多少项,接下来仍需设计代码对其进行计算。缺乏经验的程序员可能会直接按方程 [5.7] 的写法进行编程,为每一项反复计算和n!。一个简单的停止准则可能只是将每一项的值与某个误差准则进行比较(在这种情况下,表 5.2 至 5.5 并非必需)。
事实上,这正是我最初实现该函数的方式,只是为了证明自己能够做到。这是一个糟糕的实现,因为它需要反复将x提升到越来越高的幂次,更不用说为每一项调用两个耗时函数的开销了。诚然,该函数对任何输入(无论多大)都能给出正确答案,但付出的运行时性能代价却非常高昂。
double factorial(unsigned long n){
double retval = 1.0;
for(; n>1; --n)
retval *= (double)n;
return retval;
}
double sine(double x){
double first_term;
double next_term = x;
double retval = x;
double sign = 1.0;
double eps = 1.0e-16;
int n = 1;do{
cout << next_term << endl;
first_term = next_term;
n += 2;
sign *= -1.0;
next_term = sign * pow(x, n)/factorial(n);
retval += next_term;
}
while((abs(next_term) > eps));
return retval;
}
通过观察到每一项都可以由前一项递推计算,我们可以显著优化代码效率。回顾方程 [5.9] 中正弦函数的通项公:
该级数的下一项时:
前后项相比知;
我们以代表其比值:
改进版本消除了对 pow () 和 factorial () 的调用。此版本如下代码所示。
double sine(double x){
double last = x;
double retval = x;
double eps = 1.0e-16;
long n = 1;
do{
n += 2;
last *= (-x * x/((double)n * (double)(n-1)));
retval += last;
}
while((abs(last) > eps));
return retval;
}
如上 中的代码效率尚可,许多人可能想就此打住。然而,这个函数的实现方式仍然相当糟糕。我可以通过仅计算一次 x² 来稍作改进,但还有一种更好的方法 —— 方程 [5.11] 中的关系给出了线索:每一项都是下一项的一个因子。事实上,这甚至包括值 x,它存在于每一项中。因此,我可以将方程 [5.7] 和 [5.8] 因式分解为:
这种公式化方法被称为霍纳法则,它几乎是计算该级数的最优方式。请注意,每一步的分母都是两个连续整数的乘积 —— 在正弦级数中为 2×3、4×5、6×7,等等。一旦你发现这一规律,就能凭记忆写出这些函数的计算式。如果无法使用现成的正弦函数,而你又急需一个,直接对这两个方程进行编码其实相当不错。
不过仍有几个细节需要解决。首先,我遇到一个小问题:由于必须保存所有中间结果,所示方法会占用大量栈空间。如果你的编译器是高度优化的,或者你不介意栈空间消耗,这不会有问题。但如果你使用的是简单编译器和 80x87 数学协处理器,你会像我一样很快发现,协处理器可能会发生栈溢出。
式5-12可以重新改写为:
但对于计算机实现而言,我可以通过另一轮变换消除一半的符号变化。这可能并不明显,但如果我仔细地将所有前导负号折叠到括号内的表达式中,就能得到等效的形式。
这已经是相当高效的实现方式了。这些方程虽然看起来不简洁,但计算速度非常快。就像我可以在方程 [5.12] 和 [5.13] 的右侧添加更多项一样,也可以在方程 [5.15] 和 [5.16] 的左侧添加项。只需记住,这次符号是交替变化的,从右端显示的正号开始。
如下代码展示了这些方程的直接实现。所使用的项数适用于 32 位浮点精度和 ±45° 的范围。由于大多数计算机执行乘法的速度比除法快,我通过将常数存储为其倒数来调整了算法(不用担心涉及常数的表达式,大多数编译器会对这些部分进行优化)。注意名称前添加的下划线,这是为了强调(双关语)这些函数仅在有限范围内有用的事实。我会在后面的全范围版本中使用这些函数。
// Find the Sine of an Angle <= 45
double _sine(double x){
double s1 = 1.0/(2.0*3.0);
double s2 = 1.0/(4.0*5.0);
double s3 = 1.0/(6.0*7.0);
double s4 = 1.0/(8.0*9.0);
double z = x * x;
return ((((s4*z-1.0)*s3*z+1.0)*s2*z-1.0)*s1*z+1.0)*x;
}
// Find the Cosine of an Angle <= 45
double _cosine(double x){
double c1 = 1.0/(1.0*2.0);
double c2 = 1.0/(3.0*4.0);
double c3 = 1.0/(5.0*6.0);
double c4 = 1.0/(7.0*8.0);
double z = x * x;
return (((c4*z-1.0)*c3*z+1.0)*c2*z-1.0)*c1*z+1.0;
}
第二个细节?我悄悄省去了一个用于判断使用多少项的测试。由于必须从内到外计算霍纳法则,你必须知道 “内部” 从哪里开始。这意味着你不能在计算过程中测试各项;必须预先知道需要多少项。在这种情况下,对于小的 x 值,霍纳法则的额外效率抵消了跳过内部项计算可能获得的任何收益。这一结果与第 4 章中关于平方根的讨论得出的结论相似:有时固定次数地计算某些内容会更简单(而且通常更快),而不是测试某个终止条件。如果这能让你更放心,可以为 x 非常接近零的特殊情况添加一个测试;否则,最好计算完整的表达式。
你可能想知道,既然我已经在方程 [5.5] 中表明余弦可以由正弦推导而来,为什么还要同时包含正弦和余弦函数。原因很简单:即使你只对其中一个函数感兴趣,实际上也需要能够计算这两个函数。当结果接近零时,一种近似最准确;当结果接近一时,另一种近似最准确。根据输入值的不同,你最终会使用其中一种或另一种。
霍纳法则的计算必须从内到外逐层展开,这意味着无法在循环中动态判断项数,必须预先确定需要计算的项数。这一限制带来两个关键问题:
1. 为何放弃动态项数测试?
- 霍纳法则的结构性限制:其嵌套乘法形式(如 sin(x)=x⋅(1−3!x2⋅(1−5×4x2⋅(⋯))))要求先计算最内层项,再向外逐层展开。若在计算中动态判断是否终止(如 “当项值小于误差阈值时停止”),需存储所有中间层结果,这会抵消霍纳法则的空间优化优势。
- 小角度场景的效率平衡:对于小 x(如 x≈0),级数收敛极快,理论上只需 1-2 项即可满足精度。但预定义固定项数(如 4 项)的计算成本可能低于动态测试的判断开销(如条件分支、浮点比较)。正如第 4 章平方根计算的结论:固定次数的计算有时比动态终止更高效。
为何同时实现正弦与余弦函数?
尽管余弦可通过正弦推导(cos(x)=sin(2π−x)),但独立实现两者仍有必要:
1. 精度互补性
- 正弦在 0 附近更精确:当 x≈0 时,正弦级数首项 x 直接逼近真实值,而余弦级数首项为 1,次项 −2x2 对小 x 的修正量极小,需更多项才能达到同等精度。
- 余弦在 2π 附近更精确:当 x≈2π 时,余弦值接近 0,其级数收敛更快;而正弦值接近 1,需更多项修正首项 x 的较大偏差。
2. 输入范围的动态选择
- 根据输入 x 的范围选择计算路径:
- 若 x 靠近 kπ(正弦主导区间),优先计算正弦,再通过三角恒等式推导余弦。
- 若 x 靠近 kπ+2π(余弦主导区间),直接计算余弦更高效。
- 避免大角度误差累积:例如,计算 cos(179∘) 时,若通过 sin(1∘) 推导,需先将 179∘ 约简为 1∘,再调用正弦函数。此过程可能引入额外的约简误差,而直接计算余弦可避免中间步骤
至此,我已证明如果输入参数的范围可以限制,就能实现一个良好且高效的正弦函数。接下来需要说明的是,我确实可以限制范围。
相关文章:
math toolkit for real-time development读书笔记一-三角函数快速计算(1)
一、基础知识 根据高中知识我们知道,很多函数都可以用泰勒级数展开。正余弦泰勒级数展开如下: 将其进一步抽象为公式可知: 正弦和余弦的泰勒级数具有高度结构化的模式,可拆解为以下核心特征: 1. 符号交替特性 正弦级…...
超市营业额数据分析
1.推出5名销冠 2.新领导想看看他15天以来的业绩总增长情况,以及增长额前3的柜台 3.把所有柜台的销售额分为3个等级 import pandas as pd import matplotlib.pyplot as plt import numpy as np# 设置中文字体和显示方式 plt.rcParams.update({font.sans-serif&...
labelimg安装及使用指南(yolo)
1.安装 首先要安装Anaconda,然后打开Anaconda Prompt 构建一个新的虚拟环境(注:虚拟环境的python的版本应在3.9及以下,不然会在运行中报错) conda create -n label python3.9 其中这里label只是一个名字,…...
在 Ubuntu 系统中,将 JAR 包安装为服务
在 Ubuntu 系统中,将 JAR 包安装为服务可以通过 systemd 来实现。以下是详细的操作步骤: 准备工作 确保 JAR 文件路径和 Java 运行时环境已准备好。验证 Java 是否可用: java -version创建 systemd 服务文件 systemd 的服务文件通常位于 …...
我的 PDF 工具箱:CodeBuddy 打造 PDFMagician 的全过程记录
我正在参加CodeBuddy「首席试玩官」内容创作大赛,本文所使用的 CodeBuddy 免费下载链接:腾讯云代码助手 CodeBuddy - AI 时代的智能编程伙伴 最近,我萌生了一个念头:能不能自己动手做一个功能丰富的 PDF 工具箱?市面上…...
WebSocket聊天室的简单制作指南
一、前言 最近在学习WebSocket技术,做了一个简单的聊天室Demo。这个项目虽然不大,但涵盖了WebSocket的核心功能实现。下面我将详细介绍这个聊天室的实现过程,希望能帮助到同样想学习WebSocket的朋友们。 二、技术选型 后端:Spri…...
非国产算力DeepSeek 部署中的常见问题及解决方案
随着大语言模型(LLM)在企业级应用场景中的快速推进,DeepSeek 一体机凭借其高性能推理能力和便捷的系统集成优势,正逐步成为多行业智能化转型的重要基础设施。然而,在实际部署过程中,技术团队常常会遭遇一系…...
大数据技术的主要方向及其应用详解
文章目录 一、大数据技术概述二、大数据存储与管理方向1. 分布式文件系统2. NoSQL数据库3. 数据仓库技术 三、大数据处理与分析方向1. 批处理技术2. 流处理技术3. 交互式分析4. 图计算技术 四、大数据机器学习方向1. 分布式机器学习2. 深度学习平台3. 自动机器学习(AutoML) 五、…...
Maven使用详解:Maven的概述(二)
一、核心定义与功能 Maven是由Apache软件基金会开发的开源项目管理工具,专为Java项目设计,主要用于自动化构建、依赖管理和项目标准化。其核心功能包括: 依赖管理:通过pom.xml文件声明依赖库,自动从中央仓库下载并管…...
在 Odoo 18 表单视图中使用 JS 类的方法
在 Odoo 18 表单视图中使用 JS 类的方法 一、模块结构创建 要为特定视图在 JavaScript 里注册一个类。后续在任意表单视图中添加相同类时,自定义视图就会被注入该表单。 具体要做的是: 把自定义视图创建出来当作模板。将视图注册成一个组件。把它和表…...
ubuntu 更新华为源
1. 备份配置文件 sudo cp -a /etc/apt/sources.list /etc/apt/sources.list.bak 2. 修改source.list 文件,将http://archive.ubuntu.com和http://security.ubuntu.com替换成http://repo.huaweicloud.com,可以参考如下命令: # 第一条指令 s…...
如何安装cuda版本的pytorch
为什么安装Cuda 对于做深度学习研究的小伙伴本,当我们处理大量的数据时,尤其是图像数据时,过量的数据会导致我们的CPU运行压力过大,占用大量的运行内存,而且用CPU进行模型训练,训练的时间会很长࿰…...
国际名校教育大模型的构建与教学应用实践
一、引言 全球AI数字教育正在快速发展,人工智能技术已成为推动教育变革的核心驱动力。从个性化学习到智能评测,从虚拟助教到自适应教学系统,AI正在重塑教育的形态。在此背景下,国际顶尖高校纷纷布局教育大模型,探索AI与教学的深度融合,以提升教育质量、优化学习体验。与…...
postgres的docker版本安装
postgres的docker版本安装 背景 测试和开发需要用到postgres,越快越好,想到了用docker进行安装。 sudo docker run -d -p 5432:5432 --restartalways -v /home/docker/postgre/data:/var/lib/postgresql/data -e POSTGRES_PASSWORD123456 --name p…...
知识蒸馏实战:用PyTorch和预训练模型提升小模型性能
在深度学习的浪潮中,我们常常追求更大、更深、更复杂的模型以达到最先进的性能。然而,这些“庞然大物”般的模型往往伴随着高昂的计算成本和缓慢的推理速度,使得它们难以部署在资源受限的环境中,如移动设备或边缘计算平台。知识蒸…...
【HTML 全栈进阶】从语义化到现代 Web 开发实战
目录 🌟 前言🏗️ 技术背景与价值🩹 当前技术痛点🛠️ 解决方案概述👥 目标读者说明 🧠 一、技术原理剖析📊 核心概念图解💡 核心作用讲解🔧 关键技术模块说明⚖️ 技术选…...
Transformer 模型与注意力机制
目录 Transformer 模型与注意力机制 一、Transformer 模型的诞生背景 二、Transformer 模型的核心架构 (一)编码器(Encoder) (二)解码器(Decoder) 三、注意力机制的深入剖析 …...
机器学习数据预处理回归预测中标准化和归一化
在机器学习的回归预测任务中,** 标准化(Standardization)和归一化(Normalization)** 是数据预处理的重要步骤,用于消除不同特征量纲和取值范围的影响,提升模型训练效率和预测性能。 一、标准化…...
B2C 商城转型指南:传统企业如何用 ZKmall模板商城实现电商化
在数字化浪潮席卷全球的当下,传统企业向电商转型已不再是选择题,而是关乎生存与发展的必答题。然而,缺乏技术积累、开发成本高、运营经验不足等问题,成为传统企业转型路上的 “拦路虎”。ZKmall模板商城以其低门槛、高灵活、强适配…...
FPGA:Lattice的FPGA产品线以及器件选型建议
本文将详细介绍Lattice Semiconductor的FPGA产品线,帮助你了解各系列的特点和适用场景,以便更好地进行选型。Lattice以低功耗、小尺寸和高性能为核心,产品覆盖低中端市场,广泛应用于通信、计算、工业、汽车、消费电子、嵌入式视觉…...
学习51单片机02
吐血了,板子今天才到,下午才刚开始学的,生气了,害我笔记都断更了一天。。。。 紧接上文...... 如何将HEX程序烧写到程序? Tips:HEX 文件是一种常用于单片机等嵌入式系统的文件格式,它包含了程序的机器码…...
武汉SMT贴片工艺优化与生产效能提升路径
内容概要 随着华中地区电子制造产业集群的快速发展,武汉SMT贴片行业面临工艺升级与效能提升的双重挑战。本文聚焦SMT生产全流程中的关键环节,从钢网印刷精度控制、回流焊温度曲线优化、AOI检测系统迭代三大核心工艺出发,结合区域产业链特点提…...
LineBasicMaterial
LineBasicMaterial 描述 用于绘制纯色线条的基础材质,支持颜色、线宽和纹理映射。常用于THREE.Line或THREE.LineSegments几何体。 构造函数 (Constructor) 构造函数参数描述LineBasicMaterial(parameters?: Object)parameters定义材质外观的对象,可…...
虚拟机安装达梦数据库
准备 关闭SELINUX # setenforce 0 # vi /etc/selinux/config 修改SELINUXdisabled 上传达梦ISO 接下下载的达梦安装包,里面包含一个ISO文件,将其上传到CentOS的/tmp路径下安装达梦所需图形类库 # yum install -y gtk2 libXtst xorg-x11-…...
小波变换+注意力机制成为nature收割机
小波变换作为一种新兴的信号分析工具,能够高效地提取信号的局部特征,为复杂数据的处理提供了有力支持。然而,它在捕捉数据中最为关键的部分时仍存在局限性。为了弥补这一不足,我们引入了注意力机制,借助其能够强化关注…...
科技项目验收测试对软件产品和企业分别有哪些好处?
科技项目验收测试是指在项目的开发周期结束后,针对项目成果进行的一系列验证和确认活动。其目的是确保终交付的产品或系统符合预先设定的需求和标准。验收测试通常包括功能测试、性能测试、安全测试等多个方面,帮助企业评估软件在实际应用中的表现。 科…...
ChatGPT到Claude全适配:跨模型Prompt高级设计规范与迁移技巧
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习内容,尽在聚客AI学院。 一. 迭代优化:基于反馈的Prompt进化策略 1.1 优化闭环设计 初始Prompt → 生成结果 → 人工评估 → 问题分析 → 改进Prompt 代码示例&#x…...
NexBot AI 1.9.3 | 专业AI写作助手,高自由度定制内容,支持中文设置
NexBot AI是一款强大的人工智能助手应用程序,旨在帮助用户快速生成符合其需求的内容。通过高自由度的关键词和短语合并功能,用户可以根据自己的具体要求定制内容。该应用能够迅速生成多种输出结果供用户选择,非常适合需要高效工作流程的专业人…...
foxmail - foxmail 启用超大附件提示密码与帐号不匹配
foxmail 启用超大附件提示密码与帐号不匹配 问题描述 在 foxmail 客户端中,启用超大附件功能,输入了正确的账号(邮箱)与密码,但是提示密码与帐号不匹配 处理策略 找到 foxmail 客户端目录/Global 目录下的 domain.i…...
eVTOL、无人机电机功耗图和电机效率图绘制测试
测功机是测量电机性能的绝佳工具。通过施加可控负载,测功机可表征电机扭矩、转速和功率。但这是获取电机性能全面理解的唯一途径吗?我们想知道,能否仅通过电机-螺旋桨动力测试台(而非传统制动测功机)实现电机性能测绘。…...
React中useMemo和useCallback的作用:
一、useMemo 基本用法: useMemo 是 React 提供的一个 Hook,用于性能优化,它通过"记忆"(memoization)计算结果来避免在每次渲染时进行不必要的复杂计算。 const memoizedValue useMemo(() > computeExpensiveValue…...
【Shell的基本操作】
文章目录 一、实验目的二、实验环境三、实验内容3.1 Shell变量与脚本基础3.2 定制终端提示符(PS1变量)3.3 文件查找与类型确认(find命令)3.4 管道命令实战(用户登录统计)3.5 交互式备份压缩脚本 四、总结4.…...
部署docker上的redis,idea一直显示Failed to connect to any host resolved for DNS name
参考了https://blog.csdn.net/m0_74216612/article/details/144145127 这篇文章,关闭了centos的防火墙,也修改了redis.conf文件,还是一直显示Failed to connect to any host resolved for DNS name。最终发现是腾讯云服务器那一层防火墙没…...
Android 中 显示 PDF 文件内容(AndroidPdfViewer 库)
PDFView 是一个用于在 Android 应用中显示 PDF 文档的库。它提供了丰富的功能和灵活的配置选项,使得开发者能够轻松地在应用中嵌入 PDF 阅读器。 一、 添加依赖 在模块的 build.gradle 文件中添加以下依赖: // pdfimplementation("com.github.bar…...
Linux 系统切换国内镜像源教程
在中国大陆使用 Linux 系统时,由于网络环境的原因,连接官方的软件包镜像源速度较慢,甚至可能出现连接失败的情况。此时,将系统配置为使用国内的镜像源可以显著提升软件包下载和更新的速度。 常见的国内镜像源 阿里云镜像站: htt…...
4.2.3 Thymeleaf标准表达式 - 2. 选择表达式
本实战通过 Thymeleaf 的选择表达式(*{})演示了如何在模板中操作和展示对象的属性与方法。首先,在控制器中创建了一个 User 对象,并将其添加到模型中。接着,在 test2.html 模板中,通过 th:object 声明了对象…...
C#学习第23天:面向对象设计模式
什么是设计模式? 定义:设计模式是软件开发中反复出现的特定问题的解决方案。它们提供了问题的抽象描述和解决方案。目的:通过提供成熟的解决方案,设计模式可以加快开发速度并提高代码质量。 常见的设计模式 设计模式通常分为三大…...
【数据结构】二分查找-LeftRightmost
查找: Leftmost(最左侧重复元素) package 二分查找;public class BinarySearch {public static void main(String[] args) {// TODO Auto-generated method stub}public static int binarySearchBasic(int[] a,int target) {int i0,ja.length-1; //设置指针初值in…...
汽车装配又又又升级,ethernetip转profinet进阶跃迁指南
1. 场景描述:汽车装配线中,使用EtherNet/IP协议的机器人与使用PROFINET协议的PLC进行数据交互。 2. 连接设备:EtherNet/IP机器人控制器(如ABB、FANUC)与PROFINET PLC(如西门子S7-1500)。 3. 连…...
链表的中间结点数据结构oj题(力扣876)
目录 题目描述: 题目分析: 代码解决: 题目描述: 给你单链表的头结点 head ,请你找出并返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。 题目分析: 寻找中间节点这道题原理…...
LLM学习笔记(五)概率论
1. 随机变量与概率分布:模型输出的基础 在LLM中,随机变量最直观的体现就是模型预测的下一个token。每个时刻,模型都会输出一个概率分布,表示词汇表中每个token可能是"下一个词"的概率。 直观理解 想象模型在处理句子…...
归并排序:分治思想的优雅实现
归并排序(Merge Sort)以简洁而高效的分治思想,在众多排序算法中占据着重要的地位。今天,就让我们一同深入探索归并排序的奥秘。 一、归并排序简介 归并排序是一种基于分治策略的排序算法。它的核心思想是将一个大的问题分解成若…...
从小区到商场再到校园,AI智能分析网关V4高空抛物检测方案全场景护航
在城市化进程不断加速的背景下,高层建筑如雨后春笋般涌现,然而,高空抛物这一“悬在城市上空的痛”却严重威胁着人民群众的生命财产安全。传统的监控方式难以对高空抛物行为进行及时、准确地识别与预警,而AI智能分析网关V4搭载高空…...
WEB安全--Java安全--shiro550反序列化漏洞
一、前言 什么是shiro? shiro是一个Apache的Java安全框架 它的作用是什么? Apache Shiro 是一个强大且灵活的 Java 安全框架,用于处理身份验证、授权、密码管理以及会话管理等功能 二、shiro550反序列化原理 1、用户首次登录并勾选记住密码…...
现代计算机图形学Games101入门笔记(十一)
致敬两位大佬 面的细分、简化、正则化 Loop 不是循环,是这个算法的发明人家族名称是Loop. 新增点,白点是不更新前通过细分得到的点。通过加权平均4个点坐标,更新坐标就是最后细分点的坐标。 如果细分出新的点刚好在老点上。那一部分相信周围点…...
OAT 初始化时出错?问题可能出在 PAM 配置上|OceanBase 故障排查实践
本文作者:爱可生数据库工程师,任仲禹,擅长故障分析和性能优化。 背景 某客户在使用 OAT 初始化OceanBase 服务器的过程中,进行到 precheck 步骤时,遇到了如下报错信息: ERROR - check current session ha…...
现场血案:Kafka CRC 异常
一、背景 现场童鞋说客户的研发环境突然在近期间歇式的收到了CRC的相关异常,异常内容如下 Record batch for partition skywalking-traces-0 at offset 292107075 is invalid, cause: Record is corrupt (stored crc = 1016021496, compute crc = 1981017560) 报错完全没有…...
实时技术方案对比:SSE vs WebSocket vs Long Polling
早期网站仅展示静态内容,而如今我们更期望:实时更新、即时聊天、通知推送和动态仪表盘。 那么要如何实现实时的用户体验呢?三大经典技术各显神通: SSE(Server-Sent Events):轻量级单向数据流WebSocket:双向全双工通信Long Polling(长轮询):传统过渡方案假设目前有三…...
搭建游戏云服务器的配置要求包括哪些条件?
在游戏行业迅猛发展的背景下,越来越多的游戏团队、独立开发者、企业平台开始将服务器部署转向云端,尤其是在初期测试、公测阶段及全球发布期,云服务器所带来的弹性部署、全球覆盖、成本控制能力成为不可替代的优势。但问题随之而来࿱…...
Go语言八股文之Mysql锁详解
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 非常期待和您一起在这个小…...