mirror of
https://github.com/zhwei820/learn.lianglianglee.com.git
synced 2025-11-15 13:43:50 +08:00
u
This commit is contained in:
@@ -12,9 +12,7 @@
|
||||
<!-- theme css & js -->
|
||||
<meta name="generator" content="Hexo 4.2.0">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="book-container">
|
||||
<div class="book-sidebar">
|
||||
<div class="book-brand">
|
||||
@@ -27,164 +25,113 @@
|
||||
<ul class="uncollapsible">
|
||||
<li><a href="/" class="current-tab">首页</a></li>
|
||||
</ul>
|
||||
|
||||
<ul class="uncollapsible">
|
||||
<li><a href="../">上一级</a></li>
|
||||
</ul>
|
||||
|
||||
<ul class="uncollapsible">
|
||||
<li>
|
||||
|
||||
|
||||
<a href="/专栏/架构设计面试精讲/00 开篇词 中高级研发面试,逃不开架构设计这一环.md.html">00 开篇词 中高级研发面试,逃不开架构设计这一环.md.html</a>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
|
||||
<a href="/专栏/架构设计面试精讲/01 研发工程师想提升面试竞争力,该具备这三个技术认知.md.html">01 研发工程师想提升面试竞争力,该具备这三个技术认知.md.html</a>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
|
||||
<a href="/专栏/架构设计面试精讲/02 研发工程师如何用架构师视角回答架构设计方案?.md.html">02 研发工程师如何用架构师视角回答架构设计方案?.md.html</a>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
|
||||
<a href="/专栏/架构设计面试精讲/03 面试官如何考察与 CAP 有关的分布式理论?.md.html">03 面试官如何考察与 CAP 有关的分布式理论?.md.html</a>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
|
||||
<a href="/专栏/架构设计面试精讲/04 亿级商品存储下,如何深度回答分布式系统的原理性问题?.md.html">04 亿级商品存储下,如何深度回答分布式系统的原理性问题?.md.html</a>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
|
||||
<a href="/专栏/架构设计面试精讲/05 海量并发场景下,如何回答分布式事务一致性问题?.md.html">05 海量并发场景下,如何回答分布式事务一致性问题?.md.html</a>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<a class="current-tab" href="/专栏/架构设计面试精讲/06 分布式系统中,如何回答锁的实现原理?.md.html">06 分布式系统中,如何回答锁的实现原理?.md.html</a>
|
||||
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
|
||||
<a href="/专栏/架构设计面试精讲/07 RPC:如何在面试中展现出“造轮子”的能力?.md.html">07 RPC:如何在面试中展现出“造轮子”的能力?.md.html</a>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
|
||||
<a href="/专栏/架构设计面试精讲/08 MQ:如何回答消息队列的丢失、重复与积压问题.md.html">08 MQ:如何回答消息队列的丢失、重复与积压问题.md.html</a>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
|
||||
<a href="/专栏/架构设计面试精讲/08 案例串联 如何让系统抗住双十一的预约抢购活动?.md.html">08 案例串联 如何让系统抗住双十一的预约抢购活动?.md.html</a>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
|
||||
<a href="/专栏/架构设计面试精讲/09 如何回答 MySQL 的索引原理与优化问题?.md.html">09 如何回答 MySQL 的索引原理与优化问题?.md.html</a>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
|
||||
<a href="/专栏/架构设计面试精讲/10 如何回答 MySQL 的事务隔离级别和锁的机制?.md.html">10 如何回答 MySQL 的事务隔离级别和锁的机制?.md.html</a>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
|
||||
<a href="/专栏/架构设计面试精讲/11 读多写少:MySQL 如何优化数据查询方案?.md.html">11 读多写少:MySQL 如何优化数据查询方案?.md.html</a>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
|
||||
<a href="/专栏/架构设计面试精讲/12 写多读少:MySQL 如何优化数据存储方案?.md.html">12 写多读少:MySQL 如何优化数据存储方案?.md.html</a>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
|
||||
<a href="/专栏/架构设计面试精讲/13 缓存原理:应对面试你要掌握 Redis 哪些原理?.md.html">13 缓存原理:应对面试你要掌握 Redis 哪些原理?.md.html</a>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
|
||||
<a href="/专栏/架构设计面试精讲/14 缓存策略:面试中如何回答缓存穿透、雪崩等问题?.md.html">14 缓存策略:面试中如何回答缓存穿透、雪崩等问题?.md.html</a>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
|
||||
<a href="/专栏/架构设计面试精讲/15 如何向面试官证明你做的系统是高可用的?.md.html">15 如何向面试官证明你做的系统是高可用的?.md.html</a>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
|
||||
<a href="/专栏/架构设计面试精讲/16 如何从架构师角度回答系统容错、降级等高可用问题?.md.html">16 如何从架构师角度回答系统容错、降级等高可用问题?.md.html</a>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
|
||||
<a href="/专栏/架构设计面试精讲/17 如何向面试官证明你做的系统是高性能的?.md.html">17 如何向面试官证明你做的系统是高性能的?.md.html</a>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
|
||||
<a href="/专栏/架构设计面试精讲/18 如何从架构师角度回答怎么应对千万级流量的问题?.md.html">18 如何从架构师角度回答怎么应对千万级流量的问题?.md.html</a>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
|
||||
<a href="/专栏/架构设计面试精讲/19 彩蛋 互联网架构设计面试,你需要掌握的知识体系.md.html">19 彩蛋 互联网架构设计面试,你需要掌握的知识体系.md.html</a>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
|
||||
<a href="/专栏/架构设计面试精讲/结束语 程序员的道、术、势.md.html">结束语 程序员的道、术、势.md.html</a>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sidebar-toggle" onclick="sidebar_toggle()" onmouseover="add_inner()" onmouseleave="remove_inner()">
|
||||
<div class="sidebar-toggle-inner"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function add_inner() {
|
||||
let inner = document.querySelector('.sidebar-toggle-inner')
|
||||
inner.classList.add('show')
|
||||
}
|
||||
|
||||
function remove_inner() {
|
||||
let inner = document.querySelector('.sidebar-toggle-inner')
|
||||
inner.classList.remove('show')
|
||||
}
|
||||
|
||||
function sidebar_toggle() {
|
||||
let sidebar_toggle = document.querySelector('.sidebar-toggle')
|
||||
let sidebar = document.querySelector('.book-sidebar')
|
||||
@@ -200,7 +147,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function open_sidebar() {
|
||||
let sidebar = document.querySelector('.book-sidebar')
|
||||
let overlay = document.querySelector('.off-canvas-overlay')
|
||||
@@ -213,9 +159,7 @@ function hide_canvas() {
|
||||
sidebar.classList.remove('show')
|
||||
overlay.classList.remove('show')
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<div class="off-canvas-content">
|
||||
<div class="columns">
|
||||
<div class="column col-12 col-lg-12">
|
||||
@@ -293,11 +237,8 @@ function hide_canvas() {
|
||||
</ul>
|
||||
<p>在数据库层面,select for update 是悲观锁,会一直阻塞直到事务提交,所以为了不产生锁等待而消耗资源,你可以基于乐观锁的方式来实现分布式锁,比如基于版本号的方式,首先在数据库增加一个 int 型字段 ver,然后在 SELECT 同时获取 ver 值,最后在 UPDATE 的时候检查 ver 值是否为与第 2 步或得到的版本值相同。</p>
|
||||
<pre><code>## SELECT 同时获取 ver 值
|
||||
|
||||
select amount, old_ver from order where order_id = xxx
|
||||
|
||||
## UPDATE 的时候检查 ver 值是否与第 2 步获取到的值相同
|
||||
|
||||
update order set ver = old_ver + 1, amount = yyy where order_id = xxx and ver = old_ver
|
||||
</code></pre>
|
||||
<p>此时,如果更新结果的记录数为1,就表示成功,如果更新结果的记录数为 0,就表示已经被其他应用更新过了,需要做异常处理。</p>
|
||||
@@ -317,15 +258,10 @@ update order set ver = old_ver + 1, amount = yyy where order_id = xxx and ver =
|
||||
<p>而解锁的过程就是将 lock_key 键删除,但不能乱删,要保证执行操作的客户端就是加锁的客户端。而这个时候, unique_value 的作用就体现出来,实现方式可以通过 lua 脚本判断 unique_value 是否为加锁客户端。</p>
|
||||
<p>选用 Lua 脚本是为了保证解锁操作的原子性。因为 Redis 在执行 Lua 脚本时,可以以原子性的方式执行,从而保证了锁释放操作的原子性。</p>
|
||||
<pre><code>// 释放锁时,先比较 unique_value 是否相等,避免锁的误释放
|
||||
|
||||
if redis.call("get",KEYS[1]) == ARGV[1] then
|
||||
|
||||
return redis.call("del",KEYS[1])
|
||||
|
||||
else
|
||||
|
||||
return 0
|
||||
|
||||
end
|
||||
</code></pre>
|
||||
<p>以上,就是基于 Redis 的 SET 命令和 Lua 脚本在 Redis 单节点上完成了分布式锁的加锁、解锁,不过在实际面试中,<strong>你不能仅停留在操作上,因为这并不能满足应对面试需要掌握的知识深度,</strong> 所以你还要清楚基于 Redis 实现分布式锁的优缺点;Redis 的超时时间设置问题;站在架构设计层面上 Redis 怎么解决集群情况下分布式锁的可靠性问题。</p>
|
||||
@@ -382,12 +318,10 @@ end
|
||||
<a href="/专栏/架构设计面试精讲/07 RPC:如何在面试中展现出“造轮子”的能力?.md.html">下一页</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a class="off-canvas-overlay" onclick="hide_canvas()"></a>
|
||||
</div>
|
||||
<script defer src="https://static.cloudflareinsights.com/beacon.min.js/v652eace1692a40cfa3763df669d7439c1639079717194" integrity="sha512-Gi7xpJR8tSkrpF7aordPZQlW2DLtzUlZcumS8dMQjwDHEnw9I7ZLyiOj/6tZStRBGtGgN6ceN6cMH8z7etPGlw==" data-cf-beacon='{"rayId":"7099790fde6b3cfa","version":"2021.12.0","r":1,"token":"1f5d475227ce4f0089a7cff1ab17c0f5","si":100}' crossorigin="anonymous"></script>
|
||||
@@ -396,11 +330,9 @@ end
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-NPSEEVD756"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
|
||||
function gtag() {
|
||||
dataLayer.push(arguments);
|
||||
}
|
||||
|
||||
gtag('js', new Date());
|
||||
gtag('config', 'G-NPSEEVD756');
|
||||
var path = window.location.pathname
|
||||
@@ -414,14 +346,12 @@ end
|
||||
} else {
|
||||
setCookie("lastPath", path)
|
||||
}
|
||||
|
||||
function setCookie(cname, cvalue) {
|
||||
var d = new Date();
|
||||
d.setTime(d.getTime() + (180 * 24 * 60 * 60 * 1000));
|
||||
var expires = "expires=" + d.toGMTString();
|
||||
document.cookie = cname + "=" + cvalue + "; " + expires + ";path = /";
|
||||
}
|
||||
|
||||
function getCookie(cname) {
|
||||
var name = cname + "=";
|
||||
var ca = document.cookie.split(';');
|
||||
@@ -431,7 +361,5 @@ end
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user