昇思量子计算系列教程-Grover搜索算法

基于MindSpore Quantum的Grover搜索算法

概述

如果你听过量子计算,那么你一定听说过Grover搜索算法。1996年,Lov Grover [1] 提出了Grover搜索算法,它是一种利用量子状态的叠加性进行并行计算并实现加速的算法。Grover搜索算法被公认为是继Shor算法后的第二大量子算法,也是第一个被完整的实验实现的量子算法,它解决的是无序数据库搜索问题。1997年,Bennett [2] 等人证明,对于非结构化的量子搜索问题,至少需要 Ω ( N ) \Omega(\sqrt{N}) Ω(N )​次量子查询,因此Grover搜索算法对于该问题是渐进意义下的最优算法。

无序数据库搜索问题(Unordered Database Search problem)就是从一个海量元素的无序数据库中,找到某些满足要求的元素。由于数据库中元素的数量是巨大的且这些元素是无序排列的,所以,要验证给定的元素是否满足要求很容易,但反过来,要找到这些元素却不是一件容易的事。

求解无序数据库搜索问题(不妨假设只有一个目标搜索数据),经典算法所需的时间复杂度为 O ( N ) \mathcal{O}(N) O(N),而Grover搜索算法所需的时间复杂度仅为 O ( N ) \mathcal{O}(\sqrt{N}) O(N ),相比经典算法具有平方加速,展示了量子计算的强大性能。此外,Grover搜索算法中用到的振幅扩大技巧,对许多启发式的经典搜索算法可以实现加速,因而具有广泛的应用。

本文档将会介绍Grover搜索算法的基本原理,以及通过两个具体的小例子来展示如何利用MindSpore Quantum实现该算法。

问题描述

我们需要在一组无序的 N N N元素集合(数据库)中进行搜索。将数据库中的元素与索引(从 0 0 0 N − 1 N-1 N1之间的整数)建立一一对应,我们关注于搜索这些元素的索引。考虑将该搜索问题表示为一个关于输入 x x x的函数 f ( x ) f(x) f(x),其中 x x x 0 0 0 N − 1 N-1 N1之间的整数。那么,函数 f f f定义为:

f ( x ) = { 0 , x ≠ x t a r g e t 1 , x = x t a r g e t . \begin{equation} f(x)=\begin{cases}0,x\neq x_{target}\\\\ 1,x=x_{target} \end{cases} \end{equation}. f(x)= 0,x=xtarget1,x=xtarget.

不失一般性,假设 N = 2 n N=2^n N=2n​,那么在量子系统中,索引以量子态 ∣ 0 ⟩ , ∣ 1 ⟩ , . . . , ∣ N − 1 ⟩ |0\rangle,|1\rangle,...,|N-1\rangle ∣0,∣1,...,N1​(或 ∣ 00...0 ⟩ , ∣ 00...1 ⟩ , . . . , ∣ 11...1 ⟩ |00...0\rangle,|00...1\rangle,...,|11...1\rangle ∣00...0,∣00...1,...,∣11...1​)表示,也即我们可以使用 n n n​个量子比特存储这些索引。

同时假设搜索问题只有一个目标态 ∣ ω ⟩ |\omega\rangle ω。Grover搜索算法的目标就是以极大的概率将 ∣ ω ⟩ |\omega\rangle ω搜索出来。

Grover搜索算法的基本原理

Grover搜索算法的基本原理:首先通过 Hadamard 门产生均匀叠加态,然后反复调用Grover迭代(或称为 G G G算子),以放大目标项的概率振幅同时抑制非目标项的概率振幅(该方法称之为振幅放大),最后对末态进行测量,那么就能以极大的概率得到目标态 ∣ ω ⟩ |\omega\rangle ω​​。

下面介绍Grover算法的主要步骤。

Step 1:数据库初始化

∣ 0 ⟩ ⊗ n |0\rangle^{\otimes n} ∣0n​​​​执行 H ⊗ n H^{\otimes n} Hn​​​​​操作,使得数据库被初始为一个均匀叠加态,即

∣ ψ 0 ⟩ = H ⊗ n ∣ 0 ⟩ ⊗ n = 1 N ∑ i = 0 N − 1 ∣ i ⟩ . |\psi_0\rangle=H^{\otimes n}|0\rangle^{\otimes n}=\frac{1}{\sqrt{N}}\sum_{i=0}^{N-1}|i\rangle. ψ0=Hn∣0n=N 1i=0N1i.

Step 2:Grover迭代

Grover迭代又可以分解为四步:

子步骤一

执行Oracle算子 U ω U_{\omega} Uω​,翻转目标态 ∣ ω ⟩ |\omega \rangle ω​​​​​的相位。

为了将需要寻找的数据和其它的数据区别开,最简单的方法就是翻转目标态的相位(增加一个负号),此时我们需要构造一个Oracle算子 U ω U_{\omega} Uω,其作用如下:

U ω ∣ x ⟩ = { ∣ x ⟩ , x ≠ ω − ∣ x ⟩ , x = ω . \begin{equation} U_{\omega}|x\rangle=\begin{cases} &|x\rangle,x\neq \omega&\\\\ -&|x\rangle,x=\omega& \end{cases} \end{equation}. Uωx= x,x=ωx,x=ω.

由于当 x = ω x=\omega x=ω​时, f ( ω ) = 1 f(\omega)=1 f(ω)=1​,那么 U ω U_{\omega} Uω​​的作用还可以表示成:

U ω ∣ x ⟩ = ( − 1 ) f ( x ) ∣ x ⟩ , U_{\omega}|x\rangle=(-1)^{f(x)}|x\rangle, Uωx=(1)f(x)x,

其矩阵表达式为

U ω = [ ( − 1 ) f ( 0 ) 0 … 0 0 ( − 1 ) f ( 1 ) … 0 ⋮ ⋮ ⋱ ⋮ 0 0 … ( − 1 ) f ( N − 1 ) ] . \begin{equation} U_{\omega}= \left[ \begin{array}{ccc} (-1)^{f(0)} & 0 & \dots & 0 \\\\ 0 & (-1)^{f(1)} & \dots & 0 \\\\ \vdots & \vdots & \ddots & \vdots \\\\ 0 & 0 & \dots & (-1)^{f(N-1)} \end{array} \right] \end{equation}. Uω= (1)f(0)000(1)f(1)000(1)f(N1) .

子步骤二

执行 H ⊗ n H^{\otimes n} Hn操作。

n n n位量子比特执行 H ⊗ n H^{\otimes n} Hn操作。

子步骤三

执行条件相移算子 P P P

条件相移算子 P P P能使 ∣ 0 ⟩ |0\rangle ∣0​态以外的每个态的相位都翻转,其作用如下:

P ∣ x ⟩ = { ∣ 0 ⟩ , x = 0 − ∣ x ⟩ , x ≠ 0 . \begin{equation} P|x\rangle=\begin{cases}&|0\rangle,x= 0&\\\\ -&|x\rangle,x\neq0& \end{cases} \end{equation}. Px= ∣0,x=0x,x=0.

其矩阵表达式为

P = 2 ( ∣ 0 ⟩ ⟨ 0 ∣ ) ⊗ n − I n = [ 1 0 … 0 0 − 1 … 0 ⋮ ⋮ ⋱ ⋮ 0 0 … − 1 ] . \begin{equation} P = 2(|0\rangle\langle0|)^{\otimes n} - I_n = \left[ \begin{array}{ccc} 1 & 0 & \dots & 0 \\\\ 0 & -1 & \dots & 0 \\\\ \vdots & \vdots & \ddots & \vdots \\\\ 0 & 0 & \dots & -1 \end{array} \right] \end{equation}. P=2(∣00∣)nIn= 100010001 .

子步骤四

再次执行 H ⊗ n H^{\otimes n} Hn操作。

至此,完整的 G G G算子可以表示为

G = H ⊗ n [ 2 ( ∣ 0 ⟩ ⟨ 0 ∣ ) ⊗ n − I n ] H ⊗ n U ω . G = H^{\otimes n} [2(|0\rangle\langle0|)^{\otimes n} - I_n] H^{\otimes n} U_{\omega}. G=Hn[2(∣00∣)nIn]HnUω.

注意: G G G算子需要迭代的次数为

r = [ π 4 N M ] ∼ O ( N ) , r = \left[ \frac{\pi}{4} \sqrt{\frac{N}{M}} \right] \sim O(\sqrt{N}), r=[4πMN ]O(N ),

其中,M表示目标态的个数。

Step 3:测量

对末态进行 ∣ 0 ⟩ , ∣ 1 ⟩ \\{|0\rangle,|1\rangle\\} ∣0,∣1基测量,就能以极大的概率得到目标态 ∣ ω ⟩ |\omega \rangle ω

Grover搜索算法的完整量子线路模型如下所示:

grover algorithm circuit

构造翻转量子比特相位的酉算子

通过上述介绍,我们发现,Grover搜索算法中最关键的部分就是存在可以翻转量子比特相位的酉算子,Oracle算子 U ω U_{\omega} Uω可以翻转目标态的相位,条件相移算子 P P P可以翻转 ∣ 0 ⟩ |0\rangle ∣0态以外的每个态的相位。

接下来,我们将构造可以翻转某一位量子比特相位的酉算子,定义如下:

from mindquantum.core.circuit import Circuit
from mindquantum.core.gates import Zdef bitphaseflip_operator(phase_inversion_qubit, n_qubits):   # 定义可以翻转某一位量子比特相位的函数s = [1 for i in range(1 << n_qubits)]for i in phase_inversion_qubit:s[i] = -1if s[0] == -1:for i in range(len(s)):s[i] = -1 * s[i]circuit = Circuit()length = len(s)cz = []for i in range(length):if s[i] == -1:cz.append([])current = it = 0while current != 0:if (current & 1) == 1:cz[-1].append(t)t += 1current = current >> 1for j in range(i + 1, length):if i & j == i:s[j] = -1 * s[j]for i in cz:if i:if len(i) > 1:circuit += Z.on(i[-1], i[:-1])else:circuit += Z.on(i[0])return circuit

现在, bitphaseflip_operator() 函数就可以实现翻转某一位量子比特的相位,只需要输入需要翻转相位的目标量子态和量子比特总数即可。

举个例子,我们现在生成3​​量子比特的均匀叠加态,运行如下代码:

# pylint: disable=W0104
from mindquantum.core.circuit import UN
from mindquantum.core.gates import H
from mindquantum.simulator import Simulatorn_qubits = 3                                 # 设定量子比特数为3
sim = Simulator('mqvector', n_qubits)        # 使用mqvector模拟器,命名为simcircuit = Circuit()                          # 初始化量子线路,命名为circuit
circuit += UN(H, n_qubits)                   # 每位量子比特上执行H门操作sim.apply_circuit(circuit)                   # 通过模拟器sim运行搭建好的量子线路circuitcircuit.svg()                                # 打印此时的量子线路circuit

从运行的结果看到此时的量子线路,以及我们成功生成了3量子比特的均匀叠加态。

假设我们需要翻转 ∣ 4 ⟩ |4\rangle ∣4态的相位,只需调用我们定义好的bitphaseflip_operator()函数即可,运行如下代码:

# pylint: disable=W0104
sim.reset()                                                      # 重置模拟器sim维护好的量子态,使得初始化的量子态为|000>phase_inversion_qubit = [4]                                      # 翻转|4>态的相位
operator = bitphaseflip_operator(phase_inversion_qubit, n_qubits)# 调用我们定义好的bitphaseflip_operator()函数circuit += operator                                              # 在量子线路circuit中添加翻转|4>态的相位所需的量子门sim.apply_circuit(circuit)                                       # 通过模拟器sim再次运行搭建好的量子线路circuitcircuit.svg()                                                    # 打印此时的量子线路circuit

从运行的结果看到,发生相位翻转的 ∣ 100 ⟩ |100\rangle ∣100态即为我们希望相位翻转的 ∣ 4 ⟩ |4\rangle ∣4态。

假设我们需要翻转除 ∣ 0 ⟩ |0\rangle ∣0态以外的每个态的相位,运行如下代码:

# pylint: disable=W0104
n_qubits = 3                                                     # 设定量子比特数为3
sim1 = Simulator('mqvector', n_qubits)                           # 使用mqvector模拟器,命名为sim1operator1 = bitphaseflip_operator([i for i in range(1, pow(2, n_qubits))], n_qubits) # 调用我们定义好的bitphaseflip_operator()函数,翻转除|0>态以外的每个态的相位,命名为operator1circuit1 = Circuit()                                             # 初始化量子线路,命名为circuit1
circuit1 += UN(H, n_qubits)                                      # 每位量子比特上执行H门操作
circuit1 += operator1                                            # 在量子线路circuit1中添加翻转除|0>态以外的每个态的相位所需的量子门sim1.apply_circuit(circuit1)                                     # 通过模拟器sim1运行搭建好的量子线路circuit1circuit1.svg()                                                         # 打印此时的量子线路circuit1

从运行的结果看到此时的量子线路,以及我们成功翻转除 ∣ 0 ⟩ |0\rangle ∣0态以外的每个态的相位。

也就是说,我们定义的函数bitphaseflip_operator()可以实现Grover搜素算法中的Oracle算子 U ω U_{\omega} Uω和条件相移算子 P P P

利用MindSpore Quantum实现Grover搜素算法实例

实例1: n = 3 n=3 n=3​, ∣ ω ⟩ = ∣ 2 ⟩ |\omega\rangle=|2\rangle ω=∣2(单目标)

首先,我们需要定义 G G G算子,运行如下代码:

def G(phase_inversion_qubit, n_qubits):           # 定义Grover搜索算法中的G算子operator = bitphaseflip_operator(phase_inversion_qubit, n_qubits)operator += UN(H, n_qubits)operator += bitphaseflip_operator([i for i in range(1, pow(2, n_qubits))], n_qubits)operator += UN(H, n_qubits)return operator

然后,我们根据Grover搜索算法的量子线路模型在MindSpore Quantum中搭建对应的量子线路:

# pylint: disable=W0104
from numpy import pi, sqrtn_qubits = 3                                      # 设定量子比特数为3
phase_inversion_qubit = [2]                       # 设定需要翻转相位的目标态,在这里翻转|2>态的相位N = 2 ** (n_qubits)                               # 计算出数据库中元素的总个数
M = len(phase_inversion_qubit)                    # 计算出目标态的总个数r = int(pi / 4 * sqrt(N / M))                     # 设定G算子迭代次数为rsim2 = Simulator('mqvector', n_qubits)            # 使用mqvector模拟器,命名为sim2circuit2 = Circuit()                              # 初始化量子线路,命名为circuit2
circuit2 += UN(H, n_qubits)                       # 每位量子比特上执行H门操作for i in range(r):                                # 循环执行G算子r次circuit2 += G(phase_inversion_qubit, n_qubits)sim2.apply_circuit(circuit2)                      # 通过模拟器sim2运行搭建好的量子线路circuit2circuit2.svg()                                    # 打印此时的量子线路circuit2

从运行的结果看到, ∣ 010 ⟩ |010\rangle ∣010态的振幅为0.9722718241315036,相比于其它的量子态,这是极大的振幅,也就是说,若我们测量此时的状态,将会以极大的概率得到目标态 ∣ 010 ⟩ |010\rangle ∣010​,运行如下代码进行测量:

# pylint: disable=W0104
from mindquantum.core.gates import Measuresim2.reset()                                      # 重置模拟器sim2维护好的量子态,使得初始化的量子态为|000>circuit2 += UN(Measure(), circuit2.n_qubits)      # 对量子线路circuit2中的每一位量子比特添加测量门result = sim2.sampling(circuit2, shots=1000)      # 通过模拟器sim2对量子线路circuit2进行1000次的采样
result.svg()                                      # 打印采样结果

从运行的结果看到,1000次采样中有923次的采样结果为010(由于具有随机性,每次运行有略微差距),将其转化为10进制数,运行如下代码:

从运行的结果看到,我们成功地搜索出 ∣ 2 ⟩ |2\rangle ∣2态。

实例2: n = 5 n=5 n=5 ∣ ω ⟩ = ∣ 5 ⟩ |\omega\rangle=|5\rangle ω=∣5 ∣ 11 ⟩ |11\rangle ∣11(多目标)

实例1中实现的是单目标搜索,现在我们尝试实现多目标搜索。首先, G G G算子已经定义好了,我们只需设定量子比特数和需要翻转相位的目标态,然后搭建对应的量子线路即可,运行如下代码:

# pylint: disable=W0104
n_qubits = 5                                      # 设定量子比特数为5
phase_inversion_qubit = [5, 11]                   # 设定需要翻转相位的目标态,在这里翻转|5>态和|11>态的相位N = 2 ** (n_qubits)                               # 计算出数据库中元素的总个数
M = len(phase_inversion_qubit)                    # 计算出目标态的总个数r = int(pi / 4 * sqrt(N / M))                     # 设定G算子迭代次数为rsim3 = Simulator('mqvector', n_qubits)            # 使用mqvector模拟器,命名为sim3circuit3 = Circuit()                              # 初始化量子线路,命名为circuit3
circuit3 += UN(H, n_qubits)                       # 每位量子比特上执行H门操作for i in range(r):                                # 循环执行G算子r次circuit3 += G(phase_inversion_qubit, n_qubits)sim3.apply_circuit(circuit3)                      # 通过模拟器sim3运行搭建好的量子线路circuit3circuit3.svg()                                          # 打印此时的量子线路circuit3

从运行的结果看到, ∣ 00101 ⟩ |00101\rangle ∣00101​​和 ∣ 01011 ⟩ |01011\rangle ∣01011​​态的振幅均为0.6932961018664989,相比于其它的量子态,这是极大的振幅,也就是说,若我们测量此时的状态,将会以极大的概率得到目标态 ∣ 00101 ⟩ |00101\rangle ∣00101​​和 ∣ 01011 ⟩ |01011\rangle ∣01011​​态,运行如下代码进行测量:

# pylint: disable=W0104
sim3.reset()                                      # 重置模拟器sim3维护好的量子态,使得初始化的量子态为|00000>circuit3 += UN(Measure(), circuit3.n_qubits)      # 对量子线路circuit3中的每一位量子比特添加测量门result1 = sim3.sampling(circuit3, shots=1000)     # 通过模拟器sim3对量子线路circuit3进行1000次的采样
result1.svg()                                     # 打印采样结果

从运行的结果看到,1000次采样中有487次的采样结果为00101和478次的采样结果为01011(由于具有随机性,每次运行会略有不同),将其转化为10进制数,运行如下代码:
从运行的结果看到,我们成功地搜索出 ∣ 5 ⟩ |5\rangle ∣5​​和 ∣ 11 ⟩ |11\rangle ∣11​​​​​态。

至此,我们介绍了Grover搜索算法的基本原理,以及通过两个具体的小例子来展示如何利用MindSpore Quantum实现该算法!赶紧动手体验一下量子编程的乐趣吧!

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

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

相关文章

《让手机秒变超级电脑!ToDesk云电脑、易腾云、青椒云移动端评测》

前言 科技发展到如今2024年&#xff0c;可以说每一年都在发生翻天覆地的变化。而云上这个词时常都被大家提起&#xff0c;从个人设备连接到云端在如今在也不是梦了。而云电脑这个市场近年来迅速发展&#xff0c;无需购买和维护额外的硬件就可以体验到电脑端顶配的性能和体验&am…

ESP32本地大模型对话机器人制作教程

整体架构 在本地电脑部署好Ollama服务&#xff0c;安装qwen大模型和llama3.1大模型。 ESP32接入局域网&#xff0c;用户通过串口给esp32发送问题&#xff0c;esp32打包json后向ollama服务发送请求&#xff0c;ollama返回响应&#xff0c;esp32解析结果并通过串口打印出来。 …

详解ChatBI Agent架构:打造高效数据统计系统

随着人工智能技术的迅猛发展&#xff0c;智能对话系统在各行各业中的应用越来越广泛。本文将介绍一种名为ChatBI Agent的架构设计&#xff0c;并以电信运营商系统的经分数据统计Agent为案例&#xff0c;结合具体的代码实现&#xff0c;帮助读者了解这一系统的设计理念和实现方式…

2024年开放式蓝牙耳机十大排名震撼揭晓!哪款开放式耳机是音质王者?

​耳机市场上&#xff0c;有线入耳式、无线蓝牙入耳式和开放式耳机三足鼎立&#xff0c;各展风采。有线入耳式耳机虽然连接稳定&#xff0c;但线缆易缠绕&#xff0c;佩戴不够稳固&#xff1b;无线入耳式耳机虽然剪断了线的束缚&#xff0c;但长时间使用可能会引起耳朵不适。相…

FFmpeg开发笔记(五十六)使用Media3的Exoplayer播放网络视频

Android早期的MediaPlayer控件对于网络视频的兼容性很差&#xff0c;所以后来单独推出了Exoplayer库增强支持网络视频&#xff0c;在《Android Studio开发实战&#xff1a;从零基础到App上线(第3版)》一书第14章的“14.3.3 新型播放器ExoPlayer”就详细介绍了Exoplayer库的详细…

信息安全工程师(10)网络信息安全法律与政策文件

前言 网络信息安全法律与政策文件是保障网络安全、维护网络空间秩序、保护公民和组织合法权益的重要基石。 一、主要法律文件 《中华人民共和国网络安全法》 发布时间&#xff1a;2016年11月7日&#xff0c;由第十二届全国人民代表大会常务委员会第二十四次会议通过。主要内容&…

打工人必看!AI 编程助手让你轻松应对任务!

在当今科技飞速发展的时代&#xff0c;我们作为开发者面临着前所未有的挑战。技术栈频繁迭代&#xff0c;项目周期逐渐缩短&#xff0c;但对代码质量和的要求却不断提升这样的环境下&#xff0c;如何有效提升编程效率成为了一个永恒的议题。 最近&#xff0c;我找到了一位强大…

华为地图服务 - 如何在地图上绘制圆? -- HarmonyOS自学17

场景介绍 本章节将向您介绍如何在地图上绘制圆形。 接口说明 添加圆形功能主要由MapCircleOptions、addCircle和MapCircle提供&#xff0c;更多接口及使用方法请参见接口文档。 接口名 描述 MapCircleOptions 用于描述MapCircle属性。 addCircle(options: mapCommon.MapC…

Linux文件IO(三)-Linux系统如何管理文件

1.静态文件与 inode 文件在没有被打开的情况下一般都是存放在磁盘中的&#xff0c;譬如电脑硬盘、移动硬盘、U 盘等外部存储设备&#xff0c;文件存放在磁盘文件系统中&#xff0c;并且以一种固定的形式进行存放&#xff0c;我们把他们称为静态文件。 文件储存在硬盘上&#…

《DevOps实践指南》笔记-Part 1

前言 Infrastructure as Code&#xff1a;基础设施即代码&#xff0c;IaC。 Kanban&#xff1a;看板管理&#xff0c;丰田生产模式中的重要概念&#xff0c;指为了达到及时生产方式控制现场生产流程的工具。及时生产方式中的拉式生产系统可以使信息的流程缩短&#xff0c;并配…

unix中的进程标识以及使用场景

一、前言 本文将介绍unix系统中的进程标识以及使用场景。进程标识和用户标识类似&#xff0c;只不过其指代的对象是一个进程。我们常把进程标识称为进程ID&#xff0c;本文将讨论如下内容&#xff1a; 1.什么是进程标识&#xff1f; 2.特殊的进程标识 3.如果获取以及使用进程标…

神经网络推理加速入门——一个例子看懂流水

之前的两篇文章介绍了流水这一技术&#xff0c;它用来进行程序的性能加速&#xff0c;本篇通过一个生活中的小例子&#xff0c;让大家更直观的了解什么是流水。 举个例子 早晨从起床到上班出门&#xff0c;我们一般会做以下几件事&#xff1a;刷牙、烧水、喝水、出门。 如果…

全球爆发勒索病毒“永恒之蓝” 解决方案在此

英国、意大利、俄罗斯等全球多个国家爆发勒索病毒攻击&#xff0c;中国大批高校也出现感染情况&#xff0c;众多师生的电脑文件被病毒加密&#xff0c;只有支付赎金才能恢复。据360安全卫士紧急公告&#xff0c;不法分子使用NSA泄漏的黑客武器攻击Windows漏洞&#xff0c;把ONI…

新品亮相|美格智能SLM530/SLM530P智能模组,助力金融新零售智慧升级

随着金融支付产业数字化与智能化不断推进&#xff0c;泛支付场景一体化解决方案成为行业发展的新趋势&#xff0c;从手持POS机到智能收款机&#xff0c;金融支付领域需要更快速、更精准、更安全的解决方案&#xff0c;加快推进数字化升级进程。 近期&#xff0c;美格智能正式发…

JavaWeb - 5 - 前端工程化

一.前后端分离开发 前后端混合开发 缺点&#xff1a;沟通成本高&#xff0c;分工不明确&#xff0c;不便管理&#xff0c;不便维护拓展 前后端分离开发 当前最为主流的开发模式&#xff1a;前后端分离 前后端分离开发中很重要的是API接口文档&#xff08;如&#xff1a;YApi&…

1--SpringBoot外卖项目介绍及环境搭建 详解

目录 软件开发整体流程 软件开发流程 角色分工 软件环境 苍穹外卖项目介绍 项目介绍 产品原型 技术选型 开发环境搭建 前端环境搭建 后端环境搭建 完善登录功能 导入接口文档 Swagger 介绍 使用方式 常用注解 软件开发整体流程 软件开发流程 需求分析&#x…

JavaWeb的Filter详解

过滤器Filter 什么是Filter&#xff1f; 依据字面上的中文意思为过滤器。Filter的作用 当用户的请求到达指定的URL之前&#xff0c;可以借助Filter来改变这些请求的内容&#xff1b;同样地&#xff0c;当响应结果到达客户端之前&#xff0c;可以使用Filter修改输出的内容。什么…

基于springboot的驾校管理系统的设计与实现 (含源码+sql+视频导入教程)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1 、功能描述 基于springboot的驾校管理系统4拥有三种角色&#xff0c;分别为管理员、教练、学员。 管理员&#xff1a;学员/教练管理、报名管理、车辆管理、教练分配管理、课程安排管理、考勤打卡管理…

数字化转型的理论框架对比:从多维视角指导企业成功变革对比DPBOKIT4ITCOBITTOGAF

数字化转型的多维框架解析 在数字化时代&#xff0c;企业如何有效实现数字化转型已成为其生存和发展的关键问题。然而&#xff0c;市场上关于数字化管理的各种框架和理论并存&#xff0c;企业需要根据自身的需求选择最适合的指导路径。本文将通过对几个核心理论框架的对比&…

【随手笔记】使用J-LINK读写芯片内存数据

第一种使用JLINK.exe 1. 打开j-link.exe 2.输入【usb】 3. 连接芯片 输入【connect】输入芯片型号【STM32L071RB】输入连接方式 【S】 使用SWD连接方式输入连接速率 【4000】连接成功 4. 输入【&#xff1f;】查看指令提示 5. 读写指令 Mem Mem [<Zone>…