NJU数电实验-1

news2024/9/23 23:32:29

实验一 选择器

2选1多路选择器

在这里插入图片描述
逻辑表达式: y = ( ∼ s & a ) ∣ ( s & b ) y=(\sim s\&a)|(s\&b) y=(s&a)(s&b)

逻辑电路:

在这里插入图片描述

数据流建模

数据流建模主要是通过连续赋值语句 assign 来描述电路的功能

module m_mux21(a,b,s,y);
  input   a,b,s;        // 声明3个wire型输入变量a,b,和s,其宽度为1位。
  output  y;           // 声明1个wire型输出变量y,其宽度为1位。

  assign  y = (~s&a)|(s&b);  // 实现电路的逻辑功能。

endmodule

仿真代码:

#include "verilated.h"
#include "verilated_vcd_c.h"
#include "obj_dir/Vmux21.h"

VerilatedContext* contextp = NULL;
VerilatedVcdC* tfp = NULL;

static Vmux21* top;

void step_and_dump_wave(){
  top->eval();
  contextp->timeInc(1);
  tfp->dump(contextp->time());
}
void sim_init(){
  contextp = new VerilatedContext;
  tfp = new VerilatedVcdC;
  top = new Vmux21;
  contextp->traceEverOn(true);
  top->trace(tfp, 0);
  tfp->open("dump.vcd");
}

void sim_exit(){
  step_and_dump_wave();
  tfp->close();
}

int main() {
  sim_init();

  top->s=0; top->a=0; top->b=0;  step_and_dump_wave();   // 将s,a和b均初始化为“0”
                      top->b=1;  step_and_dump_wave();   // 将b改为“1”,s和a的值不变,继续保持“0”,
            top->a=1; top->b=0;  step_and_dump_wave();   // 将a,b分别改为“1”和“0”,s的值不变,
                      top->b=1;  step_and_dump_wave();   // 将b改为“1”,s和a的值不变,维持10个时间单位
  top->s=1; top->a=0; top->b=0;  step_and_dump_wave();   // 将s,a,b分别变为“1,0,0”,维持10个时间单位
                      top->b=1;  step_and_dump_wave();
            top->a=1; top->b=0;  step_and_dump_wave();
                      top->b=1;  step_and_dump_wave();

  sim_exit();
}

编译:

verilator -Wall --cc --exe --build main.cpp mux21.v --trace

波形:
在这里插入图片描述

结构化建模

结构化建模主要通过逐层实例化子模块的方式来描述电路的功能

module my_and(a,b,c);
  input  a,b;
  output c;

  assign c = a & b;
endmodule

module my_or(a,b,c);
  input  a,b;
  output c;

  assign c = a | b;
endmodule

module my_not(a,b);
  input  a;
  output b;

  assign b = ~a;
endmodule

module mux21b(a,b,s,y);
  input  a,b,s;
  output y;

  wire l, r, s_n; // 内部网线声明
  my_not i1(.a(s), .b(s_n));        // 实例化非门,实现~s
  my_and i2(.a(s_n), .b(a), .c(l)); // 实例化与门,实现(~s&a)
  my_and i3(.a(s),   .b(b), .c(r)); // 实例化与门,实现(s&b)
  my_or  i4(.a(l),   .b(r), .c(y)); // 实例化或门,实现(~s&a)|(s&b)
endmodule

行为建模

行为建模是通过类似面向过程的编程语言来描述电路的行为。例如,在Verilog中也可以用if语句来实现2选1多路选择器的行为

module mux21c(a,b,s,y);
  input   a,b,s;
  output reg  y;   // y在always块中被赋值,一定要声明为reg型的变量

  always @ (*)
    if(s==0)
      y = a;
    else
      y = b;
endmodule

//或者使用条件表达式
module mux21d(a,b,s,y);
  input   a,b,s;
  output  y;   // y不用声明为reg型的了。
  assign  y = s ? b : a;
endmodule

真正的描述电路 = 实例化 + 连线,所以请尽量不要使用“行为级建模”

4选1多路选择器

在这里插入图片描述

module mux41(a,s,y);
  input  [3:0] a;  // 声明一个wire型输入变量a,其变量宽度是4位的。
  input  [1:0] s;  // 声明一个wire型输入变量s,其变量宽度是2位的。
  output reg y;   // 声明一个1位reg型的输出变量y。

  always @ (s or a)
    case (s)
      0: y = a[0];
      1: y = a[1];
      2: y = a[2];
      3: y = a[3];
      default: y = 1'b0;
    endcase

endmodule

测试代码:

#include "verilated.h"
#include "verilated_vcd_c.h"
#include "obj_dir/Vmux41.h"

VerilatedContext* contextp = NULL;
VerilatedVcdC* tfp = NULL;

static Vmux41* top;

void step_and_dump_wave(){
  top->eval();
  contextp->timeInc(1);
  tfp->dump(contextp->time());
}
void sim_init(){
  contextp = new VerilatedContext;
  tfp = new VerilatedVcdC;
  top = new Vmux41;
  contextp->traceEverOn(true);
  top->trace(tfp, 0);
  tfp->open("dump.vcd");
}

void sim_exit(){
  step_and_dump_wave();
  tfp->close();
}

int main() {
  sim_init();
  top->s=0b00;  top->a=0b1110;  step_and_dump_wave();
                top->a=0b0001;  step_and_dump_wave();
  top->s=0b01;  top->a=0b1110;  step_and_dump_wave();
                top->a=0b0010;  step_and_dump_wave();
  top->s=0b10;  top->a=0b1010;  step_and_dump_wave();
                top->a=0b0100;  step_and_dump_wave();
  top->s=0b11;  top->a=0b0111;  step_and_dump_wave();
                top->a=0b1001;  step_and_dump_wave();
  sim_exit();
}

编译:

verilator -Wall --cc --exe --build main.cpp mux41.v --trace

波形:
在这里插入图片描述

一个通用的选择器模板

module MuxKeyInternal #(NR_KEY = 2, KEY_LEN = 1, DATA_LEN = 1, HAS_DEFAULT = 0) (
  output reg [DATA_LEN-1:0] out,
  input [KEY_LEN-1:0] key,
  input [DATA_LEN-1:0] default_out,
  input [NR_KEY*(KEY_LEN + DATA_LEN)-1:0] lut
);

  localparam PAIR_LEN = KEY_LEN + DATA_LEN;
  wire [PAIR_LEN-1:0] pair_list [NR_KEY-1:0];
  wire [KEY_LEN-1:0] key_list [NR_KEY-1:0];
  wire [DATA_LEN-1:0] data_list [NR_KEY-1:0];

  generate
    for (genvar n = 0; n < NR_KEY; n = n + 1) begin
      assign pair_list[n] = lut[PAIR_LEN*(n+1)-1 : PAIR_LEN*n];
      assign data_list[n] = pair_list[n][DATA_LEN-1:0];
      assign key_list[n]  = pair_list[n][PAIR_LEN-1:DATA_LEN];
    end
  endgenerate

  reg [DATA_LEN-1 : 0] lut_out;
  reg hit;
  integer i;
  always @(*) begin
    lut_out = 0;
    hit = 0;
    for (i = 0; i < NR_KEY; i = i + 1) begin
      lut_out = lut_out | ({DATA_LEN{key == key_list[i]}} & data_list[i]);
      hit = hit | (key == key_list[i]);
    end
    if (!HAS_DEFAULT) out = lut_out;
    else out = (hit ? lut_out : default_out);
  end

endmodule

module MuxKey #(NR_KEY = 2, KEY_LEN = 1, DATA_LEN = 1) (
  output [DATA_LEN-1:0] out,
  input [KEY_LEN-1:0] key,
  input [NR_KEY*(KEY_LEN + DATA_LEN)-1:0] lut
);
  MuxKeyInternal #(NR_KEY, KEY_LEN, DATA_LEN, 0) i0 (out, key, {DATA_LEN{1'b0}}, lut);
endmodule

module MuxKeyWithDefault #(NR_KEY = 2, KEY_LEN = 1, DATA_LEN = 1) (
  output [DATA_LEN-1:0] out,
  input [KEY_LEN-1:0] key,
  input [DATA_LEN-1:0] default_out,
  input [NR_KEY*(KEY_LEN + DATA_LEN)-1:0] lut
);
  MuxKeyInternal #(NR_KEY, KEY_LEN, DATA_LEN, 1) i0 (out, key, default_out, lut);
endmodule

使用选择器模板实现的选择器:

module mux21e(a,b,s,y);
  input   a,b,s;
  output  y;
  MuxKey #(2, 1, 1) i0 (y, s, {
    1'b0, a,
    1'b1, b
  });
endmodule

module mux41b(a,s,y);
  input  [3:0] a;
  input  [1:0] s;
  output y;
  MuxKeyWithDefault #(4, 2, 1) i0 (y, s, 1'b0, {
    2'b00, a[0],
    2'b01, a[1],
    2'b10, a[2],
    2'b11, a[3]
  });
endmodule

实验验收内容

在这里插入图片描述

module mux41(x0, x1, x2, x3, y, f);
  input  [1:0] x0; 
  input  [1:0] x1; 
  input  [1:0] x2; 
  input  [1:0] x3; 
  input  [1:0] y;  // 声明一个wire型输入变量s,其变量宽度是2位的。
  output reg [1:0] f;   // 声明一个2位reg型的输出变量y。

  MuxKeyWithDefault #(4, 2, 2) i0 (f, y, 2'b00, {
    2'b00, x0,
    2'b01, x1,
    2'b10, x2,
    2'b11, x3
  });

endmodule

先输出波形尝试一下:

#include "verilated.h"
#include "verilated_vcd_c.h"
#include "obj_dir/Vmux41.h"

VerilatedContext* contextp = NULL;
VerilatedVcdC* tfp = NULL;

static Vmux41* top;

void step_and_dump_wave(){
  top->eval();
  contextp->timeInc(1);
  tfp->dump(contextp->time());
}
void sim_init(){
  contextp = new VerilatedContext;
  tfp = new VerilatedVcdC;
  top = new Vmux41;
  contextp->traceEverOn(true);
  top->trace(tfp, 0);
  tfp->open("dump.vcd");
}

void sim_exit(){
  step_and_dump_wave();
  tfp->close();
}

int main() {
  sim_init();
  top->y=0b00;  top->x0=0b11; top->x1=0b01; top->x2=0b00;  top->x3=0b10; step_and_dump_wave();
                top->x0=0b10; top->x1=0b01; top->x2=0b01;  top->x3=0b00; step_and_dump_wave();
  top->y=0b01;  top->x0=0b11; top->x1=0b01; top->x2=0b00;  top->x3=0b10; step_and_dump_wave();
                top->x0=0b10; top->x1=0b01; top->x2=0b01;  top->x3=0b00; step_and_dump_wave();
  top->y=0b10;  top->x0=0b11; top->x1=0b01; top->x2=0b00;  top->x3=0b10; step_and_dump_wave();
                top->x0=0b10; top->x1=0b01; top->x2=0b01;  top->x3=0b00; step_and_dump_wave();
  top->y=0b11;  top->x0=0b11; top->x1=0b01; top->x2=0b00;  top->x3=0b10; step_and_dump_wave();
                top->x0=0b10; top->x1=0b01; top->x2=0b01;  top->x3=0b00; step_and_dump_wave();
  sim_exit();
}

编译:

verilator -Wall --cc --exe --build main.cpp *.v --trace --top-module mux41

波形:

在这里插入图片描述
接入NVBoard:

目录结构:

$ tree -I build/
.
├── constr
│   └── top.nxdc
├── csrc
│   └── main.cpp
├── Makefile
└── vsrc
    ├── mux41.v
    ├── MuxKeyInternal.v
    ├── MuxKey.v
    └── MuxKeyWithDefault.v

3 directories, 7 files

测试文件:

#include "Vmux41.h"
#include "verilated.h"
#include <nvboard.h>

static TOP_NAME dut;

void nvboard_bind_all_pins(Vmux41* top);

static void single_cycle() {
	dut.eval();
}

int main(int argc, char** argv) {
  nvboard_bind_all_pins(&dut);
  nvboard_init();

  while (1) {
	  nvboard_update();
	  single_cycle();
  }
   return 0;
}

引脚约束:

top=mux41

f (LD1, LD0)
y (SW1, SW0)

x0 (SW3, SW2)
x1 (SW5, SW4)
x2 (SW7, SW6)
x3 (SW9, SW8)

makefile将之前的第一行改为TOPNAME = mux41即可

实验二 译码器和编码器

译码器

在这里插入图片描述

2-4译码器

在这里插入图片描述

module decode24(x,en,y);
  input  [1:0] x;
  input  en;
  output reg [3:0]y;

  always @(x or en)
    if (en)
    begin
      case (x)
            2'd0 : y = 4'b0001;
            2'd1 : y = 4'b0010;
            2'd2 : y = 4'b0100;
            2'd3 : y = 4'b1000;
      endcase
    end
    else  y = 4'b0000;

endmodule

测试代码:

int main() {
  sim_init();

  top->en = 0b0;  top->x = 0b00;  step_and_dump_wave();
                  top->x = 0b01;  step_and_dump_wave();
                  top->x = 0b10;  step_and_dump_wave();
                  top->x = 0b11;  step_and_dump_wave();
  top->en = 0b1;  top->x = 0b00;  step_and_dump_wave();
                  top->x = 0b01;  step_and_dump_wave();
                  top->x = 0b10;  step_and_dump_wave();
                  top->x = 0b11;  step_and_dump_wave();
  sim_exit();
}

使用for循环实现3-8译码器:

module decode38(x,en,y);
  input  [2:0] x;
  input  en;
  output reg [7:0]y;
  integer i;

  always @(x or en)
    if (en) begin
      for( i = 0; i <= 7; i = i+1)
          if(x == i)
                y[i] = 1;
          else
                y[i] = 0;
    end
    else
      y = 8'b00000000;

endmodule

编码器

在这里插入图片描述

4-2编码器

module encode42(x,en,y);
  input  [3:0] x;
  input  en;
  output reg [1:0]y;

  always @(x or en) begin
    if (en) begin
      case (x)
          4'b0001 : y = 2'b00;
          4'b0010 : y = 2'b01;
          4'b0100 : y = 2'b10;
          4'b1000 : y = 2'b11;
          default: y = 2'b00;
      endcase
    end
    else  y = 2'b00;
  end
endmodule

测试代码:

int main() {
  sim_init();

  top->en=0b0; top->x =0b0000; step_and_dump_wave();
               top->x =0b0001; step_and_dump_wave();
               top->x =0b0010; step_and_dump_wave();
               top->x =0b0100; step_and_dump_wave();
               top->x =0b1000; step_and_dump_wave();
  top->en=0b1; top->x =0b0000; step_and_dump_wave();
               top->x =0b0001; step_and_dump_wave();
               top->x =0b0010; step_and_dump_wave();
               top->x =0b0100; step_and_dump_wave();
               top->x =0b1000; step_and_dump_wave();
  sim_exit();
}

优先编码器

优先编码器允许同时在几个输入端有输入信号,即输入不止一个 1 ,编码器按输入信号排定的优先顺序,只对同时输入的几个信号中优先权最高的一个进行编码

我们可以利用for循环语句可以很方便地实现优先编码器,一个4-2优先编码器的示例如下所示

module encode42(x,en,y);
  input  [3:0] x;
  input  en;
  output reg [1:0]y;
  integer i;
  always @(x or en) begin
    if (en) begin
      y = 0;
      for( i = 0; i <= 3; i = i+1)
          if(x[i] == 1)  y = i[1:0];
    end
    else  y = 0;
  end
endmodule

七段数码管

在这里插入图片描述

模块实例化

七段数码管就是一个典型的可复用模块

module bcd7seg(
  input  [3:0] b,
  output reg [6:0] h
);
// detailed implementation ...

endmodule

实验验收内容

在这里插入图片描述
目录结构:

$ tree -I build/
.
├── constr
│   └── top.nxdc
├── csrc
│   └── main.cpp
├── Makefile
└── vsrc
    ├── bcd7seg.v
    ├── encode83.v
    └── top.v

3 directories, 6 files
/**bcd7seg.v**/
module bcd7seg(
  input  [3:0] b,
  output reg [6:0] h
);
// detailed implementation ...

always@(b) begin
	case(b)
	4'd0: h<=7'b000_0001;
	4'd1: h<=7'b100_1111;
	4'd2: h<=7'b001_0010;
	4'd3: h<=7'b000_0110;
	4'd4: h<=7'b100_1100;
	4'd5: h<=7'b010_0100;
	4'd6: h<=7'b010_0000;
	4'd7: h<=7'b000_1111;
	4'd8: h<=7'b000_0000;
	4'd9: h<=7'b000_0100;
	default: h<=7'b000_0001;
	endcase
end

endmodule


/**encod38.v**/
module encode38(x,en,y, indicate);
  input  [7:0] x;
  input  en;
  output reg [2:0]y;
  output reg indicate;

  integer i;
  always @(x or en) begin
    if (en) begin
      y = 0;
      if (x != 0) indicate <= 1'b1;
      else indicate <= 1'b0;
      for( i = 0; i <= 7; i = i+1)
          if(x[i] == 1)  y = i[2:0];
    end
    else  y = 0;
  end
endmodule


/**top.v**/
module top(
    input [7:0]sw,
    input en,
    output reg [2:0] led_out,
    output reg indicate,
    output reg [6:0] seg_out
);

wire [2:0]w;

assign led_out = w;

encode38 encdr(
    .x(sw),
    .en(en),
    .y(w),
    .indicate(indicate)
);

bcd7seg seg0(
    .b({1'b0,w}),
    .h(seg_out)
);
endmodule

测试文件:

#include "Vtop.h"
#include "verilated.h"
#include <nvboard.h>

static TOP_NAME dut;

void nvboard_bind_all_pins(Vtop* top);

static void single_cycle() {
	dut.eval();
}

int main(int argc, char** argv) {
  nvboard_bind_all_pins(&dut);
  nvboard_init();

  while (1) {
	  nvboard_update();
	  single_cycle();
  }
   return 0;
}

引脚约定:

top=top

sw (SW7, SW6, SW5, SW4, SW3, SW2, SW1, SW0)
en (SW9)
led_out (LD2, LD1, LD0)
indicate (LD4)
seg_out (SEG0A, SEG0B, SEG0C, SEG0D, SEG0E, SEG0F, SEG0G)

makefile复用之前的即可

实验三 加法器与ALU

加法器

在这里插入图片描述

八位加法器实现

上述四位串行加法器的设计,如果推广到更多位加法器的设计,程序代码将会变得异常复杂,运行效率也将很低。在Verilog语言中,可以使用算术赋值语句和向量来执行这种算术运算。如果我们定义如下向量:

input  [n-1:0]  in_x, in_y;
output [n-1:0]  out_s;

则算术赋值语句

out_s = in_x + in_y;

就可以实现n位加法器了。

请注意,该代码定义了可以生成n位加法器的电路,但是该加法器电路并不包含加法过程中产生的进位输出信号和算术溢出信号。

溢出信号是用于判断运算结果 out_s 是否正确的信号。可以证明,对于有符号的补码运算的算术溢出信号可以用下面的表达式得到:

O v e r f l o w = ( i n _ x n − 1 = = i n _ y n − 1 ) & & ( o u t _ s n − 1 ! = i n _ x n − 1 ) Overflow=(in\_x_{n-1} == in\_y_{n-1})\&\&(out\_s_{n-1} != in\_x_{n-1}) Overflow=(in_xn1==in_yn1)&&(out_sn1!=in_xn1)

其判断原理是:如果两个参加加法运算的变量符号相同,而运算结果的符号与其不相同,则运算结果不准确,产生溢出

对于进位信号可以用下面的表达式得到:

{out_c,out_s} =in_x + in_y;

此表达式执行后, out_c 即为进位位, out_s 即为加法运算结果,这里的进位位仅用于表示在加法运算过程中,操作数的最高位是否对外有进位,和X86体系中借位CF的概念在减法操作中是相反的,即X86中的 C F = o u t c ⊕ c i n CF=out_c\oplus cin CF=outccin ,其中 cin 在减法时置1。在有符号的加减法中,溢出判断依据为溢出位,进位位不用。而在无符号数的加减法中,溢出判断依据进位位,溢出位不用

简单加减法运算器的设计

在这里插入图片描述

两个32位的参与运算的数据的补码操作数A和操作数B,一个控制做加法还是做减法的加/减控制端Sub/Add,为1时进行减法运算。输出信号有:一个32位的结果Result、一位进位位,一位溢出位和一位判断结果是否为零的输出位。

在图中已经加入了对减数进行求补操作,将减法变成加法的过程。即:如A – B,可以先求出(– B)的值,然后再和A相加,即A – B = A +(–B)。对于补码而言,– B的补码就是将B连同符号位在内全部取反再加一的过程。

ALU设计

实验验收内容

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

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

相关文章

这是一篇很好的互动式文章,Framer Motion 布局动画

重现framer的神奇布局动画的指南。 到目前为止&#xff0c;我最喜欢 Framer Motion 的部分是它神奇的布局动画–将 layout prop 拍在任何运动组件上&#xff0c;看着该组件从页面的一个部分无缝过渡到下一个部分。 <motion.div layout /> 在这篇文章中&#xff0c;我们…

【测试岗】那个准点下班的人,比我先升职了...

前言 陈双喜最近心态很崩。和他同期一道进公司的陈琪又升了一级&#xff0c;可是明明大家在进公司时&#xff0c;陈琪不论是学历还是工作经验&#xff0c;样样都不如自己&#xff0c;眼下不过短短的两年时间便一跃在自己的职级之上&#xff0c;这着实让他有几分不甘心。 程双…

linux常用命令介绍 03 篇——常用的文本处理工具之grep和cut(以及部分正则使用)

linux常用命令介绍 03 篇——常用的文本处理工具之grep和cut&#xff08;以及部分正则使用&#xff09;1 常用命令01篇 和 02篇1.1 Linux命令01篇——Linux解压缩文件常用命令1.2 Linux命令02篇——linux日常常用命令介绍2. 正则表达式2.1 基本定义2.2 正则中常用的元字符3. gr…

【python】异常详解

注&#xff1a;最后有面试挑战&#xff0c;看看自己掌握了吗 文章目录错误分类捕捉异常实例finally的使用捕捉特定异常抛出异常用户自定义异常&#x1f338;I could be bounded in a nutshell and count myself a king of infinite space. 特别鸣谢&#xff1a;木芯工作室 、I…

项目质量管理有哪些不同阶段?其中“质量“指的是什么?

项目质量管理是指在整个项目中管理和保持质量的过程。 "质量 "不是意味着 "完美"&#xff0c;通常更多的是指在整个项目中确保质量的一致性。然而&#xff0c;"质量 "的确切含义取决于客户或利益相关者对项目的需求&#xff0c;因此在每个项目可…

Ubuntu开机自动挂载硬盘

查看挂载信息&#xff0c;命令台输入 df -h能够看到/dev/nvme0n1p2是我们要挂在的硬盘&#xff0c;其路径是/media/lkzcswq/Data 找到要挂载磁盘的UUID sudo blkid /dev/nvme0n1p2观察到这个磁盘的UUID为72922DF0922DBA0D&#xff0c;type为ntfs 4. 编辑/etc/fstab文件 #如…

【服务器数据恢复】VMware虚拟机下的SQL Server数据库数据恢复案例

服务器数据恢复环境&#xff1a; 一台某品牌PowerEdge系列服务器和一台PowerVault系列存储&#xff0c;上层是ESXI虚拟机文件&#xff0c;虚拟机中运行SQL Server数据库。 服务器故障&#xff1a; 机房非正常断电导致虚拟机无法启动。管理员检查虚拟机发现虚拟机配置文件丢失&…

一、Java概述

一、Java概述 1.1 版本 Java SE 标准版&#xff08;核心版本&#xff09;&#xff0c;主要包含Java最核心的库包括&#xff1a;集合&#xff0c;IO&#xff0c;数据库连接、网络编程等 Java EE 企业版&#xff0c;主要用于开发&#xff0c;装配&#xff0c;部署企业级应用包括…

工业机器人编程调试怎么学

很多人觉得工业机器人很难学学&#xff0c;实际上机器人涉及的知识远比PLC要少。现简单说明一下初学者学习工业机器人编程调试的流程&#xff0c;以AUBO机器人为例&#xff1a; 首先我们需要知道工业机器人的调试学起来不难&#xff0c;远比编程更简单&#xff0c;示教器上的编…

基于信息间隙决策理论的碳捕集电厂调度(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Golang Map原理(底层结构、查找/新增/删除、扩缩容)

参考&#xff1a; 解剖Go语言map底层实现Go语言核心手册-3.字典 一、Go Map底层结构&#xff1a; Go map的底层实现是一个哈希表&#xff08;数组 链表&#xff09;&#xff0c;使用拉链法消除哈希冲突&#xff0c;因此实现map的过程实际上就是实现哈希表的过程。 先来看下…

react hooks学习记录

react hook学习记录1.什么是hooks2.State Hook3.Effect Hook4.Ref Hook1.什么是hooks (1). Hook是React 16.8.0版本增加的新特性/新语法 (2). 可以让你在函数组件中使用 state 以及其他的 React 特性 貌似现在更多的也是使用函数式组件的了&#xff0c;重要 2.State Hook imp…

Linux系统安装:Zookeeper

目录 Zookeeper的安装 1、环境准备 2、上传 3、解压文件到opt/zookeeper目下 4、安装完后进入zookeeper&#xff0c;找到conf目录 5、复制zoo_sample.cfg 6、编辑zoo.cfg 7、复制一份会话&#xff0c;进入zookeeper安装目录&#xff0c;创建一个文件夹zkdata&#xff0…

使用yeoman根据自己的模板创建一个脚手架

介绍 本文使用的模板并不是通用模板~&#xff0c;是自己构建的模板。内部具体如何选择模板逻辑就没有了&#xff0c;仅仅相当于入门demo实现流程。有兴趣学习脚手架的话yo还是不错的&#xff0c;走完本文逻辑可以试试看抽成自己项目&#xff0c;然后引用至公司~加油&#xff0…

【日常总结】Docker 磁盘占满解决方案

目录 项目背景&#xff1a; 问题描述 原因分析&#xff1a; 解决方案&#xff1a; Step 1&#xff1a;查看硬盘使用情况 Step 2&#xff1a;安装crontab Step 3&#xff1a;编写清理脚本cleardockerlog.sh&#xff0c;并执行一次 Step 4&#xff1a;加入定时任务,并设置…

什么是客户忠诚度?建立忠诚文化的 5 种方法

客户忠诚度影响企业的各个方面&#xff0c;例如收入、品牌形象、预算分配和产品路线图。拥有忠实的客户群对于建立成功的企业至关重要&#xff0c;因为您的客户是您的主要拥护者&#xff0c;有助于为您的企业营造积极的氛围。 什么是客户忠诚度&#xff1f; 客户忠诚度衡量客户…

深入浅出 MyBatis 的一级、二级缓存机制

一、MyBatis 缓存 缓存就是内存中的数据&#xff0c;常常来自对数据库查询结果的保存。使用缓存&#xff0c;我们可以避免频繁与数据库进行交互&#xff0c;从而提高响应速度。 MyBatis 也提供了对缓存的支持&#xff0c;分为一级缓存和二级缓存&#xff0c;来看下下面这张图…

java Object 万字详解 (通俗易懂)

基本介绍构造方法成员方法hashCode()getClass()toString()equals()finalize()JavaBean重写Object类的方法重写toString重写equals一、基本介绍Object类是java类层次最顶层的基类&#xff08;父类&#xff09;&#xff0c;所有类都是直接或间接继承自Object类&#xff0c;因此&a…

进程概念(详细版)

进程的概念本文主要介绍进程的相关知识 文章目录认识冯诺依曼体系结构操作系统的基本概念操作系统的作用是什么系统调用和库函数相关概念进程基本概念描述进程进程控制块(PCB)task_struct 结构体进程是如何被操作系统管理起来的先描述再组织描述好&#xff0c;组织好&#xff0…

taobao.item.img.delete( 删除商品图片 )

&#xffe5;开放平台免费API必须用户授权 删除商品图片 公共参数 请求地址: HTTP地址&#xff1a;http://gw.api.taobao.com/router/rest 公共请求参数: 公共响应参数: 请求参数 响应参数 点击获取key和secret 请求示例 TaobaoClient client new DefaultTaobaoClient(url…