零知识证明:区块链隐私保护的变革力量
🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/literature?__c=1000,移动端可微信小程序搜索“历代文学”)总架构师,
15年
工作经验,精通Java编程
,高并发设计
,Springboot和微服务
,熟悉Linux
,ESXI虚拟化
以及云原生Docker和K8s
,热衷于探索科技的边界,并将理论知识转化为实际应用。保持对新技术的好奇心,乐于分享所学,希望通过我的实践经历和见解,启发他人的创新思维。在这里,我希望能与志同道合的朋友交流探讨,共同进步,一起在技术的世界里不断学习成长。
技术合作请加本人wx(注明来自csdn):foreast_sea
零知识证明:区块链隐私保护的变革力量
一、引言
在当今数字化时代,数据隐私和安全已成为人们日益关注的焦点。随着区块链技术的广泛应用,其在数据存储和传输过程中的安全性和透明度备受赞誉,但同时也面临着隐私泄露的潜在风险。在区块链网络中,交易信息通常是公开可见的,这虽然保证了交易的可追溯性和不可篡改性,但也可能暴露用户的敏感信息,如交易金额、交易双方身份等。
为了解决这一问题,一种名为零知识证明
的“黑科技”应运而生。零知识证明允许一方(证明者)向另一方(验证者)证明某个陈述是真实的
,而无需透露除了该陈述为真之外的任何额外信息
。这一概念在区块链领域的应用具有深远的意义,它能够在不影响区块链核心特性(如去中心化、透明度和安全性)的前提下,为用户提供强大的隐私保护。
例如,在加密货币交易中,用户可以使用零知识证明向区块链网络证明自己拥有足够的资金进行交易,而无需透露具体的账户余额或交易历史。这不仅保护了用户的隐私,还能确保交易的合法性和有效性。此外,零知识证明还可以应用于身份验证、供应链管理、医疗保健等众多领域,为这些领域的数据隐私保护提供创新的解决方案。
在本文中,我们将深入探讨区块链技术的基本概念、原理、特性和应用场景,详细介绍零知识证明的工作原理及其在区块链中的应用方式,并通过实际代码示例展示其具体实现过程。通过对这些内容的深入理解,我们将能够清晰地看到零知识证明如何正在改变并将继续改变区块链技术的未来发展方向,为构建更加安全、私密和高效的数字世界奠定坚实的基础。
二、区块链概述
2.1 区块链的概念
区块链是一种分布式账本技术,它将数据以区块的形式进行存储,并通过密码学算法确保这些区块之间的链接安全可靠。每个区块包含了一批交易信息以及指向前一个区块的哈希指针,形成了一条从创世区块开始的链式结构。
这种分布式账本的独特之处在于它不依赖于单一的中心化机构来维护,而是由众多的节点(参与者)共同参与维护。每个节点都拥有整个区块链的副本,并且通过特定的共识机制来达成对新交易和区块的一致性认可。
例如,比特币就是基于区块链技术构建的一种数字货币系统。在比特币网络中,全球各地的计算机节点共同维护着一个公共的区块链账本,记录着所有比特币的交易历史。当一笔新的比特币交易发生时,它会被广播到网络中的各个节点,经过节点的验证和确认后,被打包进一个新的区块,并添加到区块链中。
2.2 区块链的原理
- 交易与区块:在区块链中,交易是最基本的操作单元。用户发起的交易包含了发送方地址、接收方地址、交易金额等信息。这些交易被收集起来,组成一个区块。一个区块通常还包含一个区块头和区块体。区块头中存储了区块的元信息,如前一区块的哈希值、时间戳、难度目标等,区块体则包含了该区块内的所有交易信息。
- 哈希算法:哈希算法在区块链中起着至关重要的作用。它将任意长度的数据转换为固定长度的哈希值。例如,比特币使用的 SHA-256 哈希算法,无论输入的数据有多长,输出的哈希值都是 256 位。哈希算法具有单向性,即从哈希值很难反推出原始数据;同时,它还具有抗碰撞性,即很难找到两个不同的数据产生相同的哈希值。通过将区块头进行哈希运算,得到的哈希值作为该区块的唯一标识,并且由于前一区块的哈希值包含在当前区块头中,使得区块链的区块之间形成了紧密的链接关系。
- 共识机制:为了确保区块链网络中的各个节点能够对交易和区块达成一致,需要一种共识机制。常见的共识机制有工作量证明(
Proof of Work,PoW
)、权益证明(Proof of Stake,PoS
)等。以工作量证明为例,节点需要通过不断地尝试计算一个满足特定难度要求的哈希值(称为挖矿),来竞争创建新的区块的权利。第一个找到符合要求哈希值的节点将其创建的区块广播到网络中,其他节点在接收到区块后,会验证区块的有效性,如果验证通过,则将该区块添加到自己维护的区块链副本中,从而实现了整个网络对区块的一致性认可。
2.3 区块链的特性
- 去中心化:区块链不存在一个中心化的控制机构,而是由众多的节点共同参与管理。这意味着没有单个实体能够完全掌控整个区块链的运行。例如,在比特币网络中,没有银行或政府机构来决定谁可以进行交易或控制货币的发行。去中心化的特性使得区块链具有更高的抗审查性和可靠性,因为即使部分节点遭受攻击或出现故障,整个网络仍然能够正常运行。
- 透明度:区块链上的交易信息是公开透明的,所有的节点都可以查看区块链上的历史交易记录。这种透明度有助于建立信任,因为任何人都可以验证交易的真实性和合法性。例如,在供应链管理中,消费者可以通过区块链查看产品的生产、运输和销售等各个环节的信息,确保产品的质量和来源可靠。
- 安全性:区块链采用了多种密码学技术来确保其安全性。哈希算法保证了区块数据的完整性,使得数据一旦被记录在区块链上就难以被篡改。同时,数字签名技术用于验证交易的发起者身份,防止交易被伪造。此外,由于区块链的分布式存储特性,攻击者需要控制大量的节点才能对区块链进行有效的攻击,这大大增加了攻击的难度和成本。
2.4 区块链的应用场景
- 数字货币:如比特币、以太坊等加密货币是区块链最著名的应用。它们允许用户在无需第三方中介的情况下进行安全、快速的价值转移。
- 供应链管理:通过在区块链上记录产品的生产、加工、运输等信息,可以实现供应链的全程追溯,提高供应链的透明度和效率,降低假冒伪劣产品的风险。
- 金融服务:区块链可以用于跨境支付、证券交易结算、信贷征信等金融领域。例如,跨境支付可以通过区块链实现更快、更便宜的资金转移,减少中间银行的手续费和处理时间。
- 智能合约:以太坊等区块链平台支持智能合约的运行。智能合约是一种自动执行的合约条款,以代码的形式部署在区块链上。例如,在房地产交易中,可以通过智能合约实现自动的产权转移和资金交割,减少人为错误和欺诈风险。
- 医疗保健:患者的医疗记录可以存储在区块链上,实现医疗数据的安全共享和隐私保护。不同的医疗机构可以在患者授权的情况下访问和更新这些数据,提高医疗诊断的准确性和效率。
三、零知识证明基础
3.1 零知识证明的概念
零知识证明是一种密码学技术,它允许证明者向验证者证明某个陈述是真实的,而无需透露陈述本身之外的任何其他信息。简单来说,就是证明者能够让验证者相信某个事实,却不泄露关于这个事实的具体细节。
例如,假设有一个迷宫,证明者知道从入口到出口的路径,但不想直接告诉验证者这条路径。通过零知识证明,证明者可以以一种交互的方式向验证者证明自己知道路径,而验证者在这个过程中无法得知路径的具体走向。
3.2 零知识证明的原理
零知识证明通常基于一些复杂的数学假设和密码学算法来实现。其中一个常见的原理是基于离散对数问题或椭圆曲线离散对数问题。
以离散对数问题为例,假设有一个大素数 (p) 和一个生成元 (g),对于给定的 (y = g^x \bmod p),计算 (x) 是非常困难的(离散对数问题)。证明者知道 (x),要向验证者证明自己知道 (x) 且不透露 (x) 的值。证明者可以通过以下步骤进行零知识证明:
- 证明者选择一个随机数 (r),计算 (a = g^r \bmod p),并将 (a) 发送给验证者。
- 验证者选择一个随机挑战 (c)(通常是 0 或 1),并将 (c) 发送给证明者。
- 如果 (c = 0),证明者计算 (z = r);如果 (c = 1),证明者计算 (z = r + x \bmod (p - 1)),然后将 (z) 发送给验证者。
- 验证者收到 (z) 后,如果 (c = 0),则验证 (a = g^z \bmod p);如果 (c = 1),则验证 (a \cdot y = g^z \bmod p)。如果验证通过,则证明者的证明有效。
在这个过程中,验证者每次只能得到一个与 (x) 相关的部分信息(通过 (z)),但由于随机挑战 (c) 的存在,验证者无法通过多次交互拼凑出 (x) 的完整值,从而实现了零知识证明。
3.3 零知识证明的类型
- 交互式零知识证明:如上述迷宫例子和离散对数问题的证明过程,证明者和验证者需要进行多轮的交互,验证者通过随机挑战来逐步验证证明者的陈述。这种类型的零知识证明在早期研究中较为常见,但由于需要交互,在一些应用场景中可能存在效率和可扩展性问题。
- 非交互式零知识证明:为了克服交互式零知识证明的局限性,非交互式零知识证明应运而生。它通过使用一些可信的公共随机源(如区块链上的哈希值)来替代验证者的随机挑战,使得证明者可以一次性生成证明,验证者可以在任何时候独立地验证证明的有效性。非交互式零知识证明在区块链应用中更为实用,因为它可以减少网络通信开销,提高系统的效率和可扩展性。
四、零知识证明在区块链中的应用
4.1 隐私保护交易
在区块链数字货币交易中,零知识证明可以用于隐藏交易的金额、发送方和接收方的具体信息。例如,在 Zcash 这种隐私加密货币中,采用了零知识证明技术(具体为 zk - SNARKs)来实现隐私保护交易。
当用户进行交易时,交易信息会被加密处理,并且通过零知识证明向区块链网络证明交易的合法性,如证明发送方有足够的资金进行交易、交易金额未被篡改等,而无需透露交易的具体细节。这样,区块链上的其他节点只能看到交易是合法的,但无法得知交易的具体内容,从而保护了用户的隐私。
4.2 身份验证与授权
在区块链的身份验证和授权场景中,零知识证明可以让用户证明自己拥有某些身份属性或权限,而无需暴露具体的身份信息。
例如,在一个基于区块链的访问控制系统中,用户可以使用零知识证明向系统证明自己满足特定的访问条件,如年龄超过 18 岁、是某个组织的成员等,而无需提供身份证号码、组织成员证号等敏感信息。系统只需要验证零知识证明的有效性,就可以决定是否给予用户访问权限。
4.3 智能合约隐私
智能合约在区块链上运行时,其代码和执行结果通常是公开可见的。零知识证明可以用于保护智能合约中的敏感数据和逻辑。
例如,一个涉及商业机密的智能合约,如企业之间的合作协议智能合约,合约中的某些关键条款(如价格、利润分配等)可以通过零知识证明进行加密处理。在合约执行过程中,只有参与方能够通过零知识证明验证合约条款的执行情况,而外部观察者无法得知合约的具体内容,从而保护了企业的商业机密。
五、零知识证明代码示例与注释
5.1 基于Java的代码示例
以下是一个简单的基于Java的区块链零知识证明示例代码,这里以简化的离散对数问题场景来展示零知识证明的基本原理。示例代码实现了证明者向验证者证明自己知道某个离散对数问题的解,同时不泄露具体解的值。
import java.math.BigInteger;
import java.security.SecureRandom;public class ZeroKnowledgeProofExample {// 大素数pprivate static final BigInteger P = new BigInteger("23");// 生成元gprivate static final BigInteger G = new BigInteger("5");// 证明者知道的秘密值xprivate static final BigInteger X = new BigInteger("3");// 证明者选择随机数r的方法private static BigInteger proverChooseRandom() {SecureRandom random = new SecureRandom();// 生成一个在1到P - 1之间的随机数return new BigInteger(P.bitLength() - 1, random).add(BigInteger.ONE);}// 证明者生成a = g^r mod p的方法private static BigInteger proverGenerateA(BigInteger r) {return G.modPow(r, P);}// 验证者生成随机挑战c(0或1)的方法private static int verifierGenerateChallenge() {SecureRandom random = new SecureRandom();return random.nextInt(2);}// 证明者根据挑战c生成z的方法private static BigInteger proverGenerateZ(BigInteger r, int c) {if (c == 0) {return r;} else {return r.add(X).mod(P.subtract(BigInteger.ONE));}}// 验证者验证证明的方法private static boolean verifierVerify(BigInteger a, int c, BigInteger z) {if (c == 0) {return G.modPow(z, P).equals(a);} else {BigInteger gToZ = G.modPow(z, P);BigInteger gToX = G.modPow(X, P);return gToZ.multiply(gToX).mod(P).equals(a);}}// 主函数进行零知识证明过程public static void main(String[] args) {// 证明者选择随机数rBigInteger r = proverChooseRandom();// 证明者生成aBigInteger a = proverGenerateA(r);// 验证者生成挑战cint c = verifierGenerateChallenge();// 证明者生成zBigInteger z = proverGenerateZ(r, c);// 验证者验证证明boolean result = verifierVerify(a, c, z);if (result) {System.out.println("零知识证明成功!");} else {System.out.println("零知识证明失败!");}}
}
以下是对上述代码的详细注释:
- 定义常量部分:
// 大素数p
private static final BigInteger P = new BigInteger("23");
// 生成元g
private static final BigInteger G = new BigInteger("5");// 证明者知道的秘密值x
private static final BigInteger X = new BigInteger("3");
这里定义了零知识证明示例所基于的离散对数问题的相关参数。P
是一个大素数,G
是对应的生成元,X
是证明者所知道的秘密值(在实际场景中,这个值是不对外公开的,但在示例中为了演示方便先进行了定义)。
- 证明者选择随机数
r
的方法:
// 证明者选择随机数r的方法
private static BigInteger proverChooseRandom() {SecureRandom random = new SecureRandom();// 生成一个在1到P - 1之间的随机数return new BigInteger(P.bitLength() - 1, random).add(BigInteger.ONE);
}
这个方法用于让证明者选择一个随机数r
。通过SecureRandom
类来生成一个在1
到P - 1
之间的随机数,以满足离散对数问题的计算要求。
- 证明者生成
a = g^r mod p
的方法:
// 证明者生成a = g^r mod p的方法
private static BigInteger proverGenerateA(BigInteger r) {return G.modPow(r, P);
}
根据证明者选择的随机数r
,使用modPow
方法计算G
的r
次幂对P
取模的结果,即得到a
的值。
- 验证者生成随机挑战
c
(0
或1
)的方法:
// 验证者生成随机挑战c(0或1)的方法
private static int verifierGenerateChallenge() {SecureRandom random = new SecureRandom();return random.nextInt(2);
}
验证者通过SecureRandom
类生成一个随机的整数,范围是0
到1
,作为对证明者的随机挑战c
。
- 证明者根据挑战
c
生成z
的方法:
// 证明者根据挑战c生成z的方法
private static BigInteger proverGenerateZ(BigInteger r, int c) {if (c == 0) {return r;} else {return r.add(X).mod(P.subtract(BigInteger.ONE));}
}
根据验证者给出的挑战c
的值,如果c
为0
,则z
就等于之前选择的随机数r
;如果c
为1
,则z
等于r
加上秘密值X
后对P - 1
取模的结果。
- 验证者验证证明的方法:
// 验证者验证证明的方法
private static boolean verifierVerify(BigInteger a, int c, BigInteger z) {if (c == 0) {return G.modPow(z, P).equals(a);} else {BigInteger gToZ = G.modPow(z, P);BigInteger gToX = G.modPow(X, P);return gToZ.multiply(gToX).mod(P).equals(a);}
}
验证者根据接收到的a
、c
和z
来验证零知识证明的有效性。如果c
为0
,则验证G
的z
次幂对P
取模的结果是否等于a
;如果c
为1
,则先分别计算G
的z
次幂和G
的X
次幂对P
取模的结果,然后将这两个结果相乘后对P
取模,验证其是否等于a
。
- 主函数进行零知识证明过程:
// 主函数进行零知识证明过程
public static void main(String[] args) {// 证明者选择随机数rBigInteger r = proverChooseRandom();// 证明者生成aBigInteger a = proverGenerateA(r);// 验证者生成挑战cint c = verifierGenerateChallenge();// 证明者生成zBigInteger z = proverGenerateZ(r, c);// 验证者验证证明boolean result = verifierVerify(a, c, z);if (result) {System.out.println("零知识证明成功!");} else {System.out.println("零知识证明失败!");}
}
在主函数中,按照零知识证明的流程依次调用前面定义的各个方法。首先证明者选择随机数r
并生成a
,然后验证者生成挑战c
,接着证明者根据c
生成z
,最后验证者验证证明并根据结果输出相应的提示信息。
请注意,这个示例只是一个非常简化的零知识证明演示,实际应用中的零知识证明会更加复杂,涉及到更严格的数学假设、更高的安全性要求以及更复杂的交互和验证机制等。
5.2 基于python的代码示例
以下是一个简单的基于离散对数问题的零知识证明代码示例(使用 Python 语言):
# 大素数 p 和生成元 g
p = 23
g = 5# 证明者知道的秘密值 x
x = 3# 证明者选择随机数 r
def prover_choose_random():import randomreturn random.randint(1, p - 1)# 证明者生成 a = g^r mod p
def prover_generate_a(r):return (g ** r) % p# 验证者生成随机挑战 c(0 或 1)
def verifier_generate_challenge():import randomreturn random.randint(0, 1)# 证明者根据挑战 c 生成 z
def prover_generate_z(r, c):if c == 0:return relse:return (r + x) % (p - 1)# 验证者验证证明
def verifier_verify(a, c, z):if c == 0:return (g ** z) % p == aelse:return ((g ** z) * (g ** x)) % p == a# 主函数进行零知识证明过程
def zero_knowledge_proof():# 证明者选择随机数 rr = prover_choose_random()# 证明者生成 aa = prover_generate_a(r)# 验证者生成挑战 cc = verifier_generate_challenge()# 证明者生成 zz = prover_generate_z(r, c)# 验证者验证证明return verifier_verify(a, c, z)# 运行零知识证明并输出结果
if __name__ == "__main__":result = zero_knowledge_proof()if result:print("零知识证明成功!")else:print("零知识证明失败!")
在上述代码中:
- 首先定义了大素数
p
和生成元g
,以及证明者知道的秘密值x
。 prover_choose_random
函数用于证明者选择一个随机数r
。prover_generate_a
函数根据随机数r
计算a = g^r mod p
。verifier_generate_challenge
函数用于验证者生成随机挑战c
。prover_generate_z
函数根据挑战c
和随机数r
以及秘密值x
计算z
。verifier_verify
函数用于验证者根据接收到的a
、c
和z
来验证零知识证明的有效性。zero_knowledge_proof
函数将整个零知识证明的过程整合起来,最后在主函数中运行并输出证明结果。
六、总结
零知识证明作为一种强大的密码学技术,在区块链领域的应用正不断拓展和深化。它为区块链的隐私保护提供了创新的解决方案,使得区块链能够在保持去中心化、透明度和安全性等核心特性的同时,更好地保护用户的隐私信息。通过在隐私保护交易、身份验证与授权、智能合约隐私等多个方面的应用,零知识证明正在重塑区块链的生态系统,为区块链技术在更多领域的广泛应用奠定了基础。
随着技术的不断发展,零知识证明在区块链中的应用将会更加成熟和完善,有望推动区块链技术走向更加安全、私密和高效的未来。
七、参考资料文献
- [1] 《区块链技术指南》,邹均,等著,机械工业出版社
- [2] 《密码学原理与实践》,Douglas R. Stinson 著,电子工业出版社
- [3] 以太坊官方文档:https://ethereum.org/
- [4] Zcash 官方网站:https://z.cash/
相关文章:
零知识证明:区块链隐私保护的变革力量
🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/literature?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,…...
基于STC89C52的CD4511译码显示数字设计
摘要 本文深入探讨基于STC89C52单片机的数字显示系统设计,剖析CD4511译码驱动芯片工作原理,结合Proteus仿真验证功能。通过硬件电路、软件编程及原理分析,完整呈现单片机控制数码管显示的实现过程,为相关开发提供理论与实践参考。 一、引言 在单片机应用中,数码管显示是…...
MPC算法路径跟踪_Matlab实现
在机器人控制领域,模型预测控制(MPC)因其能够处理动态约束和多目标优化的特性,成为路径跟踪的热门方案。近期,我在 GitHub 上发现了 Mr.Winter 的MPC路径规划项目,其代码实现简洁且功能完整。本文将结合理论…...
QT Quick(C++)跨平台应用程序项目实战教程 2 — 环境搭建和项目创建
目录 引言 1. 安装Qt开发环境 1.1 下载Qt安装包 1.2 安装Qt 1.3 安装Visual Studio 2022 1.4 在Visual Studio 2022中安装Qt插件 1.5 在Visual Studio 2022中安装大模型编程助手 2. 创建Qt Quick项目 2.1 创建新项目 2.2 项目结构 2.3 运行项目 3. 理解项目代码 3…...
洛科威多功能岩棉板为环保助力,推动企业绿色可持续发展
在当今全球环保意识日益增强的背景下,企业工程项目在追求高效益的同时,也更加注重绿色可持续发展。作为建筑材料领域的佼佼者,洛科威公司推出的多功能岩棉板凭借其卓越的绿色环保特性,正逐渐成为企业工程项目领域的首选材料。 洛科…...
7.3《重力》
教会什么:重力及其三要素、重力加速度g、 培养什么:从力的三要素出发去研究一个力,用所学探究未知 课标: (二)运动和相互作用 2.2 机械运动和力 2.2.3 通过常见事例或实验,了解重力,认识力的作用效果。 (四)实验探究 4.1.6 用弹测力计测量力。 例6 测量一本物理教科书…...
虚幻基础:ue自定义类
文章目录 Gameplay Tag:ue标签类创建:其他-数据表格-gameplaytag安装:项目设置:gamePlayTag:gamePlay标签列表使用:变量类型:gamePlayTag primary data asset:ue数据类:通…...
88页手册上线 | 企业级本地私有化DeepSeek实战指南
DeepSeek为普通企业在低成本、高性能、安全可控的前提下私有化部署AI大模型提供了可行路径。 云轴科技ZStack全新推出《企业级本地私有化DeepSeek实战手册》(点击免费下载),直击企业痛点,从7B轻量化模型到671B超大规模部署&#…...
Godot读取json配置文件
概述 在Godot 4.3中读取JSON配置文件,可以通过以下步骤实现: 步骤说明 读取文件内容:使用FileAccess类打开并读取JSON文件。 解析JSON数据:使用JSON类解析读取到的文本内容。 错误处理:处理文件不存在或JSON格式错…...
时序分析笔记
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 前言 一、周期约束 二、建立时间和保持时间 三、时序路径 四、时序模型 前言 约束文件笔记,傅里叶的猫的视频。 一、周期约束 时序约束就是告诉软件输…...
【笔记】深度学习模型训练的 GPU 内存优化之旅:重计算篇
开设此专题,目的一是梳理文献,目的二是分享知识。因为笔者读研期间的研究方向是单卡上的显存优化,所以最初思考的专题名称是“显存突围:深度学习模型训练的 GPU 内存优化之旅”,英文缩写是 “MLSys_GPU_Memory_Opt”。…...
Deepseek使用技巧大全
还有好多人不会用,一个链接让你们全部学完 https://m0739kfdebc.feishu.cn/docx/LIBddUcupoIBwVxp0yGcsT77nFd?fromfrom_copylink...
redis搭建一主一从+keepalived(虚拟IP)实现高可用
redis搭建一主一从keepalived(虚拟IP)实现高可用 前提 有两台机器:如 10.50.3.141 10.50.3.142,虚拟ip如:10.50.3.170 安装redis(两台机器执行): # 启用Remi仓库(CentOS 7) sudo yum install…...
6、说一下索引失效的场景?【中高频】
索引失效意味着 查询操作 不能利用索引进行数据检索,而是使用 全表扫描(也就是 数据库需要从磁盘上读取表的所有数据行),从而导致性能下降,下面一些场景会发生索引失效 对索引使用左或者左右模糊匹配(where…...
前端调试实战指南:从入门到高阶的完整解决方案
引言:调试的本质与价值 调试是程序员将理想代码映射到现实运行环境的关键过程。据统计,开发者平均将30%的工作时间用于调试。本指南将系统梳理现代前端调试技术体系,帮助开发者构建高效的调试工作流。 一、基础调试工具箱 1.1 浏览器开发者工具核心功能 元素调试(Elemen…...
电商多包裹与子母单发货区别
在电商发货中,多包裹发货和子母单是两种常见的发货方式,具体含义如下: 1. 多包裹发货 定义: 指一个订单中的商品因库存、尺寸或重量等原因,无法装入一个包裹,需分成多个包裹发出。 原因: 商品…...
程序化广告行业(28/89):基于用户旅程的广告策略解析
程序化广告行业(28/89):基于用户旅程的广告策略解析 大家好!一直以来,我都希望能和大家在技术学习的道路上携手前行、共同进步。在之前的文章里,我们探讨了程序化广告行业的诸多关键环节,这次让…...
Hugging Face模型国内镜像HF Mirror下载
直接下载 Hugging Face 开启梯子,一看好几个g... 我们寻找国内镜像。 访问HF-Mirror 继续上面搜索。 继续点击跟踪路径。 拼出路径。 https://hf-mirror.com/Comfy-Org/Wan_2.1_ComfyUI_repackaged/resolve/main/split_files/vae/wan_2.1_vae.safetensors 如果网…...
2025-03-19 学习记录--C/C++-C语言-单链表的结构体定义 + LNode * 和 LinkList 的区别
C语言-单链表的结构体定义 ⭐️ 一、单链表的结构体定义 🍭 typedef struct LNode { // 定义结构体 LNode,表示链表中的一个结点int data; // 数据域,存储结点的值struct LNode *next; // 指针域,指向下一个结点 } LN…...
【操作系统安全】任务7:服务与进程
目录 一、引言 二、服务与进程介绍 2.1 服务的概念 2.2 进程的概念 2.3 服务与进程的关系 2.4 服务与进程在网络安全中的重要性 三、LAMP 网站环境部署 3.1 LAMP 简介 3.2 LAMP 环境部署步骤 3.2.1 安装 Linux 操作系统 3.2.2 安装 Apache HTTP 服务器 3.2.3 安装 …...
AI里的RAG到底是什么?
AI大模型如deepseek本地部署的成本相对较低,如果要训练,微调大模型,则需要非常多的显卡,与很多时间,那一般企业无法投入那么多钱去买显卡,怎么办? 通过RAG与本地部署来提升大模型的专业知识 R…...
数据库从安装到劝退
友好的安装是数据库使用的第一步 MySQL被称为5分钟数据库。是形容安装简单。事实也是如此。RPM一下可以就把几个包安装完毕了。一个单机情况下,5分钟是足够的。 其他数据库PostgreSQL也差不多是这样。 而Redis这种就更快了。所以这些才能流行。 曾经数据库中安装相…...
《基于Spring Boot+Vue的智慧养老系统的设计与实现》开题报告
个人主页:@大数据蟒行探索者 一、研究背景及国内外研究现状 1.研究背景 根据1982年老龄问题世界大会联合国制定的标准,如果一个国家中超过65岁的老人占全国总人口的7%以上,或者超过60岁的老人占全国总人口的10%以上,那么这个国家将被定义为“老龄化社会”[1]。 随着国…...
PHP转GO Go语言环境搭建(Day1) 常见问题及解决方案指南
Go语言环境搭建(Day1)整理的 常见问题及解决方案指南: Go环境搭建问题排查手册 一、安装阶段问题 问题现象原因分析解决方案安装包下载失败网络问题或官网访问慢使用国内镜像下载:- Go中文网提示"Access Denied"Windows系统权限不足1. 右键安装包选择"以管理…...
VLLM专题(三十九)—自动前缀缓存(二)
前缀缓存(Prefix Caching)是一种在LLM推理中广泛使用的优化技术,旨在避免冗余的提示词(prompt)计算。其核心思想很简单——我们缓存已处理请求的键值缓存(kv-cache)块,并在新请求的前缀与之前请求相同时重用这些块。由于前缀缓存几乎是一种“免费的午餐”,并且不会改变…...
C语言每日一练——day_12(最后一天)
引言 针对初学者,每日练习几个题,快速上手C语言。第十二天。(最后一天,完结散花啦) 采用在线OJ的形式 什么是在线OJ? 在线判题系统(英语:Online Judge,缩写OJ࿰…...
HAL库编程知识点---Can.c和Driver_can.c分层开发
在一个工程中,通常会把对CAN外设的操作分成底层和上层两个部分,从而提高代码的模块化和可维护性。一般来说: can.c 通常由硬件抽象层(HAL)或者自动生成工具(如 CubeMX)提供或生成。主要负责CAN硬…...
L2TP实验 作业
拓扑图 实验需求 让FW1(PPPoE Client)模拟拨号用户,向内部服务器发送建立拨号连接的请求,并保证连通 实验步骤 安全区域 firewall zone trust add int g1/0/0 策略 security-policy default action permit NAS int g1/…...
算法模型从入门到起飞系列——递归(探索自我重复的奇妙之旅)
文章目录 前言一、递归本质1.1 递归的要素1.2 递归特点 二、递归&迭代2.1 递归&迭代比较2.2 递归&迭代如何实现相同功能2.2.1 递归实现2.2.2 迭代实现2.2.3 性能对比 三、优雅的递归理解3.1 阶乘计算分解3.2 [DFS](https://blog.csdn.net/qq_38315952/article/deta…...
Netty源码—1.服务端启动流程二
大纲 1.服务端启动整体流程及关键方法 2.服务端启动的核心步骤 3.创建服务端Channel的源码 4.初始化服务端Channel的源码 5.注册服务端Channel的源码 6.绑定服务端端口的源码 7.服务端启动流程源码总结 5.注册服务端Channel的源码 (1)注册服务端Channel的入口 (2)注册…...
Python OCR文本识别详细步骤及代码示例
光学字符识别(OCR)是将图像中的文字转换为可编辑文本的技术。在Python中,我们可以利用多种库实现OCR功能。本文将详细介绍使用Tesseract和EasyOCR进行文本识别的步骤,并提供完整的代码示例。 一、OCR简介 OCR(Optical…...
springmvc 框架学习
什么是 SpringMVC 框架 Spring MVC 是 Spring 框架的核心模块之一,基于 Java Servlet API 构建的 Web 层解决方案。它实现了 MVC 设计模式(Model-View-Controller),专为开发灵活、松耦合的 Web 应用程序而设计。 在控制层框架历…...
学习threejs,构建THREE.ParametricGeometry参数化函数生成几何体
👨⚕️ 主页: gis分享者 👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕️ 收录于专栏:threejs gis工程师 文章目录 一、🍀前言1.1 ☘️THREE.ParametricGeometry1…...
【华为OD-E卷 - 单词接龙 100分(python、java、c++、js、c)】
【华为OD-E卷 - 单词接龙 100分(python、java、c、js、c)】 题目 单词接龙的规则是: 可用于接龙的单词首字母必须要前一个单词的尾字母相同; 当存在多个首字母相同的单词时,取长度最长的单词,如果长度也相…...
美团Leaf分布式ID生成器使用教程:号段模式与Snowflake模式详解
引言 在分布式系统中,生成全局唯一ID是核心需求之一。美团开源的Leaf提供了两种分布式ID生成方案:号段模式(高可用、依赖数据库)和Snowflake模式(高性能、去中心化)。本文将手把手教你如何配置和使用这两种…...
性能测试过程实时监控分析
性能监控 前言一、查看性能测试结果的3大方式1、GUI界面报告插件2、命令行运行 html报告3、后端监听器接入仪表盘 二、influxDB grafana jmeter测试监控大屏1、原理:2、linux环境中influxDB 安装和配置3、jmerer后端监听器连接influxDB4、linux环境总grafana环境搭…...
【工具类】Java的 LocalDate 获取本月第一天和最后一天
博主介绍:✌全网粉丝22W,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...
Eclipse 创建 Java 类
Eclipse 创建 Java 类 引言 Eclipse 是一款功能强大的集成开发环境(IDE),被广泛用于 Java 开发。本文将详细介绍如何在 Eclipse 中创建 Java 类,包括配置开发环境、创建新项目、添加类以及编写类代码等步骤。 配置 Eclipse 开发环境 1. 安装 Eclipse 首先,您需要在您…...
Centos编译升级libcurl
Centos编译升级libcurl 下载最新版源码包安装编译依赖配置编译选项如果报错:通过 EPEL 仓库安装手动源码编译安装 如果报错:安装Brotli 开发库 如果报错:方法一:安装 libpsl-devel 依赖通过 EPEL 仓库安装重新运行 configure 方…...
蓝桥杯第九天 2022 省赛 第 4 题 最少刷题数
太多坑了,考虑不全只能过50%,有两种特殊情况 public static void main(String[]args) {Scanner scan new Scanner(System.in);int n scan.nextInt();int a[] new int [100005];int b[] new int [100005];for(int i 0;i<n;i)a[i] scan.nextInt()…...
3D点云数据处理中的聚类算法总结
1.欧式聚类: 基于点的空间距离(欧几里得距离)来分割点云,将距离较近的点归为同一簇。 欧式聚类需要的参数:邻域半径R,簇的最小点阈值minPts,最大点数阈值maxPts。 实现效率: O(n * log n) 实现…...
配置本机监控
配置本机监控 1、安装zabbix-agent 2、编辑zabbix-agent配置文件 zabbix-agent工作模式: 主动模式 被动模式 这两行配置都是指定监控服务器的地址 被动模式下,zabbix server的地址 主动模式下,zabbix server的地址 指定被监控端的名称&…...
基于python的Flask模块化设计与蓝图的妙用——打造轻量化Web应用
基于python的Flask模块化设计与蓝图的妙用——打造轻量化Web应用 前言 如果你刚开始学习Flask,可能会遇到这样的困惑:当项目功能越来越多,代码都堆在一个.py文件里,不仅难维护,还容易冲突。别担心!本文将用…...
历年云南大学计算机复试上机真题
历年云南大学计算机复试机试真题 在线评测:传送门:pgcode.cn 喝饮料 题目描述 商店里有 n 中饮料,第 i 种饮料有 mi 毫升,价格为 wi。 小明现在手里有 x 元,他想吃尽量多的饮料,于是向你寻求帮助&#x…...
Python 线程池
Python 线程池 flyfish 线程池的概念 线程池是一种多线程处理形式,它预先创建了一定数量的线程,这些线程会被保存在一个线程池中。当有新的任务提交时,线程池会从池中取出一个空闲的线程来执行该任务;若池中没有空闲线程&#…...
【Linux】Bash是什么?怎么使用?
李升伟 整理 什么是 Bash? Bash(Bourne Again Shell)是一种 命令行解释器(Shell),广泛用于 Unix 和 Linux 操作系统。它是 Bourne Shell(sh) 的增强版,提供了更多的功能…...
蓝桥杯day2:解码异或 后的数组
一、题意 未知 整数数组 arr 由 n 个非负整数组成。 经编码后变为长度为 n - 1 的另一个整数数组 encoded ,其中 encoded[i] arr[i] XOR arr[i 1] 。例如,arr [1,0,2,1] 经编码后得到 encoded [1,2,3] 。 给你编码后的数组 encoded 和原数组 arr …...
R语言软件配置(自用)
①输入R: The R Project for Statistical Computing ②点击进入Cran镜像网页,选择清华大学镜像,选择自己合适的版本下载即可(以我电脑windows为例)。 ③点击base或者install R for the first time,然后选择Download R-4.4.3 for windows&…...
基于deepseek的智能语音客服【第二讲】后端异步接口调用封装
本篇内容主要讲前端请求(不包含)访问后端服务接口,接口通过检索知识库,封装提示词,调用deepseek的,并返回给前端的全过程,非完整代码,不可直接运行。 1.基于servlet封装异步请求 为…...
LEDNet总结
LEDNet:联合低光增强和暗光去模糊 1、暗光增强和去模糊可以单独处理,但是合并效果不理想。 研究问题的背景:光线不足 可见度颜色失真 最小快门速度有限 长时间曝光引起运动模糊 低光运动模糊同时存在 存在问题:暗光增强后运动模…...