多载波调制与OFDM原理讲解以及MATLAB实现GUI设计

前言

基于MATLAB设计并实现了一个OFDM调制的图形用户界面(GUI)系统。该系统旨在简化OFDM调制过程的仿真,提供友好的用户交互界面。设计目标是通过GUI实现参数化的OFDM仿真,包括子载波数、符号数、IFFT长度、循环前缀长度、循环后缀长度和信噪比等参数的动态调节。系统支持多种调制方式(如QPSK、16QAM、64QAM、256QAM)和单径、多径信道模型,并实时显示OFDM信号的时域图和星座图。用户可通过GUI调整各项参数,启动或暂停仿真,观察误码率的变化。

多载波调制思想

在信道不理想的条件下,若采用单一正弦波作为载波实现调制,已调信号频带上很难保持理想传输特性,容易造成信号的严重失真和码间串扰。

多载波调制就是把数据流分解为若干个载波,因此,在多载波调制信道中,数据传输速率相对较低,码元周期较长,克服了单载波调制方式码元持续时间Ts短,占用带宽B大,信号特性\left | C(f) \right |不理想,易产生码间串扰等缺点。只要时延扩展与码元周期相比小于一定的值,就不会产生码间串扰,因而多载波调制对于信道的时间弥散性不敏感,具有较强的抗多径传播和抗频率选择性衰落的能力以及较高的频谱利用率。

OFDM可以抵抗多径干扰,是当前研究的一个热点。在4G移动通信等高速无线通信系统中得到了广泛的应用。

OFDM原理

OFDM时域图绘制 

一个OFDM系统中有N个子信道,每个子信道采用的子载波为

x_{k}(t)= B_{k}cos(2\pi f_{k}t+\varphi_{k})

其中B_{k}是第k路子载波的振幅,它受基带码元的调制,f_{k}为第k路子载波的频率,\varphi_{k}为第k路子载波的初始相位,则在此系统中的N路自信号之和可以表示为

 e(t)=\sum_{k=0}^{N-1}x_{k}(t)= \sum_{k=0}^{N-1}B_{k}cos(2\pi f_{k}t+\varphi_{k})

复数形式为

e(t)= \sum_{k=0}^{N-1}B_{k} e^{j(2\pi f_{k}t+\varphi_{k})} 

代码在下面频域部分一起给出。 

这一步没什么难的,就是根据公式s(k) =\sum_{i=0}^{N-1} \exp(j2\pi \frac{ik}{N})实现。

OFDM频域图绘制

在我查过资料之后,大家基本上都是直接使用sinc绘制的。比如这下面的是来源于知乎的一篇代码生成的。

NoOfCarriers = 11;              % 设定载波的数量(需要保证是奇数)
iMin = -(NoOfCarriers-1)/2;     % 最小的子载波的索引
iMax = (NoOfCarriers-1)/2;      % 最大的子载波的索引
f = -10:0.01:10;                % 设定频率是从-10MHz到10MHz
fList = zeros(1,NoOfCarriers);  % 频率列表,用来存储各sinc函数的中心频率
cList = zeros(1,NoOfCarriers);  % 幅值列表,用来存储各sinc函数的幅值
%************************** 画出各OFDM子载波的频域图 **************************%
for i=iMin:1:iMax% 计算出每一个OFDM子载波的sinc函数fshift = i ;c = sinc(f - fshift);fList(i+NoOfCarriers) =  fshift;cList(i+NoOfCarriers) = max(c);plot(f,c,'linewidth',1.5);hold on;stem(i ,1,'r-','linewidth',1.5);
end
xlabel("频率 MHz");
grid();
hold off;

那么为什么是sinc呢?实际上OFDM信号不可能是无限长的,而有限长的OFDM信号实际可以看做与矩形窗函数的乘积,矩形窗函数可以定义如下:

g(t) = \left\{\begin{matrix} 1 , 0<\left | t \right |<T\\ 0, \left | t \right |>T \end{matrix}\right.

对其进行傅里叶变换:

G(jw)=\frac{sin(\frac{wT}{2})}{\frac{w}{2}}

由于时域相乘等效于频域卷积,因此OFDM信号反映到频谱,就成为各个不同位置的冲击响应与sinc函数的卷积。

这里我们来看看怎么对时域波形做fft变换。

% ======================== 绘制时域波形图 =======================
Fs = 1000;                               % 总的采样率
N = 1024;                                % 总的子载波数
T = N / Fs;                              % 信号绘制为一个周期的长度
x = 0 : 1/Fs : T-1/Fs;                   % 生成时间向量,用于绘制波形
Numscr = 4;                              % 绘制的子载波数量
s_data = 1;                              % 初始相位
y = zeros(Numscr, numel(x));             % 初始化存储每个子载波的复数值的矩阵
ini_phase = ones(1, numel(x));           % 生成与时间长度相匹配的初始相位向量% 生成所有子载波的时域波形
for k = 0 : Numscr-1                     % 循环遍历要绘制的子载波数量y(k+1, :) = ini_phase .* exp(1i * 2 * pi * k * (0:numel(x)-1) / N); % 计算每个时间点上每个子载波的复数值
end% 绘制时域波形
figure(1);
plot(x, real(y));     
xlabel('时间/s');                
ylabel('幅度/V');               
title('多路子载波的时域波形');       
grid on; % ======================== 绘制频域波形图 =======================
a = 20;                                  % 扩展系数
total_length = (a + 1) * N;
delta_f = Fs / total_length;
f = (-Fs / 2) : delta_f : (Fs / 2 - delta_f);
y1 = zeros(Numscr, a * N);
y_combined = horzcat(y, y1); 
y_fft = zeros(Numscr, (a+1)*N);
for k = 1 : Numscry_fft(k, :) = real(fftshift(fft(y_combined(k,:)))) / N;  % 计算每个子载波的频谱
endfigure(2);
plot(f, y_fft(1,:), f, y_fft(2,:), f, y_fft(3,:), f, y_fft(4,:));
grid on;
xlim([-10, 10]);
xlabel('频率/Hz');
ylabel('幅度/V');
title('多路子载波的频域波形'); 

a为扩展系数,设置为20,用于增加频谱的分辨率。扩展后的信号长度为 (a + 1) 倍的 N,这样就能扩展频谱分辨率,扩展后的频谱分辨率显著提高,频率间隔变得更小,频谱图更加细腻和平滑。

验证IDFT实现OFDM和模拟调制实现是否完全等效

假设OFDM系统包含了8个子载波,载波频率为1kHz,子载波频率间隔为1kHz,每个子载波采用4QAM调制,符号周期为1ms,试比较OFDM的模拟调制实现与IDFT/DFT实现。

% 参数设置
N = 8;                      % 子载波数
x = randi([0, 3], 1, N);    % 随机生成子载波上的数据
x1 = qammod(x, 4);          % 采用4-QAM调制
f = 1:N;                    % 子载波频率
t = 0:0.001:1-0.001;        % 符号持续时间% 模拟调制实现
w = 2*pi*f.'*t;             % 子载波频率矩阵
y1 = x1 * exp(1i * w);      % 模拟调制实现% IDFT实现
x2 = ifft(x1, N);           % 计算逆离散傅里叶变换
x2_time = (0:N-1)/N;        % IDFT时间轴% 绘制波形比较
figure;
plot(t, abs(y1));           % 绘制模拟调制实现的时域波形
hold on;
stem(x2_time, abs(x2) * N, '-r'); % 绘制IDFT实现的时域波形
legend('模拟调制实现','IDFT实现');
title('模拟调制实现与IDFT比较');
xlabel('时间 (s)');
ylabel('幅度');% 验证IDFT和FFT的关系
x3 = fft(x2, N);            % 计算快速傅里叶变换disp(x1);
disp(x3);

升余弦窗处理

为了减少旁瓣干扰,提高系统的抗干扰性能,对添加了循环前缀和循环后缀的信号进行升余弦窗处理。升余弦窗处理通过调整信号的幅度,减少频域中的旁瓣,从而降低干扰。升余弦窗的系数计算使用了sin函数,目的是在窗函数的边界部分创建一个平滑的过渡。

窗口长度T由窗口的总长度bitLength和滚降系数\alpha决定:

T=\frac{bitLength}{2(1+\alpha )}

然后,计算窗口系数window(t)其中 t 是从 1 到 \frac{bitLength}{2}的向量:

window(t)=\frac{1}{2}(1-sin(\frac{\pi}{2\alpha T}\ast T))

这个公式通过sin函数在窗口的边界部分创建一个平滑的过渡,以减少频谱中的旁瓣干扰。注意这里的计算方式与标准升余弦窗的公式不同,更类似于汉宁窗(Hann window)的计算方式。对于(1-\alpha )范围内的T窗口系数设置为1,表示在窗口的平坦部分,信号保持不变:

window(1:(1-\alpha )\ast T)

最后,将窗口反转并拼接,生成完整的升余弦窗。通过升余弦窗处理,可以有效地减少频谱中的旁瓣干扰,从而提高信号的传输质量。使用sin函数是为了在窗口的边界部分创建一个平滑的过渡,以减少干扰。尽管这里与标准升余弦窗有所不同,但其基本思想是相同的,即通过平滑过渡减少频谱旁瓣干扰。

function window = rcoswindow(alpha, bit_length)warning off;window = zeros(1, bit_length / 2);t = 1:bit_length / 2;T = bit_length / (2 * (1 + alpha));window(t) = 0.5 * (1 - sin(pi / (2 * alpha * T) * (t - T)));window(1:(1 - alpha) * T) = 1;window = [fliplr(window) window]';
end

OFDM实现

clear all;
close all;% OFDM仿真参数
carrier_count = 200;    % 子载波数
symbol_count = 100;     % 总符号数
ifft_length = 512;      % IFFT长度
CP_length = 128;        % 循环前缀长度
CS_length = 20;         % 循环后缀长度
alpha = 7/32;           % 升余弦窗系数
SNR = 20;               % 信噪比
rate = [];% 选择调制方式:'QPSK'、'16QAM'、'64QAM'、'256QAM'
modulation_type = 'QPSK'; % 可以修改为 'QPSK', '64QAM', '256QAM'switch modulation_typecase 'QPSK'M = 4;case '16QAM'M = 16;case '64QAM'M = 64;case '256QAM'M = 256;otherwiseerror('Unsupported modulation type');
endbit_per_symbol = log2(M);
bit_length = carrier_count * symbol_count * bit_per_symbol;bit_sequence = randi([0, 1], bit_length, 1); % 绘制生成随机二进制序列
figure(1);
bar(bit_sequence(1:50), 'b');
xlabel('Bit Index');
ylabel('Bit Value');
title('Binary Source Code Distribution');
grid on;% ================子载波调制方式========================
bit_moded = qammod(bit_sequence, M, 'InputType', 'bit', 'UnitAveragePower', true);
figure('position', [0 0 400 400]);
scatter(real(bit_moded), imag(bit_moded));
title(['调制后的散点图 - ', modulation_type]);
grid on;
% ===================IFFT===========================
% =================串并转换==========================
ifft_position = zeros(ifft_length, symbol_count);
bit_moded = reshape(bit_moded, carrier_count, []);
figure('position', [400 0 400 400]);
stem(abs(bit_moded(:, 1)));
grid on;% 1-28置零 29-228有效 229-285置零 286-485共轭 486-512置零
carrier_position = 29:228;
conj_position = 485:-1:286;
ifft_position(carrier_position, :) = bit_moded;
ifft_position(conj_position, :) = conj(bit_moded);
signal_time = ifft(ifft_position, ifft_length);   % 512   100
figure('position', [0 400 400 400]);
subplot(3,1,1);
plot(signal_time(:, 1), 'b');
title('原始单个OFDM符号');
xlabel('Time');
ylabel('Amplitude');% ==================加循环前缀和后缀==================
signal_time_C = [signal_time(end-CP_length+1:end, :); signal_time];
signal_time_C = [signal_time_C; signal_time_C(1:CS_length, :)];
subplot(3,1,2); % 单个完整符号为512+128+20=660
plot(signal_time_C(:, 1));
xlabel('Time');
ylabel('Amplitude');
title('加CP和CS的单个OFDM符号');% =======================加窗========================
signal_window = signal_time_C .* repmat(rcoswindow(alpha, size(signal_time_C, 1)), 1, symbol_count);
subplot(3,1,3);
plot(signal_window(:, 1));
title('加窗后的单个OFDM符号');
xlabel('Time');
ylabel('Amplitude');
% ===================发送信号,多径信道====================
signal_Tx = reshape(signal_window, 1, []); % 时域完整信号
signal_origin = reshape(signal_time_C, 1, []); % 未加窗完整信号
mult_path_am = [1 0.2 0.1]; % 多径幅度
mutt_path_time = [0 20 50]; % 多径时延
path2 = 0.2 * [zeros(1, 20) signal_Tx(1:end-20)];
path3 = 0.1 * [zeros(1, 50) signal_Tx(1:end-50)];
signal_Tx_mult = signal_Tx + path2 + path3; % 多径信号figure(5);
subplot(2,1,1);
plot(signal_Tx_mult);
title('多径下OFDM信号');
xlabel('Time/samples');
ylabel('Amplitude');
subplot(2,1,2);
plot(signal_Tx);
title('单径下OFDM信号');
xlabel('Time/samples');
ylabel('Amplitude');% =====================发送信号频谱========================
% ====================未加窗信号频谱=======================
% 每个符号求频谱再平均,功率取对数
figure(6);
orgin_aver_power = 20 * log10(mean(abs(fft(signal_time_C'))));
subplot(2,1,1);
plot((1:length(orgin_aver_power)) / length(orgin_aver_power), orgin_aver_power);
hold on;
plot(0:1/length(orgin_aver_power):1, -35, 'rd');
hold off;
axis([0 1 -40 max(orgin_aver_power)]);
grid on;
title('未加窗信号频谱');
% ====================加窗信号频谱=========================
orgin_aver_power = 20 * log10(mean(abs(fft(signal_window'))));
subplot(2,1,2);
plot((1:length(orgin_aver_power)) / length(orgin_aver_power), orgin_aver_power);
hold on;
plot(0:1/length(orgin_aver_power):1, -35, 'rd');
hold off;
axis([0 1 -40 max(orgin_aver_power)]);
grid on;
title('加窗信号频谱');% ========================加AWGN==========================
Rx_data_sig = awgn(signal_Tx, SNR, 'measured'); % 向单径信号添加噪声
Rx_data_mut = awgn(signal_Tx_mult, SNR, 'measured'); % 向多径信号添加噪声% =======================串并转换==========================
Rx_data_mut = reshape(Rx_data_mut, ifft_length + CS_length + CP_length, []);
Rx_data_sig = reshape(Rx_data_sig, ifft_length + CS_length + CP_length, []);% ====================去循环前缀和后缀======================
Rx_data_sig(1:CP_length, :) = [];
Rx_data_sig(end-CS_length+1:end, :) = [];
Rx_data_mut(1:CP_length, :) = [];
Rx_data_mut(end-CS_length+1:end, :) = [];% FFT
fft_sig = fft(Rx_data_sig);
fft_mut = fft(Rx_data_mut);% 降采样
data_sig = fft_sig(carrier_position, :);
data_mut = fft_mut(carrier_position, :);figure;
scatter(real(reshape(data_sig, 1, [])), imag(reshape(data_sig, 1, [])), '.');
grid on;
title('单径下接收信号星座图');figure;
scatter(real(reshape(data_mut, 1, [])), imag(reshape(data_mut, 1, [])), '.');
grid on;
title('多径下接收信号星座图');% =========================逆映射===========================
bit_demod_sig = reshape(qamdemod(data_sig, M, 'OutputType', 'bit'), [], 1);
bit_demod_mut = reshape(qamdemod(data_mut, M, 'OutputType', 'bit'), [], 1);% =========================误码率===========================
error_bit_sig = sum(bit_demod_sig ~= bit_sequence);
error_bit_mut = sum(bit_demod_mut ~= bit_sequence);
error_rate_sig = error_bit_sig / bit_length;
error_rate_mut = error_bit_mut / bit_length;
rate = [rate; error_rate_sig error_rate_mut];% 打印误码率
fprintf('单径误码率: %f\n', error_rate_sig);
fprintf('多径误码率: %f\n', error_rate_mut);

生成的波形如下所示: 

图1 

图1上展示了一个原始单个OFDM符号的时域波形。该图像显示了OFDM符号在时域上的分布情况,未添加任何前缀或后缀。图1中展示了添加循环前缀(CP)和循环后缀(CS)后的单个OFDM符号。循环前缀和后缀有助于克服信道中的多径效应,并改善信号的接收性能。图1下展示了加窗后的单个OFDM符号。升余弦窗的应用使信号在边缘处更加平滑,从而减少频谱泄漏和旁瓣干扰。 

图2 单径与多径下OFDM信号

图2展示了单径和多径情况下的OFDM信号。多径效应引入了信号的时延和幅度变化,导致信号波形在多径情况下更加复杂。这部分仿真展示了信号在不同传输环境下的变化。

图3 加窗子与未加窗信号频谱图对比

图3展示了加窗和未加窗信号的频谱对比。通过比较可以看到,加窗后的信号频谱在边缘部分有显著的改善,表明升余弦窗在减少频谱泄漏方面的有效性。

图4 单径与多径下接受信号星座图

图4展示了单径和多径情况下的接收信号星座图。在单径情况下,接收的星座点较为集中,表示信号失真较小;而在多径情况下,由于多径效应的影响,星座点出现了明显的散布,显示出信号在复杂信道环境下的失真程度。

用户界面设计

界面整体设计采用两栏式设计,左侧为参数设置模块,右侧为结果显示模块。

左侧的参数设置模块提供了多个输入控件,用户可以在这里设置信噪比(SNR)、子载波数、符号数、IFFT长度、循环前缀长度、循环后缀长度以及调制方式等参数。这些控件包括文本框、下拉菜单和旋钮,用户可以通过这些控件输入或选择相应的数值和选项,以便精确地控制OFDM系统的仿真环境。在参数设置模块,还设计了开始仿真、暂停(恢复)仿真和结束仿真的按钮。用户点击“开始仿真”按钮后,系统会根据设置的参数启动仿真过程。在仿真进行中,用户可以通过“暂停”按钮暂时中止仿真,通过“恢复”按钮继续仿真,而点击“结束仿真”按钮则可以完全停止当前的仿真过程。

右侧的结果显示模块主要用于展示OFDM信号的时域波形和接收信号的星座图。在仿真过程中,系统会实时更新结果显示模块的内容,以便用户可以直观地观察OFDM信号的变化和传输效果。通过时域波形图,用户可以看到经过IFFT变换后的信号时域表现;通过星座图,用户可以分析接收信号的解调效果和误码情况。此外,结果显示模块还会实时显示系统的误码率,帮助用户评估不同参数设置下系统的性能。

动态演示

项目资源

你可以通过github下载整个项目资源。包括程序版本与独立桌面版本。

Auorui/Design-of-OFDM-GUI: 基于matlab的OFDM GUI设计 (github.com)

由于为了方便,误码率的计算是通过每次勾选复选框进行计算的。它并不是实时的,在多径上面误码率较大。 

参考文章

nayakanuj/playingWithOFDM(github.com)

OFDM基本原理_ofdm信号-CSDN博客

OFDM通信系统的MATLAB仿真(2) - 羽扇纶巾o0 - 博客园 (cnblogs.com)

OFDM调制matlab仿真详细代码_ofdm matlab-CSDN博客

如何画OFDM频谱图-CSDN博客

OFDM系统仿真【matlab代码】-CSDN博客

无线通信基础2:深入理解OFDM(含Matlab代码) - 知乎 (zhihu.com)

【现代数字传输】OFDM的原理讲解和MATLAB实现_ofdm matlab-CSDN博客

OFDM学习--第二节 用Matlab仿真基本的链路_哔哩哔哩_bilibili

给“小白”图示讲解OFDM的原理(受益匪浅,OFDM小白强推)_直观图解ofdm原理-CSDN博客

OFDM系统仿真【matlab源码】_ofdmmatlab仿真代码-CSDN博客

OFDM完整仿真过程及解释(MATLAB) - 简书 (jianshu.com)

OFDM原理及MATLAB仿真-CSDN博客

OFDM演示GUI_哔哩哩_bilibili

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

模拟退火算法2—优缺点

模拟退火算法优点 1、以一定的概率接受恶化解 模拟退火算法(SA)在搜索策略上与传统的随机搜索方法不同,它不仅引入了适当的随机因素,而且还引入了物理系统退火过程的自然机理。这种自然机理的引入使模拟退火算法在迭代过程中不仅接受使目标函数变“好”的试探点,而且还能以一…

【单片机毕业设计选题24034】-基于STM32的手机智能充电系统

系统功能: 系统可以设置充电时长&#xff0c;启动充电后按设置的充电时长充电&#xff0c;充电时间到后自动 停止充电&#xff0c;中途检测到温度过高也会结束充电并开启风扇和蜂鸣器报警。 系统上电后&#xff0c;OLED显示“欢迎使用智能充电系统请稍后”&#xff0c;两秒钟…

哨兵1SAR空间数据包协议数据单元文档(五)

《哨兵1SAR空间数据包协议数据单元》文档对数据包的结构进行了详细描述&#xff0c;并提供了用户数据的格式和解码算法。 原文链接: 哨兵1SAR空间数据包协议数据单元文档英文版 同系列中的其他文章篇链接: 哨兵1SAR空间数据包协议数据单元文档&#xff08;一&#xff09; 哨兵1…

保存在FinalShell服务器登录密码忘记了,如何快速获取到

一、从FinalShell获取服务器基本信息 如图操作会导出一个json文件&#xff0c;可以直接保存在桌面&#xff0c;或者其他位置 json格式如下&#xff1a; {"forwarding_auto_reconnect":false ,"custom_size":false ,"delete_time":0 ,"sec…

Python数据分析-旧金山犯罪预测分析(San Francisco Crime Classification)

一、研究背景 旧金山是一个人口稠密、旅游业发达的城市&#xff0c;同时也是美国犯罪率较高的城市之一。随着城市的不断发展&#xff0c;犯罪行为的类型和频率也在不断变化&#xff0c;这对城市的治安管理和社会稳定构成了巨大的挑战。近年来&#xff0c;数据科学技术的迅猛发…

C# 编程中互斥锁的使用

C# 中的互斥锁 互斥锁是 C# 中使用的同步原语&#xff0c;用于控制多个线程或进程对共享资源的访问。其目的是确保在任何给定时间只有一个线程或进程可以获取互斥锁&#xff0c;从而提供互斥。 C# 中互斥锁的优点 可以使用互斥锁 (Mutex) 并享受其带来的好处。 1. 共享资源…

德国威步的技术演进之路(下):从云端许可管理到硬件加密狗的创新

从单机用户许可证到WkNET网络浮点授权的推出&#xff0c;再到引入使用次数和丰富的时间许可证管理&#xff0c;德国威步产品不断满足市场对灵活性和可扩展性的需求。TCP/IP浮动网络许可证进一步展示了威步技术在网络时代的创新应用。借助于2009年推出的借用许可证以及2015年推出…

mac磁盘工具如何合并分区 macos 磁盘工具 无法抹除 磁盘管理软件哪个使用率最高

一、什么是NTFS格式分区 NTFS格式分区是微软公司开发的诸多文件系统中的一种。NTFS格式分区是一种文件系统&#xff0c;磁盘只有在安装了文件系统后才能被正常使用&#xff0c;文件系统的格式有非常多&#xff0c;常见的有FAT 32和NTFS。 作为常见文件系统&#xff0c;NTFS格式…

无人机集群协同搜索研究综述

源自&#xff1a;指挥控制与仿真 作者&#xff1a;刘圣洋, 宋婷, 冯浩龙, 孙玥, 韩飞 注&#xff1a;若出现无法显示完全的情况&#xff0c;可 V 搜索“人工智能技术与咨询”查看完整文章 摘要 无人机集群协同区域搜索能够有效地获取任务区域地面信息,降低环境不确定度。基…

买卖股票的最佳时期含冷冻期(leetcode)

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 也就有这样的状态转移方程&#xff1a; 买入&#xff1a;dp[i][0] max(dp[i-1][1] - prices[i], dp[i-1][0]); 可买入&#xff1a;dp[i][1] max(dp[i-1][1], dp[i-1][2]); 冷冻期&#xff1a;dp[i][2] dp[i-1][0] prices…

使用ChatGPT自动生成测试用例思维导图

使用ChatGPT自动生成测试用例思维导图 引言ChatGPT在测试用例编写中的应用全面覆盖测试场景边界测试避免测试用例重复 借助ChatGPT生成测试用例思维导图准备工作步骤一&#xff1a;与ChatGPT对话步骤二&#xff1a;生成思维导图代码 结语 引言 在编写测试用例时&#xff0c;测…

基于Python Django的房价数据分析平台,包括大屏和后台数据管理,有线性、向量机、梯度提升树、bp神经网络等模型

背景 随着城市化进程的加速和房地产市场的快速发展&#xff0c;房价已成为经济学、社会学等多学科交叉研究的热点问题。为了更精确地分析和预测房价&#xff0c;数据分析和机器学习技术被广泛应用。在此背景下&#xff0c;开发一个基于Python Django的房价数据分析平台具有重要…

职业技能大赛引领下物联网专业实训教学的改革研究

随着物联网技术的迅猛发展&#xff0c;作为培养高技能应用型人才的高职院校&#xff0c;面临着将理论与实践深度结合&#xff0c;以满足行业对物联网专业人才新要求的挑战。职业技能大赛作为一种重要的教育评价与促进机制&#xff0c;为物联网专业实训教学的改革提供了新的视角…

成人高考本科何时报名-深职训学校帮您规划学习之路

你有想过继续深造自己的学历吗&#xff1f;也许你已经工作多年&#xff0c;但总觉得学历是一块心病&#xff0c;想要通过成人高考本科来提升自己。不用着急&#xff0c;今天我们来聊一聊成人高考本科的报名时间&#xff0c;以及深职训学校如何帮助你顺利完成报名。 深圳成人高…

LeetCode-刷题记录-滑动窗口合集(本篇blog会持续更新哦~)

一、滑动窗口概述 滑动窗口&#xff08;Sliding Window&#xff09;是一种用于解决数组&#xff08;或字符串&#xff09;中子数组&#xff08;或子串&#xff09;问题的有效算法。 Sliding Window核心思想&#xff1a; 滑动窗口技术的基本思想是维护一个窗口&#xff08;一般…

怎样在Python中使用oobabooga的API密钥,通过端口5000获取模型列表的授权

题意&#xff1a; oobabooga-textgen-web-ui how to get authorization to view model list from port 5000 via the oobas api-key in python 怎样在Python中使用oobabooga的API密钥&#xff0c;通过端口5000获取模型列表的授权 问题背景&#xff1a; I wish to extract an…

fastapi+vue3前后端分离开发第一个案例整理

开发思路 1、使用fastapi开发第一个后端接口 2、使用fastapi解决cors跨域的问题。cors跨域是浏览器的问题&#xff0c;只要使用浏览器&#xff0c;不同IP或者不同端口之间通信&#xff0c;就会存在这个问题。前后端分离是两个服务&#xff0c;端口不一样&#xff0c;所以必须要…

XLSX + LuckySheet + LuckyExcel实现前端的excel预览

文章目录 功能简介简单代码实现效果参考 功能简介 通过LuckyExcel的transformExcelToLucky方法&#xff0c; 我们可以把一个文件直接转成LuckySheet需要的json字符串&#xff0c; 之后我们就可以用LuckySheet预览excelLuckyExcel只能解析xlsx格式的excel文件&#xff0c;因此对…

.NET 漏洞分析 | 某ERP系统存在SQL注入

01阅读须知 此文所提供的信息只为网络安全人员对自己所负责的网站、服务器等&#xff08;包括但不限于&#xff09;进行检测或维护参考&#xff0c;未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供的信息而造成的直接或间接后果和损失&#xf…

学习笔记——动态路由——OSPF(认证)

十二、OSPF邻居认证 1、OSPF邻居认证概述 链路是路由器接口的另一种说法&#xff0c;因此OSPF也称为接口状态路由协议。OSPF通过路由器之间通告网络接口的状态来建立链路状态数据库&#xff0c;生成最短路径树&#xff0c;每个OSPF路由器使用这些最短路径构造路由表。 OSPF认…