【IC验证面试常问-4】
IC验证面试常问-4
- 1.11 struct和union的异同
- 1.13 rose 和posedge 的区别?
- 1.14 semaphore的用处是什么?
- 1.15 类中的静态方法使用注意事项有哪些?
- 1.16 initial和final的区别? s t o p , stop, stop,finish的区别
- 1.17 logic,wire和reg的区别?
- 1.18 抽象类和抽象接口是什么?
- 1.19 always@ always_comb always_ff的区别
- 1.20 parameter、define和typedef之间的区别?
- 1.21 solve..before如何使用
- 1.22 mailbox和队列的异同;
- 1.23 动态automa 和静态 static的生命周期;
- 1.24 值传参和引用传参
- 1.25 class和struct的异同,class和module的异同;
- 1.26 对象创建的初始化顺序
- 1.27 new(),coypy()和clone()的区别?
【博客首发与微信公众号《漫谈芯片与编程》,欢迎专注一下】
本篇博客继续介绍IC验证基本功–SV常问问题;
1.11 struct和union的异同
相同点:
struct和union都是用于组合多个不同类型的数据成员,来定义复合数据类型;
声明方式都是使用关键字struct或union,后面跟一对花括号{}来定义数据成员;
不同点:
1.存储方式:
- struct: 结构体中的每个数据成员都有自己独立的存储空间,它们在内存中是连续存储的。结构体的大小是其所有成员大小的总和,加上可能的填充字节(为了对齐)。
- union: 联合体中的所有数据成员共享同一块内存空间,因此在同一时间只能存储一个数据成员的值。意味着在任一时刻,联合体只能存储其中一个成员的值。
2.访问方式
- sruct: 通过成员符.来访问结构体中的每个数据成员;
- union:由于联合体中的所有数据成员共享同一块内存空间,因此只能访问当前存储在联合体中的数据成员。
//在这个结构体中,data、address和enable都有自己的存储空间,可以同时存储不同的值。
struct {logic [7:0] data;logic [2:0] address;logic enable;
} my_struct;//在这个联合体中,data、address和enable共享同一块内存空间,同一时间只能存储一个数据成员的值。如果存储了data,那么address和enable的值就会被覆盖。
union {logic [7:0] data;logic [2:0] address;logic enable;
} my_union;
【总结】
struct用于组合多个不同类型的数据成员,每个成员都有自己的存储空间。
union用于在不同时间存储不同类型的数据成员,但所有成员共享同一块内存空间。
1.13 rose 和posedge 的区别?
在项目中,很少用到$rose这个用法,在这里简单了解下;
- $rose 是一个系统函数,用于检测信号是否从 0 变为 1(即上升沿), $rose(signal) 返回一个布尔值,如果 signal 在当前时间步从 0 变为 1,则返回 1(真),否则返回 0(假)。可以在组合逻辑、任务、函数等中使用。
- posedge:是一个事件控制关键字,用于检测信号的上升沿;posedge signal 通常用在 always 块或事件控制中,当 signal 从 0 变为 1 时触发相应的代码块,用于同步模块;
// 使用$posedge检测时钟上升沿
always @(posedge clk) begin// 在时钟上升沿执行的代码
end// 使用$rose检测信号的正向边沿变化
always @(posedge clk) beginif ($rose(enable)) begin// 在enable信号变为1时执行的代码end
end
1.14 semaphore的用处是什么?
semaphore 是一种同步机制,用于控制对共享资源的访问同步机制。它主要用于多线程或多进程环境中,以防止多个线程或进程同时访问同一个资源,从而避免竞态条件(race conditions)和数据不一致的问题。semaphore 本质上是一个整数计数器,初始值为一个正整数,表示可用资源的数量。
主要用途:
- 资源管理:信号量可以用来管理有限的资源,例如硬件资源或内存空间。通过限制同时访问资源的线程数量,可以防止资源被过度使用或耗尽。
- 线程同步:信号量可以用于同步不同线程或进程的执行,确保某些操作按预期顺序执行。例如,一个线程可以等待信号量的值变为非零,然后获取资源的访问权;而另一个线程可以在使用完资源后释放信号量,使其值增加。
- 互斥访问:信号量可以实现互斥访问,即同一时间只有一个线程可以访问共享资源。这可以通过将信号量的初始值设置为1,并在访问资源前获取信号量、访问结束后释放信号量来实现。
semaphore 的基本操作:
获取(get):线程尝试获取 semaphore 的一个令牌(token)。如果 semaphore 的计数大于 0,计数减 1,线程继续执行;如果计数为 0,线程将阻塞,直到其他线程释放令牌。
释放(put):线程释放 semaphore 的一个令牌,计数加 1,如果有等待的线程,唤醒其中一个线程
program test;import uvm_pkg::*;`include "uvm_macros.svh"class my_thread extends uvm_thread;`uvm_object_utils(my_thread)semaphore my_semaphore;function new(string name = "my_thread");super.new(name);my_semaphore = new(1); // 初始化信号量,允许一个线程访问资源endfunctiontask run();forever beginmy_semaphore.get(); // 获取信号量// 访问共享资源的代码$display("Thread %s is accessing the shared resource", this.get_name());#10ns; // 模拟资源使用时间my_semaphore.put(); // 释放信号量endendtaskendclassinitial beginmy_thread t1, t2;t1 = new("thread1");t2 = new("thread2");t1.start();t2.start();end
endprogram
1.15 类中的静态方法使用注意事项有哪些?
类的静态方法:静态方法是属于类本身而不是类的实例的方法;这意味着你可以在没有创建类的实例的情况下调用静态方法;静态方法通常用于执行与类相关的操作,而不需要访问类的实例数据。
- 访问权限:静态方法不能访问非静态成员,为这些成员需要类的实例才能存在。静态方法只能访问类的静态成员;
- 调用方式:无需实例化:静态方法可以通过类名直接调用,而不需要创建类的实例。例如,my_class::my_static_method();实例化后也可调用;
- 声明周期:静态方法在整个仿真周期都存在;
- 主要用途:常用于工具函数、工厂方法和单例模式;
class My_Class;// 静态变量static int count = 0;// 非静态变量int id;// 构造函数function new(int _id);id = _id;count++;endfunction// 静态方法static function int get_count();return count;endfunction// 非静态方法function void display();$display("ID: %0d, Count: %0d", id, get_count());endfunction
endclassmodule tb;initial begin// 通过类名调用静态方法$display("Initial count: %0d", My_Class::get_count());// 创建类的实例My_Class obj1 = new(1);My_Class obj2 = new(2);// 通过实例调用静态方法$display("Count through instance: %0d", obj1.get_count());// 通过类名调用静态方法$display("Final count: %0d", My_Class::get_count());// 调用非静态方法obj1.display();obj2.display();end
endmodule
1.16 initial和final的区别? s t o p , stop, stop,finish的区别
initial和final是两个不同的过程块,它们用于在仿真开始和结束时执行特定的代码。 s t o p 和 stop和 stop和finish是两个系统任务,用于在仿真过程中停止或结束仿真;
initial 块:
用途:initial 块用于定义仿真开始时执行的代码。每个 initial 块中的代码在仿真开始时并行执行。
执行时机:initial 块中的代码在仿真时间 0 时开始执行。
使用场景:通常用于初始化信号、启动仿真过程、生成激励信号等。
final 块:
用途:final 块用于定义仿真结束时执行的代码。每个 final 块中的代码在仿真结束时并行执行。
执行时机:final 块中的代码在仿真结束时执行,即在 $finish 被调用之后。
使用场景:通常用于清理资源、打印最终结果、执行最后的检查等。
module tb;initial begin$display("Simulation started at time %0t", $time);// 仿真开始时执行的代码#100; // 仿真延迟 100 个时间单位$finish; // 结束仿真endfinal begin$display("Simulation ended at time %0t", $time);// 仿真结束时执行的代码end
endmodule
$stop 和 $finish
$stop:
用途:暂停仿真,进入交互模式。
效果:调用 $stop 会使仿真暂停,用户可以查看当前状态并进行调试。仿真可以在调试器中继续执行。
使用场景:通常用于调试,当仿真达到某个特定状态时暂停,以便检查变量和信号的值。
$finish:
用途:终止仿真。
效果:调用 $finish 会立即终止仿真,退出仿真器。
使用场景:通常用于正常结束仿真,或者在检测到严重错误时提前终止仿真。
module tb;initial begin$display("Simulation started at time %0t", $time);// 仿真开始时执行的代码#50; // 仿真延迟 50 个时间单位$display("Stopping simulation at time %0t", $time);$stop; // 暂停仿真#50; // 仿真延迟 50 个时间单位$display("Finishing simulation at time %0t", $time);$finish; // 结束仿真endfinal begin$display("Simulation ended at time %0t", $time);// 仿真结束时执行的代码end
endmodule//以下方式可以用于调试
$stop(2); // 停止仿真,退出状态为2
$finish(0); // 结束仿真,退出状态为0
1.17 logic,wire和reg的区别?
logic、wire和reg是用于声明信号类型的关键字。
logic:
logic是SystemVerilog中引入的一种新的数据类型,它可以替代传统的reg和wire类型。
logic类型的信号可以用于组合逻辑和时序逻辑,可以被连续赋值(assign)、过程赋值(always)或在模块端口声明中使用。
logic类型的信号默认初始值为x(未知),这与reg类型不同,reg类型默认初始值为0。
wire:
wire类型用于表示组合逻辑信号,即信号的值是由其驱动源(如逻辑门、连续赋值语句)即时决定的。
wire类型的信号只能用于连续赋值语句,不能用于过程赋值语句(如always块)。
wire类型的信号默认初始值为z(高阻态)。
reg:
reg类型用于表示时序逻辑信号,即信号的值可以在时钟边沿触发时更新。但最后综合是不是寄存器还是线网要看具体always语句块;
reg类型的信号可以用于过程赋值语句,如always块,但不能用于连续赋值语句。
reg类型的信号默认初始值为0。
【总结】
logic类型可以用于组合逻辑和时序逻辑,默认初始值为x。
wire类型用于组合逻辑,默认初始值为z。
reg类型用于时序逻辑,默认初始值为0。
module example;logic clk;wire reset;reg [7:0] data;// 组合逻辑assign reset = ~clk;// 时序逻辑always @(posedge clk) begindata <= data + 1;end
endmodule
1.18 抽象类和抽象接口是什么?
OOP特性中的抽象:就是具体由抽象类和抽象接口机制来实现的;
抽象类(Abstract Class)和抽象接口(Abstract Interface)是用于定义一组方法的模板,但这些方法的具体实现留给继承或实现它们的子类或接口实现者。抽象类和抽象接口的主要目的是提供一种方式来强制实现特定的行为,同时允许具体的实现细节有所不同。
抽象类(Abstract Class):
抽象类是使用virtual关键字声明的类,其中至少包含一个纯虚方法(Pure Virtual Method)。
纯虚方法是没有实现的方法,它只有方法声明,没有方法体。纯虚方法使用virtual关键字和= 0来表示。
抽象类不能被实例化,它只能作为其他类的基类,用于继承和实现其纯虚方法。
子类必须实现抽象类中的所有纯虚方法,否则该子类也将成为一个抽象类。
用途:
定义模板:抽象类提供了一个模板,派生类可以继承并实现抽象方法。
强制实现:通过定义纯虚方法,抽象类可以强制派生类实现这些方法。
代码重用:抽象类可以包含通用的方法和属性,这些可以被派生类继承和使用。
// 抽象类示例
virtual class Animal;pure virtual function void makeSound();
endclassclass Dog extends Animal;function void makeSound();$display("Woof!");endfunction
endclassclass Cat extends Animal;function void makeSound();$display("Meow!");endfunction
endclass
抽象接口(Abstract Interface):
抽象接口是使用interface关键字声明的接口,其中可以包含方法声明、变量声明和其他接口声明。
抽象接口中的方法可以是纯虚方法,也可以是有默认实现的方法。
抽象接口不能被实例化,它只能作为其他类或接口的模板,用于继承和实现其方法。
实现抽象接口的类或接口必须实现其中的所有纯虚方法,否则该类或接口也将成为一个抽象类或接口。
用途:
定义协议:抽象接口定义了一组方法签名,实现该接口的类必须提供这些方法的具体实现。
解耦合:抽象接口可以解耦合类的定义和实现,使得类的设计更加灵活和模块化。
// 抽象接口
interface AnimalInterface;// 纯虚方法pure virtual function string make_sound();
endinterface// 实现类
class Dog implements AnimalInterface;// 实现纯虚方法virtual function string make_sound();return "Woof!";endfunction
endclass// 测试平台
module tb;initial beginDog d = new();$display("Dog says: %s", d.make_sound());end
endmodule
1.19 always@ always_comb always_ff的区别
always: 是最通用的过程块,可以用于描述组合逻辑、时序逻辑;
always_comb:always_comb是用于描述组合逻辑的过程块;不需要显式指定敏感列表,编译器会自动推断并生成敏感列表。
always_ff: always_ff是用于描述时序逻辑的过程块,特别是寄存器(flip-flop)。
精细化always_comb/ff 可以帮助工具更好地理解和优化设计中
// 使用 always 描述时序逻辑
always @(posedge clk or negedge reset_n) beginif (!reset_n) beginq <= 0;end else beginq <= d;end
end// 使用 always_ff 描述时序逻辑
always_ff @(posedge clk or negedge reset_n) beginif (!reset_n) beginq <= 0;end else beginq <= d;end
end// 使用 always 描述组合逻辑
always @(a, b, sel) beginif (sel) beginout = a;end else beginout = b;end
end// 使用 always_comb 描述组合逻辑
always_comb beginif (sel) beginout = a;end else beginout = b;end
end
1.20 parameter、define和typedef之间的区别?
parameter、define和typedef是用于定义常量、宏和类型别名的关键字。
parameter:parameter 用于定义常量,通常用于模块或接口中的参数化设计;在编译时确定,并且在整个仿真过程中保持不变。parameter 的作用域通常是模块或接口的本地作用域,localparam 限制为块级作用域。parameter 可以在实例化模块时被重新定义,以实现参数化设计。
module my_module #(parameter int WIDTH =4, parameter string NAME = "default") (input logic [WIDTH-1:0] in,output logic [WIDTH-1:0] out
);// 模块逻辑
endmodule
`define: 用于定义预处理宏的预处理指令,通常用于文本替换;作用域是全局的,在整个设计中使用;适用于全局定义常量或宏函数的情况;
`define WIDTH 8
module my_module (input logic [`WIDTH-1:0] data_in, output logic [`WIDTH-1:0] data_out);// 使用define定义的宏assign data_out = data_in;
endmodule
typedef: 用于定义类型别名的关键字,可以简化复杂的类型声明,或者用于定义新的数据类型;
typedef struct packed {logic [7:0] byte1;logic [7:0] byte2;
} my_struct;typedef enum {RED, GREEN, BLUE} color_t;module top;// 使用 typedef 定义的类型my_struct s;color_t c;initial begins.byte1 = 8'hAA;s.byte2 = 8'hBB;c = RED;$display("s.byte1 = %h, s.byte2 = %h, c = %s", s.byte1, s.byte2, c.name());end
endmodule
1.21 solve…before如何使用
solve…before语句是约束随机化中指定约束之间的优先级的关键字;通常用于解决在约束块中存在多个约束条件时,可能会出现的求解顺序问题。通过使用solve…before,你可以明确指定某些约束应该在其他约束之前求解,从而确保约束求解的正确性和一致性。
class MyClass;rand int a;rand int b;constraint c1 {a inside {[1:10]};b == a * 2;}// 解决依赖关系solve a before b;
endclassmodule tb;initial beginMyClass obj = new();// 随机化对象if (obj.randomize()) begin$display("a = %0d, b = %0d", obj.a, obj.b);end else begin$display("Randomization failed");endend
endmodule
1.22 mailbox和队列的异同;
mailbox主要是用于在不同线程或进程之间传递数据的容器;
queue主要用于单个进程内部的数据管理;
实现方式:
mailbox:是一种基于事件的通信机制,它使用一个共享的内存区域来存储数据。当一个线程向mailbox中放入数据时,它会通知等待在该mailbox上的线程,这些线程会被唤醒并尝试从mailbox中取出数据。
queue:是一种基于数组的数据结构,它可以动态地增长和收缩。queue中的数据是按照它们被插入的顺序存储的,并且可以在任何时候被访问和修改。
使用场景:
mailbox:通常用于需要异步通信的场景,例如在测试平台中,不同的线程可以通过mailbox来交换数据和控制信息。
queue:通常用于需要顺序处理数据的场景,例如在处理器设计中,指令队列可以使用queue来存储待执行的指令。
操作方式:
mailbox:提供了put、get和peek等操作,用于向mailbox中放入数据、从mailbox中取出数据以及查看mailbox中的下一个数据。
queue:提供了push_back、pop_front、front和back等操作,用于向queue的末尾插入数据、从queue的前端取出数据以及查看queue的前端和后端数据。
//mailbox
mailbox mbx;
initial beginmbx = new();forkbeginint data = 10;mbx.put(data); // 发送数据endbeginint data;mbx.get(data); // 接收数据$display("Received data: %0d", data);endjoin
end//queuequeue<int> q;
initial beginq.push_back(10); // 添加数据q.push_back(20);q.push_back(30);while (q.size() > 0) beginint data = q.pop_front(); // 移除并获取第一个数据$display("Popped data: %0d", data);end
end
1.23 动态automa 和静态 static的生命周期;
automatic 和 static 是用于控制变量生命周期的关键字。它们决定了变量在仿真过程中的存在时间和作用域。
默认声明是:automatic类型;声明周期在变量被创建时存在,在执行完毕后销毁;automatic 变量存储在栈内存中,不需要手动管理内存,因为它们在块执行完毕后自动销毁
static变量–需要显示声明:static变量生命周期从仿真开始到仿真结束。static变量存储在静态内存区域;
1.24 值传参和引用传参
值传参:
值传参是指将实际参数的值复制一份传递给函数或任务中的形式参数。
在函数或任务内部对形式参数的修改不会影响到实际参数的值。
值传参适用于需要保护实际参数不被修改的情况,或者需要传递不可变数据的情况。
引用传参:
引用传参是指将实际参数的内存地址传递给函数或任务中的形式参数。
在函数或任务内部对形式参数的修改会直接影响到实际参数的值。
引用传参适用于需要修改实际参数值的情况,或者需要传递可变数据的情况。
值传参:值传递确保了函数或任务内部的操作不会影响外部变量,有助于保持代码的独立性和安全性。
缺点:对于大型数据结构,值传递会导致额外的内存开销和复制时间。
module parameter_pass;// 值传参示例function void pass_by_value(int a, int b);int temp;temp = a;a = b;b = temp;$display("Inside pass_by_value: a = %0d, b = %0d", a, b);endfunction// 引用传参示例function void pass_by_reference(ref int a, ref int b);int temp;temp = a;a = b;b = temp;$display("Inside pass_by_reference: a = %0d, b = %0d", a, b);endfunctionint x, y;initial beginx = 10;y = 20;$display("Before calling functions: x = %0d, y = %0d", x, y);// 调用值传参函数pass_by_value(x, y);$display("After calling pass_by_value: x = %0d, y = %0d", x, y);// 调用引用传参函数pass_by_reference(x, y);$display("After calling pass_by_reference: x = %0d, y = %0d", x, y);end
endmodule
1.25 class和struct的异同,class和module的异同;
class和struct的异同:
默认访问控制:
struct中的成员默认是public的,这意味着它们可以在struct的外部被直接访问。
class中的成员默认是private的,这意味着它们不能在class的外部被直接访问,需要通过class提供的方法来访问。
继承:
class支持继承,允许一个class继承另一个class的成员和方法。
struct不支持继承,它只能包含数据成员,不能包含方法。
动态内存分配:
class支持动态内存分配,可以使用new操作符在运行时创建class的实例。
struct不支持动态内存分配,它通常在编译时被实例化。
封装性:
class提供了更好的封装性,因为它的成员默认是私有的,需要通过方法来访问。
struct的封装性较差,因为它的成员默认是公有的,可以被直接访问。
//================class
class MyClass;int data;function new(int val);data = val;endfunctionfunction void print_data();$display("Data: %0d", data);endfunction
endclassmodule tb;initial beginMyClass obj = new(10);obj.print_data(); // 输出: Data: 10end
endmodule//==============struct
typedef struct {int data;
} MyStruct;module tb;initial beginMyStruct s;s.data = 10;$display("Data: %0d", s.data); // 输出: Data: 10end
endmodule
class 和 module 的异同:
class:主要用于面向对象编程,封装数据和行为,支持继承、多态和随机化。
module:主要用于描述硬件逻辑,包括组合逻辑和时序逻辑,是 SystemVerilog 中的基本构建块。
//=========================class
class MyClass;int data;function new(int val);data = val;endfunctionfunction void print_data();$display("Data: %0d", data);endfunction
endclassmodule tb;initial beginMyClass obj = new(10);obj.print_data(); // 输出: Data: 10end
endmodule//=========================module
module MyModule (input logic clk,input logic rst_n,input logic [7:0] in,output logic [7:0] out
);always_ff @(posedge clk or negedge rst_n) beginif (!rst_n) beginout <= 8'd0;end else beginout <= in;endend
endmodulemodule tb;logic clk;logic rst_n;logic [7:0] in;logic [7:0] out;MyModule uut (.clk(clk),.rst_n(rst_n),.in(in),.out(out));initial beginclk = 0;rst_n = 0;in = 8'd10;#10 rst_n = 1;#10 $display("Output: %0d", out); // 输出: Output: 10endalways #5 clk = ~clk;
endmodule
class 和 struct:
class 用于面向对象编程,支持成员函数、构造函数、继承和随机化。
struct 用于简单数据封装,不支持成员函数和继承。
class 和 module:
class 用于面向对象编程,支持随机化和继承,主要用于描述算法和行为。
module 用于描述硬件逻辑,支持时序逻辑和组合逻辑,是 SystemVerilog 中的基本构建块。
1.26 对象创建的初始化顺序
对象的创建和初始化顺序是非常重要的,尤其是在类中包含多个成员变量和构造函数;
初始化顺序
变量声明:在对象创建之前,所有的变量声明都会被处理。这包括类成员变量、局部变量等。
构造函数调用:在变量声明之后,构造函数会被调用。构造函数用于初始化对象的成员变量。
父类构造函数调用:如果当前类继承自其他类,那么在调用当前类的构造函数之前,会先调用父类的构造函数。这是通过super关键字来实现的。
成员变量初始化:在构造函数内部,可以对成员变量进行初始化。这些初始化语句会按照它们在类定义中的出现顺序执行。
构造函数体执行:在完成所有成员变量的初始化之后,构造函数的体(即花括号内的代码)会被执行。
class Parent;int x;function new();x = 10;$display("Parent constructor: x = %0d", x);endfunction
endclassclass Child extends Parent;int y;function new();super.new(); // 调用父类的构造函数y = 20;$display("Child constructor: y = %0d", y);endfunction
endclassmodule test;initial beginChild c = new();$display("After object creation: x = %0d, y = %0d", c.x, c.y);end
endmodule
在这个示例中,当创建Child类的对象c时,初始化顺序如下:
- 声明Child类的成员变量y。
- 调用Parent类的构造函数,初始化x为10。
- 初始化Child类的成员变量y为20。
- 执行Child类构造函数的体。
这个示例展示了SystemVerilog中对象创建的初始化顺序,包括变量声明、构造函数调用、父类构造函数调用、成员变量初始化和构造函数体执行。
1.27 new(),coypy()和clone()的区别?
new():用于创建一个新的对象实例。它会分配内存,并初始化对象的成员变量。
copy():用于创建一个浅拷贝。它不会分配新的内存,而是复制现有对象的状态。
clone():用于创建一个深拷贝。用于创建一个新的对象实例,并将现有对象的成员变量值复制到新对象中。
class MyClass;int x;int y;function new();x = 10;y = 20;endfunctionfunction MyClass copy(MyClass original);MyClass new_obj = new();new_obj.x = original.x;new_obj.y = original.y;return new_obj;endfunctionfunction MyClass clone();MyClass new_obj = new();new_obj.x = x;new_obj.y = y;return new_obj;endfunction
endclassmodule test;initial beginMyClass obj1 = new();MyClass obj2;obj2 = obj1.copy(); // 使用copy方法复制对象$display("obj2.x = %0d, obj2.y = %0d", obj2.x, obj2.y);obj2 = obj1.clone(); // 使用clone方法复制对象$display("obj2.x = %0d, obj2.y = %0d", obj2.x, obj2.y);end
endmodule
至此,SV的基本功常见问题就先到此结束了,接下来介绍IC验证的基本功–UVM常见问题。
相关文章:
【IC验证面试常问-4】
IC验证面试常问-4 1.11 struct和union的异同1.13 rose 和posedge 的区别?1.14 semaphore的用处是什么?1.15 类中的静态方法使用注意事项有哪些?1.16 initial和final的区别? s t o p , stop, stop,finish的区别1.17 logic,wire和re…...
【数据集】【YOLO】【目标检测】交通事故识别数据集 8939 张,YOLO道路事故目标检测实战训练教程!
数据集介绍 【数据集】道路事故识别数据集 8939 张,目标检测,包含YOLO/VOC格式标注。数据集中包含2种分类:{0: accident, 1: non-accident}。数据集来自国内外图片网站和视频截图。检测范围道路事故检测、监控视角检测、无人机视角检测、等&…...
书生浦语第四期基础岛L1G4000-InternLM + LlamaIndex RAG 实践
文章目录 一、任务要求11.首先创建虚拟环境2. 安装依赖3. 下载 Sentence Transformer 模型4.下载 NLTK 相关资源5. 是否使用 LlamaIndex 前后对比6. LlamaIndex web7. LlamaIndex本地部署InternLM实践 一、任务要求1 任务要求1(必做,参考readme_api.md&…...
基于ViT的无监督工业异常检测模型汇总
基于ViT的无监督工业异常检测模型汇总 论文1:VT-ADL: A Vision Transformer Network for Image Anomaly Detection and Localization(2021)1.1 主要思想1.2 系统框架 论文2:Inpainting Transformer for Anomaly Detection…...
数据库管理-第258期 23ai:Oracle Data Redaction(20241104)
数据库管理258期 2024-11-04 数据库管理-第258期 23ai:Oracle Data Redaction(20241104)1 简介2 应用场景与有点3 多租户环境4 特性与能力4.1 全数据编校4.2 部分编校4.3 正则表达式编校4.4 随机编校4.5 空值编校4.6 无编校4.7 不同数据类型上…...
运放进阶篇-多种波形可调信号发生器-产生方波-三角波-正弦波
引言:前几节我们已经说到硬件相关基础的电路,以及对于运放也讲到了初步的理解,特别是比较器的部分,但是放大器的部分我们对此并没有阐述,在这里通过实例进行理论结合实践的学习。而运放真正的核心,其实就是…...
CSS中的变量应用——:root,Sass变量,JavaScript中使用Sass变量
:root—— 原生CSS 自定义属性(变量) 在 SCSS 文件中定义 CSS 自定义属性。然后通过 JavaScript 读取这些属性。 // variables.scss :root { --login-bg-color: #293146;--left-menu-max-width: 200px;--left-menu-min-width: 64px;--left-menu-bg-…...
WPF+MVVM案例实战与特效(二十八)- 自定义WPF ComboBox样式:打造个性化下拉菜单
文章目录 1. 引言案例效果3. ComboBox 基础4. 自定义 ComboBox 样式4.1 定义 ComboBox 样式4.2 定义 ComboBoxItem 样式4.3 定义 ToggleButton 样式4.4 定义 Popup 样式5. 示例代码6. 结论1. 引言 在WPF应用程序中,ComboBox控件是一个常用的输入控件,用于从多个选项中选择一…...
速盾:怎么使用cdn加速?
CDN(Content Delivery Network)即内容分发网络,是一种通过在网络各处部署节点来缓存和传输网络内容的技术。通过使用CDN加速,可以提高网站的访问速度、减轻服务器负载、提供更好的用户体验。 使用CDN加速的步骤如下: …...
C++ 优先算法 —— 三数之和(双指针)
目录 题目:三数之和 1. 题目解析 2. 算法原理 ①. 暴力枚举 ②. 双指针算法 不漏的处理: 去重处理: 固定一个数 a 的优化: 3. 代码实现 Ⅰ. 暴力枚举(会超时 O(N)) Ⅱ.…...
YOLOv7-0.1部分代码阅读笔记-yolo.py
yolo.py models\yolo.py 目录 yolo.py 1.所需的库和模块 2.class Detect(nn.Module): 3.class IDetect(nn.Module): 4.class IAuxDetect(nn.Module): 5.class IBin(nn.Module): 6.class Model(nn.Module): 7.def parse_model(d, ch): 8.if __name__ __main__…...
【缓存与加速技术实践】Web缓存代理与CDN内容分发网络
文章目录 Web缓存代理Nginx配置缓存代理详细说明 CDN内容分发网络CDN的作用CDN的工作原理CDN内容的获取方式解决缓存集中过期的问题 Web缓存代理 作用: 缓存之前访问过的静态网页资源,以便在再次访问时能够直接从缓存代理服务器获取,减少源…...
MySQL的约束和三大范式
一.约束 什么是约束,为什么要用到约束? 约束就是用于创建表时,给对应的字段添加对应的约束 约束的作用就是当我们用insert into时,如果传入的数据有问题,不符合创建表时我们定的规定,这时MySQL就会自动帮…...
Unity网络通信(part7.分包和黏包)
目录 前言 概念 解决方案 具体代码 总结 分包黏包概念 分包 黏包 解决方案概述 前言 在探讨Unity网络通信的深入内容时,分包和黏包问题无疑是其中的关键环节。以下是对Unity网络通信中分包和黏包问题前言部分的详细解读。 概念 在网络通信中,…...
练习题 - DRF 3.x Overviewses 框架概述
Django REST Framework (DRF) 是一个强大的工具,用于构建 Web APIs。作为 Django 框架的扩展,DRF 提供了丰富的功能和简洁的 API,使得开发 RESTful Web 服务变得更加轻松。对于想要在 Django 环境中实现快速且灵活的 API 开发的开发者来说,DRF 是一个非常有吸引力的选择。学…...
Linux 经典面试八股文
快速鉴别十个题 1,你如何描述Linux文件系统的结构? 答案应包括对/, /etc, /var, /home, /bin, /lib, /usr, 和 /tmp等常见目录的功能和用途的描述。 2,在Linux中如何查看和终止正在运行的进程? 期望的答案应涵盖ps, top, htop, …...
Filter和Listener
一、Filter过滤器 1 概念 可以实现拦截功能,对于指定资源的限定进行拦截,替换,同时还可以提高程序的性能。在Web开发时,不同的Web资源中的过滤操作可以放在同一个Filter中完成,这样可以不用多次编写重复代码…...
Go 项目中实现类似 Java Shiro 的权限控制中间件?
序言: 要在 Go 项目中实现类似 Java Shiro 的权限控制中间件,我们可以分为几个步骤来实现用户的菜单访问权限和操作权限控制。以下是一个基本的实现框架步骤: 目录 一、数据库设计 二、中间件实现 三、使用中间件 四、用户权限管理 五…...
【Javascript】-一些原生的网页设计案例
JavaScript 网页设计案例 1. 动态时钟 功能描述:在网页上显示一个动态更新的时钟,包括小时、分钟和秒。实现思路: 使用 setInterval 函数每秒更新时间。获取当前时间并更新页面上的文本。 代码示例:<div id"clock"…...
SpringBoot开发——Spring Boot 3种定时任务方式
文章目录 一、什么是定时任务二、代码示例1、 @Scheduled 定时任务2、多线程定时任务3、基于接口(SchedulingConfigurer)实现动态更改定时任务3.1 数据库中存储cron信息3.2 pom.xml文件中增加mysql依赖3.3 application.yaml文件中增加mysql数据库配置:3.4 创建定时器3.5 启动…...
椭圆曲线密码学(ECC)
一、ECC算法概述 椭圆曲线密码学(Elliptic Curve Cryptography)是基于椭圆曲线数学理论的公钥密码系统,由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA,ECC在相同安全强度下密钥更短(256位ECC ≈ 3072位RSA…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...
Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...
selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...
Webpack性能优化:构建速度与体积优化策略
一、构建速度优化 1、升级Webpack和Node.js 优化效果:Webpack 4比Webpack 3构建时间降低60%-98%。原因: V8引擎优化(for of替代forEach、Map/Set替代Object)。默认使用更快的md4哈希算法。AST直接从Loa…...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...
Rust 开发环境搭建
环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行: rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu 2、Hello World fn main() { println…...
