learn.lianglianglee.com/专栏/重学操作系统-完/12 (1)加餐 练习题详解(二).md.html
2022-05-11 18:57:05 +08:00

1117 lines
29 KiB
HTML
Raw Permalink 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>12 (1)加餐 练习题详解(二).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 href="/专栏/重学操作系统-完/00 开篇词 为什么大厂面试必考操作系统?.md.html">00 开篇词 为什么大厂面试必考操作系统?.md.html</a>
</li>
<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 程序的执行:相比 32 位64 位的优势是什么?(上).md.html">02 程序的执行:相比 32 位64 位的优势是什么?(上).md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/03 程序的执行:相比 32 位64 位的优势是什么?(下).md.html">03 程序的执行:相比 32 位64 位的优势是什么?(下).md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/04 构造复杂的程序:将一个递归函数转成非递归函数的通用方法.md.html">04 构造复杂的程序:将一个递归函数转成非递归函数的通用方法.md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/05 存储器分级L1 Cache 比内存和 SSD 快多少倍?.md.html">05 存储器分级L1 Cache 比内存和 SSD 快多少倍?.md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/05 (1) 加餐 练习题详解(一).md.html">05 (1) 加餐 练习题详解(一).md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/06 目录结构和文件管理指令rm -rf 指令的作用是?.md.html">06 目录结构和文件管理指令rm -rf 指令的作用是?.md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/07 进程、重定向和管道指令xargs 指令的作用是?.md.html">07 进程、重定向和管道指令xargs 指令的作用是?.md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/08 用户和权限管理指令: 请简述 Linux 权限划分的原则?.md.html">08 用户和权限管理指令: 请简述 Linux 权限划分的原则?.md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/09 Linux 中的网络指令:如何查看一个域名有哪些 NS 记录?.md.html">09 Linux 中的网络指令:如何查看一个域名有哪些 NS 记录?.md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/10 软件的安装: 编译安装和包管理器安装有什么优势和劣势?.md.html">10 软件的安装: 编译安装和包管理器安装有什么优势和劣势?.md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/11 高级技巧之日志分析:利用 Linux 指令分析 Web 日志.md.html">11 高级技巧之日志分析:利用 Linux 指令分析 Web 日志.md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/12 高级技巧之集群部署:利用 Linux 指令同时在多台机器部署程序.md.html">12 高级技巧之集群部署:利用 Linux 指令同时在多台机器部署程序.md.html</a>
</li>
<li>
<a class="current-tab" href="/专栏/重学操作系统-完/12 (1)加餐 练习题详解(二).md.html">12 (1)加餐 练习题详解(二).md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/13 操作系统内核Linux 内核和 Windows 内核有什么区别?.md.html">13 操作系统内核Linux 内核和 Windows 内核有什么区别?.md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/14 用户态和内核态:用户态线程和内核态线程有什么区别?.md.html">14 用户态和内核态:用户态线程和内核态线程有什么区别?.md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/15 中断和中断向量Javajs 等语言为什么可以捕获到键盘输入?.md.html">15 中断和中断向量Javajs 等语言为什么可以捕获到键盘输入?.md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/16 WinMacUnixLinux 的区别和联系:为什么 Debian 漏洞排名第一还这么多人用?.md.html">16 WinMacUnixLinux 的区别和联系:为什么 Debian 漏洞排名第一还这么多人用?.md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/16 (1)加餐 练习题详解(三).md.html">16 (1)加餐 练习题详解(三).md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/17 进程和线程:进程的开销比线程大在了哪里?.md.html">17 进程和线程:进程的开销比线程大在了哪里?.md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/18 锁、信号量和分布式锁:如何控制同一时间只有 2 个线程运行?.md.html">18 锁、信号量和分布式锁:如何控制同一时间只有 2 个线程运行?.md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/19 乐观锁、区块链:除了上锁还有哪些并发控制方法?.md.html">19 乐观锁、区块链:除了上锁还有哪些并发控制方法?.md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/20 线程的调度:线程调度都有哪些方法?.md.html">20 线程的调度:线程调度都有哪些方法?.md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/21 哲学家就餐问题:什么情况下会触发饥饿和死锁?.md.html">21 哲学家就餐问题:什么情况下会触发饥饿和死锁?.md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/22 进程间通信: 进程间通信都有哪些方法?.md.html">22 进程间通信: 进程间通信都有哪些方法?.md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/23 分析服务的特性:我的服务应该开多少个进程、多少个线程?.md.html">23 分析服务的特性:我的服务应该开多少个进程、多少个线程?.md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/23 (1)加餐 练习题详解(四).md.html">23 (1)加餐 练习题详解(四).md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/24 虚拟内存 :一个程序最多能使用多少内存?.md.html">24 虚拟内存 :一个程序最多能使用多少内存?.md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/25 内存管理单元: 什么情况下使用大内存分页?.md.html">25 内存管理单元: 什么情况下使用大内存分页?.md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/26 缓存置换算法: LRU 用什么数据结构实现更合理?.md.html">26 缓存置换算法: LRU 用什么数据结构实现更合理?.md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/27 内存回收上篇:如何解决内存的循环引用问题?.md.html">27 内存回收上篇:如何解决内存的循环引用问题?.md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/28 内存回收下篇:三色标记-清除算法是怎么回事?.md.html">28 内存回收下篇:三色标记-清除算法是怎么回事?.md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/28 (1)加餐 练习题详解(五).md.html">28 (1)加餐 练习题详解(五).md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/29 Linux 下的各个目录有什么作用?.md.html">29 Linux 下的各个目录有什么作用?.md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/30 文件系统的底层实现FAT、NTFS 和 Ext3 有什么区别?.md.html">30 文件系统的底层实现FAT、NTFS 和 Ext3 有什么区别?.md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/31 数据库文件系统实例MySQL 中 B 树和 B+ 树有什么区别?.md.html">31 数据库文件系统实例MySQL 中 B 树和 B+ 树有什么区别?.md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/32 HDFS 介绍:分布式文件系统是怎么回事?.md.html">32 HDFS 介绍:分布式文件系统是怎么回事?.md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/32 (1)加餐 练习题详解(六).md.html">32 (1)加餐 练习题详解(六).md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/33 互联网协议群TCPIP多路复用是怎么回事.md.html">33 互联网协议群TCPIP多路复用是怎么回事.md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/34 UDP 协议UDP 和 TCP 相比快在哪里?.md.html">34 UDP 协议UDP 和 TCP 相比快在哪里?.md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/35 Linux 的 IO 模式selectpollepoll 有什么区别?.md.html">35 Linux 的 IO 模式selectpollepoll 有什么区别?.md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/36 公私钥体系和网络安全:什么是中间人攻击?.md.html">36 公私钥体系和网络安全:什么是中间人攻击?.md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/36 (1)加餐 练习题详解(七).md.html">36 (1)加餐 练习题详解(七).md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/37 虚拟化技术介绍VMware 和 Docker 的区别?.md.html">37 虚拟化技术介绍VMware 和 Docker 的区别?.md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/38 容器编排技术:如何利用 K8s 和 Docker Swarm 管理微服务?.md.html">38 容器编排技术:如何利用 K8s 和 Docker Swarm 管理微服务?.md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/39 Linux 架构优秀在哪里.md.html">39 Linux 架构优秀在哪里.md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/40 商业操作系统:电商操作系统是不是一个噱头?.md.html">40 商业操作系统:电商操作系统是不是一个噱头?.md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/40 (1)加餐 练习题详解(八).md.html">40 (1)加餐 练习题详解(八).md.html</a>
</li>
<li>
<a href="/专栏/重学操作系统-完/41 结束语 论程序员的发展——信仰、选择和博弈.md.html">41 结束语 论程序员的发展——信仰、选择和博弈.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')
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>12 (1)加餐 练习题详解(二)</h1>
<p>今天我会带你把《模块二Linux 指令》中涉及的课后练习题,逐一讲解,并给出每个课时练习题的解题思路和答案。</p>
<h3>练习题详解</h3>
<h4>06 | 目录结构和文件管理指令rm / -rf 指令的作用是?</h4>
<p><strong>【问题】</strong> 搜索文件系统中所有以包含 <code>std</code>字符串且以<code>.h</code>扩展名结尾的文件。</p>
<p><strong>【解析】</strong> 这道题目比较简单,大家也比较活跃,我自己只写了一种方法,没想到留言中有挺多不错的方案,那我们一起来看下。</p>
<p>下面是我的方案,你学完模块二的内容后,应该知道查看全部文件需要<code>sudo</code>,以管理员身份:</p>
<pre><code>sudo find / -name &quot;*std*.h&quot;
</code></pre>
<p>我在留言中看到有的同学用的是<code>-iname</code>,这样也是可以的,只是忽略了大小写。</p>
<p>也可以结合 grep 语句, 用管道实现,比如:</p>
<pre><code>sudo find / -name &quot;*.h&quot; |grep std
</code></pre>
<h4>07 | 进程、重定向和管道指令xargs 指令的作用是?</h4>
<p><strong>【问题】</strong> 请问下面这段 Shell 程序的作用是什么?</p>
<pre><code>mkfifo pipe1
mkfifo pipe2
echo -n run | cat - pipe1 &gt; pipe2 &amp;
cat &lt; pipe2 &gt; pipe1
</code></pre>
<p><strong>【解析】</strong> 这个题目是我在网上看到的一个比较有趣的问题。</p>
<p>前 2 行代码创建了两个管道文件。</p>
<p>从第 3 行开始,代码变得复杂。<code>echo -n run</code>就是向输出流中写入一个<code>run</code>字符串(不带回车,所以用<code>-n</code>)。通过管道,将这个结果传递给了<code>cat</code><code>cat</code>是 concatenate 的缩写,意思是把文件粘在一起。</p>
<ul>
<li><code>cat</code><code>&gt;</code>重定向输出到一个管道文件时,如果没有其他进程从管道文件中读取内容,<code>cat</code>会阻塞。</li>
<li><code>cat</code><code>&lt;</code>读取一个管道内容时,如果管道中没有输入,也会阻塞。</li>
</ul>
<p>从这个角度来看,总共有 3 次重定向:</p>
<ul>
<li><code>-</code>也就是输入流的内容和<code>pipe1</code>内容合并重定向到<code>pipe2</code></li>
<li><code>pipe2</code>内容重定向到<code>cat</code></li>
<li><code>cat</code>的内容重定向到<code>pipe1</code></li>
</ul>
<p>仔细观察下路径:<code>pipe1</code>-&gt;<code>pipe2</code>-&gt;<code>pipe1</code>,构成了一个循环。 这样导致管道<code>pipe1</code>管道<code>pipe2</code>中总是有数据(没有数据的时间太短)。于是,就构成了一个无限循环。我们打开执行这个程序后,可以用<code>htop</code>查看当前的 CPU 使用情况,会发现 CPU 占用率很高。</p>
<h4>08 | 用户和权限管理指令: 请简述 Linux 权限划分的原则?</h4>
<p><strong>【问题】</strong> 如果一个目录是只读权限,那么这个目录下面的文件还可写吗?</p>
<p><strong>【解析】</strong> 这类问题,你一定要去尝试,观察现象再得到结果。</p>
<p><img src="assets/Ciqc1F-JYOSAEeZOAAK-jHkfQpk505.png" alt="Drawing 0.png" /></p>
<p>你可以看到上图中foo 目录不可读了,下面的<code>foo/bar</code>文件还可以写。 即便它不可写了,下面的<code>foo/bar</code>文件还是可以写。</p>
<p><img src="assets/Ciqc1F-JYOuACHgqAADld0-OED0560.png" alt="Drawing 1.png" /></p>
<p>但是想要创建新文件就会出现报错,因为创建新文件也需要改目录文件。这个例子说明 Linux 中的文件内容并没有存在目录中,目录中却有文件清单。</p>
<h4>09 | Linux 中的网络指令:如何查看一个域名有哪些 NS 记录?</h4>
<p><strong>【问题】</strong> 如何查看正在 TIME_WAIT 状态的连接数量?</p>
<p><strong>【解析】</strong> 注意,这里有个小坑,就是 netstat 会有两行表头,这两行可以用 tail 过滤掉,下面<code>tail -n +3</code>就是告诉你 tail 从第 3 行开始显示。<code>-a</code>代表显示所有的 socket。</p>
<pre><code>netstat -a | tail -n +3 | wc -l
</code></pre>
<h4>10 | 软件的安装: 编译安装和包管理器安装有什么优势和劣势?</h4>
<p><strong>【问题】</strong> 如果你在编译安装 MySQL 时发现找不到libcrypt.so ,应该如何处理?</p>
<p><strong>【解析】</strong> 遇到这类问题,首先应该去查资料。 比如查 StackOverflow搜索关键词libcrypt.so not found或者带上自己的操作系统<code>ubuntu</code>。下图是关于 Stackoverflow 的一个解答:</p>
<p><img src="assets/Ciqc1F-JYUSACvI4AABGKWEIwZc693.png" alt="Drawing 2.png" /></p>
<p>在这里我再多说两句,程序员成长最需要的是学习时间,如果在这前面加一个形容词,那就是大量的学习时间;而程序员最需要掌握的技能就是搜索和学习知识的能力。如果你看到今天的这篇内容,说明已经学完了《重学操作系统》专栏两个模块的知识,希望你可以坚持下去!</p>
<h4>11 | 高级技巧之日志分析:利用 Linux 指令分析 Web 日志</h4>
<p><strong>【问题 1 】</strong> 根据今天的 access_log 分析出有哪些终端访问了这个网站,并给出分组统计结果。</p>
<p><strong>【解析】</strong><code>access_log</code>中有<code>Debian</code><code>Ubuntu</code>等等。我们可以利用下面的指令看到,第 12 列是终端,如下图所示:</p>
<p><img src="assets/Ciqc1F-JYVKAeXxWAAFX4ed-XgU367.png" alt="Drawing 3.png" /></p>
<p>我们还可以使用<code>sort</code><code>uniq</code>查看有哪些终端,如下图所示:</p>
<p><img src="assets/Ciqc1F-JYVqABf8YAAJ8F9oyYEk538.png" alt="Drawing 4.png" /></p>
<p>最后需要写一个脚本,进行统计:</p>
<pre><code>cat nginx_logs.txt |\
awk '{tms[$12]++;next}END{for (t in tms) print t, tms[t]}'
</code></pre>
<p>结果如下:</p>
<p><img src="assets/CgqCHl-JYWCAQ5S7AALOO3VxYyE532.png" alt="Drawing 5.png" /></p>
<p><strong>【问题 2】</strong> 根据今天的 access_log 分析出访问量 Top 前三的网页。</p>
<p>如果不需要 Substring 等复杂的处理,也可以使用<code>sort</code><code>uniq</code>的组合。如下图所示:</p>
<p><img src="assets/CgqCHl-JYWmASpWzAAHX7u4P8x4076.png" alt="Drawing 6.png" /></p>
<h4>12 | 高级技巧之集群部署:利用 Linux 指令同时在多台机器部署程序</h4>
<p><strong>【问题】</strong>~/.bashrc ~/.bash_profile, ~/.profile 和 /etc/profile 的区别是什么?</p>
<p><strong>【解析】</strong> 执行一个 shell 的时候分成<strong>login shell</strong><strong>non-login shell</strong>。顾名思义我们使用了<code>sudo``su</code>切换到某个用户身份执行 shell也就是<code>login shell</code>。还有 ssh 远程执行指令也是 login shell也就是伴随登录的意思——<code>login shell</code> 会触发很多文件执行,路径如下:</p>
<p><img src="assets/CgqCHl-M_a2AB4DCAABaALYsBvA370.png" alt="Lark20201019-104257.png" /></p>
<p>如果以当前用户身份正常执行一个 shell比如说<code>./a.sh</code>,就是一个<code>non-login</code>的模式。 这时候不会触发上述的完整逻辑。</p>
<p>另外shell还有另一种分法就是<code>interactive</code><code>non-interactive</code>。interactive 是交互式的意思,当用户打开一个终端命令行工具后,会进入一个输入命令得到结果的交互界面,这个时候,就是<code>interactive shell</code></p>
<p><code>baserc</code>文件通常只在<code>interactive</code>模式下才会执行,这是因为<code>~/.bashrc</code>文件中通常有这样的语句,如下图所示:</p>
<p><img src="assets/CgqCHl-JYZmAU3eiAADOD88ztPA917.png" alt="Drawing 7.png" /></p>
<p>这个语句通过<code>$-</code>看到当前<code>shell</code>的执行环境,如下图所示:</p>
<p><img src="assets/Ciqc1F-JYZ-AKItgAABi7Cu95fc751.png" alt="Drawing 8.png" /></p>
<p>带 i 字符的就是<code>interactive</code>没有带i字符就不是。</p>
<p>因此, 如果你需要通过 ssh 远程 shell 执行一个文件,你就不是在 interactive 模式下bashrc 不会触发。但是因为登录的原因login shell 都会触发,也就是说 profile 文件依然会执行。</p>
<h3>总结</h3>
<p>这个模块我们学习了 Linux 指令。我带大家入了个门,也和你一起感受了一次 Linux 指令的博大精深。Linux 虽然没有上下五千年的历史,但每次使用,依然让我感受到了它浓郁的历史气息,悠久的文化传承,自由的创造精神。希望这块知识可以陪伴大家,鼓励你成为优秀的程序员。虽然我们已经学了几十个指令,但还是沧海一粟。后续就需要你多查资料,多用<code>man</code>手册,继续深造了。</p>
<p>好的Linux 指令部分就告一段落。下一节课,我们将开启操作系统核心知识学习,请和我一起来学习“模块三:操作系统基础知识”吧。</p>
</div>
</div>
<div>
<div style="float: left">
<a href="/专栏/重学操作系统-完/12 高级技巧之集群部署:利用 Linux 指令同时在多台机器部署程序.md.html">上一页</a>
</div>
<div style="float: right">
<a href="/专栏/重学操作系统-完/13 操作系统内核Linux 内核和 Windows 内核有什么区别?.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":"70997d64a8253cfa","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>