learn.lianglianglee.com/专栏/分布式技术原理与实战45讲-完/00 开篇词:搭建分布式知识体系,挑战高薪 Offer.md.html
2022-08-14 03:40:33 +08:00

367 lines
28 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<!-- saved from url=(0046)https://kaiiiz.github.io/hexo-theme-book-demo/ -->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">
<link rel="icon" href="/static/favicon.png">
<title>00 开篇词:搭建分布式知识体系,挑战高薪 Offer.md.html</title>
<!-- Spectre.css framework -->
<link rel="stylesheet" href="/static/index.css">
<!-- 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">
<a href="/">
<img src="/static/favicon.png">
<span>技术文章摘抄</span>
</a>
</div>
<div class="book-menu uncollapsible">
<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 class="current-tab" href="/专栏/分布式技术原理与实战45讲-完/00 开篇词:搭建分布式知识体系,挑战高薪 Offer.md.html">00 开篇词:搭建分布式知识体系,挑战高薪 Offer</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/01 如何证明分布式系统的 CAP 理论?.md.html">01 如何证明分布式系统的 CAP 理论?</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/02 不同数据一致性模型有哪些应用?.md.html">02 不同数据一致性模型有哪些应用?</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/03 如何透彻理解 Paxos 算法?.md.html">03 如何透彻理解 Paxos 算法?</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/04 ZooKeeper 如何保证数据一致性?.md.html">04 ZooKeeper 如何保证数据一致性?</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/05 共识问题:区块链如何确认记账权?.md.html">05 共识问题:区块链如何确认记账权?</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/06 如何准备一线互联网公司面试?.md.html">06 如何准备一线互联网公司面试?</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/07 分布式事务有哪些解决方案?.md.html">07 分布式事务有哪些解决方案?</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/08 对比两阶段提交,三阶段协议有哪些改进?.md.html">08 对比两阶段提交,三阶段协议有哪些改进?</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/09 MySQL 数据库如何实现 XA 规范?.md.html">09 MySQL 数据库如何实现 XA 规范?</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/10 如何在业务中体现 TCC 事务模型?.md.html">10 如何在业务中体现 TCC 事务模型?</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/11 分布式锁有哪些应用场景和实现?.md.html">11 分布式锁有哪些应用场景和实现?</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/12 如何使用 Redis 快速实现分布式锁?.md.html">12 如何使用 Redis 快速实现分布式锁?</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/13 分布式事务考点梳理 + 高频面试题.md.html">13 分布式事务考点梳理 + 高频面试题</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/14 如何理解 RPC 远程服务调用?.md.html">14 如何理解 RPC 远程服务调用?</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/15 为什么微服务需要 API 网关?.md.html">15 为什么微服务需要 API 网关?</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/16 如何实现服务注册与发现?.md.html">16 如何实现服务注册与发现?</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/17 如何实现分布式调用跟踪?.md.html">17 如何实现分布式调用跟踪?</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/18 分布式下如何实现配置管理?.md.html">18 分布式下如何实现配置管理?</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/19 容器化升级对服务有哪些影响?.md.html">19 容器化升级对服务有哪些影响?</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/20 ServiceMesh服务网格有哪些应用.md.html">20 ServiceMesh服务网格有哪些应用</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/21 Dubbo vs Spring Cloud两大技术栈如何选型.md.html">21 Dubbo vs Spring Cloud两大技术栈如何选型</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/22 分布式服务考点梳理 + 高频面试题.md.html">22 分布式服务考点梳理 + 高频面试题</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/23 读写分离如何在业务中落地?.md.html">23 读写分离如何在业务中落地?</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/24 为什么需要分库分表,如何实现?.md.html">24 为什么需要分库分表,如何实现?</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/25 存储拆分后,如何解决唯一主键问题?.md.html">25 存储拆分后,如何解决唯一主键问题?</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/26 分库分表以后,如何实现扩容?.md.html">26 分库分表以后,如何实现扩容?</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/27 NoSQL 数据库有哪些典型应用?.md.html">27 NoSQL 数据库有哪些典型应用?</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/28 ElasticSearch 是如何建立索引的?.md.html">28 ElasticSearch 是如何建立索引的?</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/29 分布式存储考点梳理 + 高频面试题.md.html">29 分布式存储考点梳理 + 高频面试题</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/30 消息队列有哪些应用场景?.md.html">30 消息队列有哪些应用场景?</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/31 集群消费和广播消费有什么区别?.md.html">31 集群消费和广播消费有什么区别?</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/32 业务上需要顺序消费,怎么保证时序性?.md.html">32 业务上需要顺序消费,怎么保证时序性?</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/33 消息幂等:如何保证消息不被重复消费?.md.html">33 消息幂等:如何保证消息不被重复消费?</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/34 高可用:如何实现消息队列的 HA.md.html">34 高可用:如何实现消息队列的 HA</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/35 消息队列选型Kafka 如何实现高性能?.md.html">35 消息队列选型Kafka 如何实现高性能?</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/36 消息队列选型RocketMQ 适用哪些场景?.md.html">36 消息队列选型RocketMQ 适用哪些场景?</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/37 消息队列考点梳理 + 高频面试题.md.html">37 消息队列考点梳理 + 高频面试题</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/38 不止业务缓存,分布式系统中还有哪些缓存?.md.html">38 不止业务缓存,分布式系统中还有哪些缓存?</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/39 如何避免缓存穿透、缓存击穿、缓存雪崩?.md.html">39 如何避免缓存穿透、缓存击穿、缓存雪崩?</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/40 经典问题:先更新数据库,还是先更新缓存?.md.html">40 经典问题:先更新数据库,还是先更新缓存?</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/41 失效策略:缓存过期都有哪些策略?.md.html">41 失效策略:缓存过期都有哪些策略?</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/42 负载均衡:一致性哈希解决了哪些问题?.md.html">42 负载均衡:一致性哈希解决了哪些问题?</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/43 缓存高可用:缓存如何保证高可用?.md.html">43 缓存高可用:缓存如何保证高可用?</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/44 分布式缓存考点梳理 + 高频面试题.md.html">44 分布式缓存考点梳理 + 高频面试题</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/45 从双十一看高可用的保障方式.md.html">45 从双十一看高可用的保障方式</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/46 高并发场景下如何实现系统限流?.md.html">46 高并发场景下如何实现系统限流?</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/47 降级和熔断:如何增强服务稳定性?.md.html">47 降级和熔断:如何增强服务稳定性?</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/48 如何选择适合业务的负载均衡策略?.md.html">48 如何选择适合业务的负载均衡策略?</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/49 线上服务有哪些稳定性指标?.md.html">49 线上服务有哪些稳定性指标?</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/50 分布式下有哪些好用的监控组件?.md.html">50 分布式下有哪些好用的监控组件?</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/51 分布式下如何实现统一日志系统?.md.html">51 分布式下如何实现统一日志系统?</a>
</li>
<li>
<a href="/专栏/分布式技术原理与实战45讲-完/52 分布式路漫漫,厚积薄发才是王道.md.html">52 分布式路漫漫,厚积薄发才是王道</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')
let content = document.querySelector('.off-canvas-content')
if (sidebar_toggle.classList.contains('extend')) { // show
sidebar_toggle.classList.remove('extend')
sidebar.classList.remove('hide')
content.classList.remove('extend')
} else { // hide
sidebar_toggle.classList.add('extend')
sidebar.classList.add('hide')
content.classList.add('extend')
}
}
function open_sidebar() {
let sidebar = document.querySelector('.book-sidebar')
let overlay = document.querySelector('.off-canvas-overlay')
sidebar.classList.add('show')
overlay.classList.add('show')
}
function hide_canvas() {
let sidebar = document.querySelector('.book-sidebar')
let overlay = document.querySelector('.off-canvas-overlay')
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">
<div class="book-navbar">
<!-- For Responsive Layout -->
<header class="navbar">
<section class="navbar-section">
<a onclick="open_sidebar()">
<i class="icon icon-menu"></i>
</a>
</section>
</header>
</div>
<div class="book-content" style="max-width: 960px; margin: 0 auto;
overflow-x: auto;
overflow-y: hidden;">
<div class="book-post">
<p id="tip" align="center"></p>
<div><h1>00 开篇词:搭建分布式知识体系,挑战高薪 Offer</h1>
<p>你好,我是邴越,在一线互联网公司从事分布式开发工作多年,一直关注分布式理论和新技术的发展。</p>
<p>互联网发展到今天,用户数量越来越多,产生的数据规模也越来越大,应用系统必须支持高并发访问和海量数据处理的需求。</p>
<p>对比集中式架构,分布式系统由于具有可扩展性,可以动态扩展服务和存储节点,使用廉价的机器构建高性能的服务,更适合如今的互联网业务。分布式系统技术已经成为微服务架构、大数据、云计算等技术领域的基石,在电商、互联网金融、支付等众多业务中,都离不开分布式技术的有效运用。</p>
<p>掌握分布式技能的后端工程师越来越抢手,不止业务部门、中间件和基础架构等部门也在大规模抢人。分布式技术的应用越来越广泛,各大公司的相关岗位要求也越来越高,然而在面试和工作中,我们却看到各种各样的问题:</p>
<ul>
<li>面试时,可以回答概念性的问题,但问到实质性问题时就懵了,由于缺少相关经验而卡住;</li>
<li>工作中对常用分布式技术的原理一知半解,在典型场景下可以应付,但稍微变更业务场景或业务目标后,就开始毫无头绪;</li>
<li>系统设计中,没有全面平衡各个设计点,关注了收益,却没考虑到风险,比如增加了缓存,却带来了数据不一致,增加了消息队列,却因为不合理的重试导致服务异常。</li>
</ul>
<p>总结来说,这往往是从业者没有在实际的分布式业务场景中实践过,或者对分步式技术缺乏体系化的认知,或者对一些原理和底层的内容未曾深入研究,导致可以解决常见问题,而没有系统化的解决思路。</p>
<p>因此,<strong>我梳理了一套分布式技术的方法论,希望可以帮助你快速而体系化地补齐分布式知识</strong>。此外,一路走来,我在分布式系统设计中踩过的坑,在开发实践中看到和经历过的一些典型问题,也将在这里一并分享给你,希望能够帮到更多开发者,并减轻你学习分布式的畏难心理。</p>
<h3>分布式是工程师进阶的必经之路</h3>
<p>经常听到一些开发人员,在工作之余感叹自己职业发展的困惑与焦虑,比如每天写业务代码,如何摆脱 CRUD Boy 的标签,去提升技术能力?一直在传统企业工作,怎么才能加入 BAT 等大公司?所有的机遇都是在充分准备后才能获得的,这些问题的关键,就是你在技术上的持续精进。</p>
<p><img src="assets/Ciqah16ERqmAE-qtAAJ5c5hckiA055.png" alt="img" /></p>
<p>**如果想在技术线上深耕和谋求发展,成为高级工程师、资深工程师或者架构师,**<strong>掌握分布式系统知识已经成为了必要的一环</strong>。不管是目前流行的 SOA 架构,还是蓬勃发展的微服务和 Serverless 架构,都是在分布式的基础上构建的,业务开发中的框架选型、注册中心,以及服务拆分之后面临的分布式事务问题、分布式锁,也都是分布式系统所关注的。</p>
<h3>想要高薪 Offer必须掌握分布式</h3>
<p>要想进入大公司并拿到高薪 Offer分布式技术也是一个很好的敲门砖。大型互联网公司每天都要面对海量的业务请求处理各种复杂的系统问题是工作常态所以需要应聘人员掌握常用的分布式技术并在面试过程中重点考察你对分布式系统的理解和经验水平。</p>
<p>针对<strong>高级岗位</strong>,除了掌握在分布式环境下进行开发的能力,你还需要了解其中的原理、机制,以便能够快速定位线上问题;而对于<strong>架构师</strong>来说,你还需要具备独立设计分布式系统的能力,这就需要了解高并发、高可用的相关知识了。</p>
<p><strong>在****拉勾网上搜索后端工程师的招聘岗位,可以看到很多岗位都要求掌握缓存、分布式服务、消息队列等分布式组件应用,部分岗位还要求在高并发等分布式设计方向有一定的积累。</strong></p>
<p><img src="assets/Ciqah16FzVKAUHomABFJwSsmtFg192.png" alt="img" /></p>
<p>结合拉勾对海量招聘启事的大数据分析,我们也总结出了后端开发者在面试中要求<strong>掌握的分布式技能点</strong>,同时也把它们融入到了课程设计中:</p>
<ul>
<li>分布式系统理论和设计;</li>
<li>分布式事务和一致性;</li>
<li>分布式服务及微服务架构;</li>
<li>分布式缓存和常见 NoSQL 应用;</li>
<li>分布式下数据库的拆分,比如读写分离、分库分表;</li>
<li>消息中间件的应用,常见组件的选型;</li>
<li>合理应用分布式技术,实现系统的高可用。</li>
</ul>
<p><img src="assets/Cgq2xl6ERqmAEq1kAAENcRtXEvU094.png" alt="img" /></p>
<h3>难点不难,给你学得会的分布式课程</h3>
<p>分布式系统在工作和面试中如此重要,但是掌握起来并不容易。</p>
<ul>
<li><strong>理论众多、难以入手。<strong>分布式系统不仅涉及一致性、事务等众多的理论知识,还包括非常多的复杂算法,比如 Paxos 和 Zab 算法,如果</strong>没有一个明确的抓手</strong><strong>学习起来会很吃力</strong></li>
<li><strong>领域庞杂、关联技术栈多。<strong>分布式系统涉及很多领域,比如 RPC 服务调用、分库分表,这些不同的领域需要了解和掌握不同的技术栈。因此我的建议是,要想快速提升分布式技术能力,那么</strong>需要明确哪些才是你日常工作中最迫切需要的</strong>,从实践中开始体验和学习,积累经验。要知道,分布式不是一堆理论的堆砌,而是和日常开发息息相关。</li>
<li><strong>工作特点,接触不到分布式</strong>**。<strong>鉴于现在一些软件开发公司,或者传统公司的 IT 部门,还在使用集中式系统架构,所以部分开发者平时在工作中很少接触分布式系统,因此,我在这个课程中,将会侧重</strong>讲解很多实际场景的实践内容**,以帮助你更有效地掌握分布式。</li>
</ul>
<p>工作多年,我从一个初入行的新人,一步步晋升一线互联网公司的核心业务负责人,我深知分布式知识的重要性和学习痛点,为了让你在短时间内能够快速掌握分布式知识,我对这门课程进行了精心设计。</p>
<p><strong>1知识体系化快速学习</strong></p>
<p>碎片化知识很难有效学习,体系化的学习才是重点。分布式系统知识足够庞杂,本课程从理论开始,一步一步落地到实践中,帮助你快速构建知识框架,让你对分布式技术有个总体的认知。</p>
<p><img src="assets/Ciqah16ERqmAGJjpAACXHV15Oyg347.png" alt="img" /></p>
<p><strong>2选取最常用的知识点</strong></p>
<p>分布式系统博大精深,但并不是每个人都在做基础架构研发,也不是每一项技术都能直接落地,因而本课程选取了在工程开发中最常用的技术栈,比如在分布式服务模块中选取了网关、注册中心、容器化等内容来讲解,在数据库模块中选择了读写分离、分库分表等内容,这些都是在开发中打交道最多的知识点。</p>
<p><strong>3拒绝空谈理论结合实际业务场景</strong></p>
<p>技术是为业务服务的,再高深的技术都要落地,我们的课程内容不是干巴巴的讲理论,而是结合了实际业务场景,带着问题去讲解,让你能够在实际的场景中理解并应用,达到事半功倍的效果。</p>
<p><strong>4面试真题解析帮你赢取高薪 Offer</strong></p>
<p>为了帮助你更好地准备面试,每个模块后面都附上了一个“<strong>加餐</strong>”内容,并梳理出了面试中经常出现的考点,以及高频面试真题。虽然是加餐,但是内容绝对有料。</p>
<p>当然,快速通关面试只是我们的目标之一,我更希望你在这个课程中,真正学有所得,将知识和经验融入到个人能力中,做一些长期主义的事情。</p>
<h3>课程设计</h3>
<p>本课程分为 7 个模块,共 45 讲。我将从实际工作和面试出发,从分布式理论开始带你建立知识框架,然后逐个攻破分布式技术的各个核心技术领域。为了让你更清晰地了解本课程中的所有知识点,我还准备了一份思维导图:</p>
<p><img src="assets/Cgq2xl6ERqmAdmMXAAMdZN_Jn7I815.png" alt="img" /></p>
<ul>
<li>**分布式基础:**扎实的理论是进一步学习分布式知识的钥匙,这一模块将详解分布式的概念,包括 CAP 和 Base 理论、各种数据一致性模型,以及两阶段和三阶段提交协议等。</li>
<li>**分布式事务:**在电商、金融等业务中都涉及资金往来,事务非常重要,那么分布式事务如何解决、分布式锁如何实现、……,这一模块将会解答。</li>
<li>**分布式服务:**分布式服务是微服务架构的必要条件,这一模块将讲解如何解决服务拆分后的一系列问题,比如 RPC、网关、注册中心等。</li>
<li>**分布式存储:**系统架构拆分以后,存储层面的拆分同样重要,数据库层涉及读写分离、分库分表等,这一模块我们来一起来探究这些技术的原理,以及如何在业务中落地。</li>
<li>**消息队列:**消息中间件是分布式系统架构的整合剂,这一模块将分享消息队列使用的常见问题,比如重复消费、消息时序等。</li>
<li><strong>分布式缓存:</strong> 缓存的高性能在分布式系统中发挥了更加重要的作用,那么分布式缓存有哪些分类,以及有哪些经典问题,这一模块我们来一起探究。</li>
<li>**分布式高可用:**高可用是工程师始终追求的目标,最后这个模块,我将会为你分享在分布式系统中如何保障系统可用性,如何做好系统监控和限流降级。</li>
</ul>
</div>
</div>
<div>
<div style="float: right">
<a href="/专栏/分布式技术原理与实战45讲-完/01 如何证明分布式系统的 CAP 理论?.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":"7099768dee463cfa","version":"2021.12.0","r":1,"token":"1f5d475227ce4f0089a7cff1ab17c0f5","si":100}' crossorigin="anonymous"></script>
</body>
<!-- Global site tag (gtag.js) - Google Analytics -->
<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
var cookie = getCookie("lastPath");
console.log(path)
if (path.replace("/", "") === "") {
if (cookie.replace("/", "") !== "") {
console.log(cookie)
document.getElementById("tip").innerHTML = "<a href='" + cookie + "'>跳转到上次进度</a>"
}
} 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(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i].trim();
if (c.indexOf(name) === 0) return c.substring(name.length, c.length);
}
return "";
}
</script>
</html>