电子产业一站式赋能平台

PCB联盟网

搜索
查看: 72|回复: 0
收起左侧

海康威视,开了体面的薪资!

[复制链接]

283

主题

283

帖子

1891

积分

三级会员

Rank: 3Rank: 3

积分
1891
发表于 2024-11-1 17:02:00 | 显示全部楼层 |阅读模式
大家好,我是库森。
; Z- R+ \2 W2 e) w$ M: G+ i海康威视作为一家体面厂,我们来看看今年海康威视的校招薪资开了多少?
' A9 ?6 r9 d( H; I$ ~我根据一些同学的反馈,整理了海康威视软件开发岗位的校招薪资,在目前的就业背景下,海康威视的校招薪资还是很体面的。
+ f  y5 @9 p$ u8 b
  • 14k x 15 = 21w(本科 985,武汉)
  • 15k x 15 =  22.5w(硕士双一流,杭州)
  • 16 x 15 =  24w (本硕 211,杭州)
  • 19 x 15 = 28.5w (本硕 211,杭州)那海康威视的面试难度如何呢?0 R/ Q4 A/ ^( a9 L- T
    我也找了一位今年秋招面海康威视同学的面经,给大家做做参考参考,总共 1 轮技术面 + 1 轮 HR 面,3-5 个工作日出结果。
    8 M3 l. H- y6 C" `7 r% j一面是技术面,问的问题不算多,主要拷打了 Java、MySQL、Redis 方面的八股文,都属于经典的面试问题,不算难。
    ' X% s0 [+ N  A! ~& e: o

    fmvmujcputf64078576854.jpg

    fmvmujcputf64078576854.jpg
    ; p9 ?: Y& y& M" h2 z8 |' M; o: D
    Java 介绍一下 Spring Boot 整体的启动流程?
  • 首先从main找到run()方法,在执行run()方法之前new一个SpringApplication对象
  • 进入run()方法,创建应用监听器SpringApplicationRunListeners开始监听
  • 然后加载SpringBoot配置环境(ConfigurableEnvironment),然后把配置环境(Environment)加入监听对象中
  • 然后加载应用上下文(ConfigurableApplicationContext),当做run方法的返回对象
  • 最后创建Spring容器,refreshContext(context),实现starter自动化配置和bean的实例化等工作。[/ol]说一说 Spring MVC 整体的执行流程?9 O. p+ ~7 `; T# \. V: L

    cxzzckxp1pl64078576954.jpg

    cxzzckxp1pl64078576954.jpg
    , B. Z7 W5 B4 Y, M( I
    流程图步骤详解:
  • 发送请求:用户发送的所有请求都会到前端控制器DispatcherServlet
  • 请求查找Handler:DispatcherServlet收到请求会调用HandlerMapping(处理器映射器)查找Handler
  • 返回Handler:处理器映射器根据url返回具体的处理器,生成HandlerExecutionChain对象,其中包含了目标Handler和若干拦截器(可能没有)
  • 请求调用Handler:DispatcherServlet通过Handler寻找匹配到HandlerAdapter
  • 执行Handler:HandlerAdapter调用Handler
  • 返回结果:Handler执行完成,返回一个ModelAndView对象
  • 返回结果给DispatcherServlet:HandlerAdapter将Handler执行结果ModelAndView返回给DispatcherServlet
  • 如果Handler返回的View是逻辑视图名称而不是真正的View对象,DispatcherServlet调用resolveViewName方法在配置的所有视图解析器(ViewResolver)中,寻找合适的,最终通过ViewResolver将逻辑视图名解析成真正的View对象
  • ViewResolver通过调用createView方法尝试将视图名解析成View,如果无法解析会返回Null(注: 如果ViewResolver是派生自AbstractCachingViewResolver则在调用createView方法前会先尝试根据viewName和Iocale从缓存中查找对应的视图对象)
  • DispatcherServlet调用View的render方法进行渲染视图 (即将模型数据填充至request域)
  • DispatcherServlet响应用户[/ol]MySQL MySQL 索引的机制,类型有哪些?MySQL可以按照四个角度来分类索引。7 J% t4 x) w: Z; e9 [/ b
  • 按「数据结构」分类:B+tree索引、Hash索引、Full-text索引
  • 按「物理存储」分类:聚簇索引(主键索引)、二级索引(辅助索引)
  • 按「字段特性」分类:主键索引、唯一索引、普通索引、前缀索引
  • 按「字段个数」分类:单列索引、联合索引接下来,按照这些角度来说说各类索引的特点。: R$ v- \0 }  ~2 z
    按数据结构分类
    " G( m9 B: }, p( @3 d" R3 Q3 \* o
    从数据结构的角度来看,MySQL 常见索引有 B+Tree 索引、HASH 索引、Full-Text 索引。
    ( \* y! d8 V4 e+ R9 u3 M. y每一种存储引擎支持的索引类型不一定相同,我在表中总结了 MySQL 常见的存储引擎 InnoDB、MyISAM 和 Memory 分别支持的索引类型。
    : g- {( o' {% ~- |6 V( N6 {; U

    zjro0uixxki64078577054.jpg

    zjro0uixxki64078577054.jpg

    # [) J8 ?7 J$ Z# FInnoDB 是在 MySQL 5.5 之后成为默认的 MySQL 存储引擎,B+Tree 索引类型也是 MySQL 存储引擎采用最多的索引类型。
    ( p& ?# t2 H4 n在创建表时,InnoDB 存储引擎会根据不同的场景选择不同的列作为索引:
    * I5 P" v0 p. X) r+ w9 F
  • 如果有主键,默认会使用主键作为聚簇索引的索引键(key);
  • 如果没有主键,就选择第一个不包含 NULL 值的唯一列作为聚簇索引的索引键(key);
  • 在上面两个都没有的情况下,InnoDB 将自动生成一个隐式自增 id 列作为聚簇索引的索引键(key);其它索引都属于辅助索引(Secondary Index),也被称为二级索引或非聚簇索引。创建的主键索引和二级索引默认使用的是 B+Tree 索引
    + M- Z+ q$ U% A, ^) ]; @# x6 h按物理存储分类
    & h* e2 z8 \; H
    从物理存储的角度来看,索引分为聚簇索引(主键索引)、二级索引(辅助索引)。3 j6 b6 \! k  ^+ H# J5 M6 f4 b
    这两个区别在前面也提到了:9 b- }+ ]. ?+ o7 q! b( a
  • 主键索引的 B+Tree 的叶子节点存放的是实际数据,所有完整的用户记录都存放在主键索引的 B+Tree 的叶子节点里;
  • 二级索引的 B+Tree 的叶子节点存放的是主键值,而不是实际数据。所以,在查询时使用了二级索引,如果查询的数据能在二级索引里查询的到,那么就不需要回表,这个过程就是覆盖索引。如果查询的数据不在二级索引里,就会先检索二级索引,找到对应的叶子节点,获取到主键值后,然后再检索主键索引,就能查询到数据了,这个过程就是回表。: G+ s! p* ]7 N1 y
    按字段特性分类) d; Q$ x/ \  V- ]) a
    从字段特性的角度来看,索引分为主键索引、唯一索引、普通索引、前缀索引。1 Z! D+ e8 X+ v& Q, z
  • 主键索引主键索引就是建立在主键字段上的索引,通常在创建表的时候一起创建,一张表最多只有一个主键索引,索引列的值不允许有空值。) d  [2 t/ |# _8 S/ \# p6 v
    在创建表时,创建主键索引的方式如下:
    7 d' m4 |7 R" \CREATE TABLE table_name  (' Y  R2 R1 A6 p9 o; v
      ....6 [  M! h8 e; s  ^6 n, l
      PRIMARY KEY (index_column_1) USING BTREE# p4 C) i. C% `
    );
    5 C; k* t2 i0 `" S& v/ P; s$ g6 b
  • 唯一索引唯一索引建立在 UNIQUE 字段上的索引,一张表可以有多个唯一索引,索引列的值必须唯一,但是允许有空值。, g% ?% k" w7 ~) L1 l1 v  a* {
    在创建表时,创建唯一索引的方式如下:
    0 u; g( g, N3 U# x( \0 mCREATE TABLE table_name  (5 `- u. f8 W' N5 m- ]
      ....1 y3 l% J, H1 O" s' v$ K) W' `, o- p
      UNIQUE KEY(index_column_1,index_column_2,...) 2 o: I# X4 F% s9 n- g
    );" i" S/ N7 M% j% B% h/ f7 r
    建表后,如果要创建唯一索引,可以使用这面这条命令:
    ) x- \. {4 v1 Z( |CREATE UNIQUE INDEX index_name
    . e6 |$ u4 ^, I( D( V( A. Z7 LON table_name(index_column_1,index_column_2,...);5 Y7 W- I9 [' q0 [/ N
  • 普通索引普通索引就是建立在普通字段上的索引,既不要求字段为主键,也不要求字段为 UNIQUE。) C) O% T/ j% r2 l* _& O3 F
    在创建表时,创建普通索引的方式如下:
    - O- w4 Q0 j" j/ b. G6 Y0 ]3 Q8 oCREATE TABLE table_name  (
    / ^# G, V; l$ x  ....* i7 o6 g' W: o3 U
      INDEX(index_column_1,index_column_2,...)
    1 r# p6 L% D2 l);3 R3 p& n. W) W9 S3 \7 ~
    建表后,如果要创建普通索引,可以使用这面这条命令:4 x0 M0 `. f9 g& E
    CREATE INDEX index_name2 J5 [# Q; f( F5 Z
    ON table_name(index_column_1,index_column_2,...);9 ~+ b' V; g" v$ c& J, Q" u: r
  • 前缀索引前缀索引是指对字符类型字段的前几个字符建立的索引,而不是在整个字段上建立的索引,前缀索引可以建立在字段类型为 char、 varchar、binary、varbinary 的列上。
    * i, V6 `% _) ?使用前缀索引的目的是为了减少索引占用的存储空间,提升查询效率。
      X% u& T4 ^1 ]$ J/ v; W( @在创建表时,创建前缀索引的方式如下:
    - Q* Z1 T# G; O! TCREATE TABLE table_name(7 |! ?) o$ a5 C. y
        column_list,# }! x7 Z# J0 D$ {, P* w/ T# q
        INDEX(column_name(length))
    3 n: n9 D; y6 w# L+ x+ A);
    & G( l' O! V( G- C' ]9 @$ \: A. v建表后,如果要创建前缀索引,可以使用这面这条命令:
    ( N: E; }% t5 Y: p: }CREATE INDEX index_name" H7 R# Y0 M' D5 r* {" r& {
    ON table_name(column_name(length));* ~, [; i$ k# k2 B1 ^% q
    按字段个数分类! ^  v, S" p1 o3 b/ F. G
    从字段个数的角度来看,索引分为单列索引、联合索引(复合索引)。/ q& n6 P6 A; @7 I5 `  E" N  ^
  • 建立在单列上的索引称为单列索引,比如主键索引;
  • 建立在多列上的索引称为联合索引;通过将多个字段组合成一个索引,该索引就被称为联合索引。
    ' W: x8 x" f1 W7 J) a比如,将商品表中的 product_no 和 name 字段组合成联合索引(product_no, name),创建联合索引的方式如下:
    ' C- z3 B2 L/ @CREATE INDEX index_product_no_name ON product(product_no, name);
    " Z# {6 n2 \% F联合索引(product_no, name) 的 B+Tree 示意图如下(图中叶子节点之间我画了单向链表,但是实际上是双向链表,原图我找不到了,修改不了,偷个懒我不重画了,大家脑补成双向链表就行)。+ x) B4 s- m2 L  ?1 }+ t$ q; P3 M

    ibea4h5cthi64078577154.jpg

    ibea4h5cthi64078577154.jpg
      c0 D: V/ P8 i7 |' S
    可以看到,联合索引的非叶子节点用两个字段的值作为 B+Tree 的 key 值。当在联合索引查询数据时,先按 product_no 字段比较,在 product_no 相同的情况下再按 name 字段比较。
    5 F  B3 V& r2 w. Q* C( ^; {也就是说,联合索引查询的 B+Tree 是先按 product_no 进行排序,然后再 product_no 相同的情况再按 name 字段排序。
    8 Q, v' E, |/ }因此,使用联合索引时,存在最左匹配原则,也就是按照最左优先的方式进行索引的匹配。在使用联合索引进行查询的时候,如果不遵循「最左匹配原则」,联合索引会失效,这样就无法利用到索引快速查询的特性了。. e) x1 m( ~5 F( t! K4 n
    比如,如果创建了一个 (a, b, c) 联合索引,如果查询条件是以下这几种,就可以匹配上联合索引:
    4 x  o! \  A1 f2 ]4 H
  • where a=1;
  • where a=1 and b=2 and c=3;
  • where a=1 and b=2;需要注意的是,因为有查询优化器,所以 a 字段在 where 子句的顺序并不重要。/ ^- c' R" ?& s8 j* b, \! I& {) ^
    但是,如果查询条件是以下这几种,因为不符合最左匹配原则,所以就无法匹配上联合索引,联合索引就会失效:
    0 e/ p, m% \& `% z: Z; D  B
  • where b=2;
  • where c=3;
  • where b=2 and c=3;上面这些查询条件之所以会失效,是因为(a, b, c) 联合索引,是先按 a 排序,在 a 相同的情况再按 b 排序,在 b 相同的情况再按 c 排序。所以,b 和 c 是全局无序,局部相对有序的,这样在没有遵循最左匹配原则的情况下,是无法利用到索引的。9 o0 I0 M- j2 P
    联合索引有一些特殊情况,并不是查询过程使用了联合索引查询,就代表联合索引中的所有字段都用到了联合索引进行索引查询,也就是可能存在部分字段用到联合索引的 B+Tree,部分字段没有用到联合索引的 B+Tree 的情况。
    ; Y; q2 ~9 ?- d& T( _* O这种特殊情况就发生在范围查询。联合索引的最左匹配原则会一直向右匹配直到遇到「范围查询」就会停止匹配。也就是范围查询的字段可以用到联合索引,但是在范围查询字段的后面的字段无法用到联合索引2 |+ {2 l7 J, P9 _0 y/ ~/ {+ O  L. ]
    有无排查索引失效的经验,展开讲讲?可以使用 EXPLAIN 来查看 SQL 的执行计划,判断SQL是否走了索引,如果没有走索引,就代表索引发生失效了。' e+ y% O: f- c* U2 a# r7 C
    如下图,就是一个没有使用索引,并且是一个全表扫描的查询语句。
    % ~5 _& l7 S7 A# k& F

    53a05fgp4c264078577254.jpg

    53a05fgp4c264078577254.jpg

    + s, u0 x6 p$ [2 R对于执行计划,参数有:
    ( g0 `. L6 {# g/ l& {8 x/ v2 \" \. r
  • possible_keys 字段表示可能用到的索引;
  • key 字段表示实际用的索引,如果这一项为 NULL,说明没有使用索引;
  • key_len 表示索引的长度;
  • rows 表示扫描的数据行数。
  • type 表示数据扫描类型,我们需要重点看这个。type 字段就是描述了找到所需数据时使用的扫描方式是什么,常见扫描类型的执行效率从低到高的顺序为: J. x9 d/ E0 z2 F& Y
  • All(全表扫描):在这些情况里,all 是最坏的情况,因为采用了全表扫描的方式。
  • index(全索引扫描):index 和 all 差不多,只不过 index 对索引表进行全扫描,这样做的好处是不再需要对数据进行排序,但是开销依然很大。所以,要尽量避免全表扫描和全索引扫描。
  • range(索引范围扫描):range 表示采用了索引范围扫描,一般在 where 子句中使用 、in、between 等关键词,只检索给定范围的行,属于范围查找。从这一级别开始,索引的作用会越来越明显,因此我们需要尽量让 SQL 查询可以使用到 range 这一级别及以上的 type 访问方式
  • ref(非唯一索引扫描):ref 类型表示采用了非唯一索引,或者是唯一索引的非唯一性前缀,返回数据返回可能是多条。因为虽然使用了索引,但该索引列的值并不唯一,有重复。这样即使使用索引快速查找到了第一条数据,仍然不能停止,要进行目标值附近的小范围扫描。但它的好处是它并不需要扫全表,因为索引是有序的,即便有重复值,也是在一个非常小的范围内扫描。
  • eq_ref(唯一索引扫描):eq_ref 类型是使用主键或唯一索引时产生的访问方式,通常使用在多表联查中。比如,对两张表进行联查,关联条件是两张表的 user_id 相等,且 user_id 是唯一索引,那么使用 EXPLAIN 进行执行计划查看的时候,type 就会显示 eq_ref。
  • const(结果只有一条的主键或唯一索引扫描):const 类型表示使用了主键或者唯一索引与常量值进行比较,比如 select name from product where id=1。需要说明的是 const 类型和 eq_ref 都使用了主键或唯一索引,不过这两个类型有所区别,const 是与常量进行比较,查询效率会更快,而 eq_ref 通常用于多表联查中extra 显示的结果,这里说几个重要的参考指标:; t3 F9 F5 x9 w- j2 p5 b5 p5 l
  • Using filesort :当查询语句中包含 group by 操作,而且无法利用索引完成排序操作的时候, 这时不得不选择相应的排序算法进行,甚至可能会通过文件排序,效率是很低的,所以要避免这种问题的出现。
  • Using temporary:使了用临时表保存中间结果,MySQL 在对查询结果排序时使用临时表,常见于排序 order by 和分组查询 group by。效率低,要避免这种问题的出现。
  • Using index:所需数据只需在索引即可全部获得,不须要再到表中取数据,也就是使用了覆盖索引,避免了回表操作,效率不错。索引失效的场景有哪些?会发生索引失效的情况:
    6 L( i4 u# n6 V# d  \
  • 当我们使用左或者左右模糊匹配的时候,也就是 like %xx 或者 like %xx%这两种方式都会造成索引失效;
  • 当我们在查询条件中对索引列使用函数,就会导致索引失效。
  • 当我们在查询条件中对索引列进行表达式计算,也是无法走索引的。
  • MySQL 在遇到字符串和数字比较的时候,会自动把字符串转为数字,然后再进行比较。如果字符串是索引列,而条件语句中的输入参数是数字的话,那么索引列会发生隐式类型转换,由于隐式类型转换是通过 CAST 函数实现的,等同于对索引列使用了函数,所以就会导致索引失效。
  • 联合索引要能正确使用需要遵循最左匹配原则,也就是按照最左优先的方式进行索引的匹配,否则就会导致索引失效。
  • 在 WHERE 子句中,如果在 OR 前的条件列是索引列,而在 OR 后的条件列不是索引列,那么索引会失效。Redis Redis 为什么这么快?官方使用基准测试的结果是,单线程的 Redis 吞吐量可以达到 10W/每秒,如下图所示:
    ; L' P1 `" {+ v  b+ D! z

    h1twxfhtg3w64078577354.jpg

    h1twxfhtg3w64078577354.jpg

    . I) o; {; x$ R# j7 e之所以 Redis 采用单线程(网络 I/O 和执行命令)那么快,有如下几个原因:5 Y+ Y- X7 G9 A0 p, N- P) Y
  • Redis 的大部分操作都在内存中完成,并且采用了高效的数据结构,因此 Redis 瓶颈可能是机器的内存或者网络带宽,而并非 CPU,既然 CPU 不是瓶颈,那么自然就采用单线程的解决方案了;
  • Redis 采用单线程模型可以避免了多线程之间的竞争,省去了多线程切换带来的时间和性能上的开销,而且也不会导致死锁问题。
  • Redis 采用了 I/O 多路复用机制处理大量的客户端 Socket 请求,IO 多路复用机制是指一个线程处理多个 IO 流,就是我们经常听到的 select/epoll 机制。简单来说,在 Redis 只运行单线程的情况下,该机制允许内核中,同时存在多个监听 Socket 和已连接 Socket。内核会一直监听这些 Socket 上的连接请求或数据请求。一旦有请求到达,就会交给 Redis 线程处理,这就实现了一个 Redis 线程处理多个 IO 流的效果。Redis 6.0 之后为什么引入了多线程?Redis 单线程指的是「接收客户端请求->解析请求 ->进行数据读写等操作->发送数据给客户端」这个过程是由一个线程(主线程)来完成的,这也是我们常说 Redis 是单线程的原因。
    & D/ M/ Q8 c. V但是,Redis 程序并不是单线程的,Redis 在启动的时候,是会启动后台线程(BIO)的:4 a, ^; [. `- H) \* C( N
  • Redis 在 2.6 版本,会启动 2 个后台线程,分别处理关闭文件、AOF 刷盘这两个任务;
  • Redis 在 4.0 版本之后,新增了一个新的后台线程,用来异步释放 Redis 内存,也就是 lazyfree 线程。例如执行 unlink key / flushdb async / flushall async 等命令,会把这些删除操作交给后台线程来执行,好处是不会导致 Redis 主线程卡顿。因此,当我们要删除一个大 key 的时候,不要使用 del 命令删除,因为 del 是在主线程处理的,这样会导致 Redis 主线程卡顿,因此我们应该使用 unlink 命令来异步删除大key。之所以 Redis 为「关闭文件、AOF 刷盘、释放内存」这些任务创建单独的线程来处理,是因为这些任务的操作都是很耗时的,如果把这些任务都放在主线程来处理,那么 Redis 主线程就很容易发生阻塞,这样就无法处理后续的请求了。; x% Z5 I" ]! _! \- N
    后台线程相当于一个消费者,生产者把耗时任务丢到任务队列中,消费者(BIO)不停轮询这个队列,拿出任务就去执行对应的方法即可。
    ! X) }" I0 v/ x* @# \

    znfflvyj2bj64078577454.jpg

    znfflvyj2bj64078577454.jpg
    ! b( P# v1 r9 ~
    虽然 Redis 的主要工作(网络 I/O 和执行命令)一直是单线程模型,但是在 Redis 6.0 版本之后,也采用了多个 I/O 线程来处理网络请求这是因为随着网络硬件的性能提升,Redis 的性能瓶颈有时会出现在网络 I/O 的处理上
    8 m6 H4 u9 b* d8 Z$ h( c7 C, G4 f所以为了提高网络 I/O 的并行度,Redis 6.0 对于网络 I/O 采用多线程来处理。但是对于命令的执行,Redis 仍然使用单线程来处理,所以大家不要误解Redis 有多线程同时执行命令
    ; K% S0 P* S$ ?  y1 g$ ]Redis 官方表示,Redis 6.0 版本引入的多线程 I/O 特性对性能提升至少是一倍以上/ [1 q' ?& _  N4 k# n, }: t! N2 h
    Redis 6.0 版本支持的 I/O 多线程特性,默认情况下 I/O 多线程只针对发送响应数据(write client socket),并不会以多线程的方式处理读请求(read client socket)。要想开启多线程处理客户端读请求,就需要把 Redis.conf 配置文件中的 io-threads-do-reads 配置项设为 yes。
    % ]) m8 d9 \0 j+ \& u//读请求也使用io多线程5 z1 j/ p2 f* R( r* I( }0 ~1 P
    io-threads-do-reads yes) s7 V7 P3 U# ^' @
    同时, Redis.conf 配置文件中提供了 IO 多线程个数的配置项。
    , ], Q# u' x  r! B4 d  E// io-threads N,表示启用 N-1 个 I/O 多线程(主线程也算一个 I/O 线程)6 f$ q# S+ q- w5 W
    io-threads 4
    8 X9 b% m$ ~( {3 M关于线程数的设置,官方的建议是如果为 4 核的 CPU,建议线程数设置为 2 或 3,如果为 8 核 CPU 建议线程数设置为 6,线程数一定要小于机器核数,线程数并不是越大越好。
    ; ^5 Z% M9 t2 m% ]7 x, R因此, Redis 6.0 版本之后,Redis 在启动的时候,默认情况下会额外创建 6 个线程(这里的线程数不包括主线程):
    ( {0 }( B" g3 |& N
  • Redis-server :Redis的主线程,主要负责执行命令;
  • bio_close_file、bio_aof_fsync、bio_lazy_free:三个后台线程,分别异步处理关闭文件任务、AOF刷盘任务、释放内存任务;
  • io_thd_1、io_thd_2、io_thd_3:三个 I/O 线程,io-threads 默认是 4 ,所以会启动 3(4-1)个 I/O 多线程,用来分担 Redis 网络 I/O 的压力。Redis 分布式锁怎么解决超卖问题的?同一个锁key,同一时间只能有一个客户端拿到锁,其他客户端会陷入无限的等待来尝试获取那个锁,只有获取到锁的客户端才能执行下面的业务逻辑。7 Z: j- D( {7 c) ^" y; |) y; U, k
    比如说,用户要一次性买 10 台手机,那么避免超卖的流程如下:
    ; J2 c1 f; _& N; H, Q' F
  • 只有一个订单系统实例可以成功加分布式锁,然后只有他一个实例可以查库存、判断库存是否充足、下单扣减库存,接着释放锁。
  • 释放锁之后,另外一个订单系统实例才能加锁,接着查库存,一下发现库存只有 2 个了,库存不足,无法购买,下单失败,不会将库存扣减为-8的,就避免超卖的问题。这种方案的缺点是同一个商品在多用户同时下单的情况下,会基于分布式锁串行化处理,导致没法同时处理同一个商品的大量下单的请求。
  • 回复

    使用道具 举报

    发表回复

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则


    联系客服 关注微信 下载APP 返回顶部 返回列表