-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcontent.json
More file actions
1 lines (1 loc) · 79.2 KB
/
content.json
File metadata and controls
1 lines (1 loc) · 79.2 KB
1
{"meta":{"title":"wkaanig的个人博客","subtitle":"Hugking","description":"相信奇迹的人本身就和奇迹一样了不起","author":"wkaanig","url":"http://blog.wkaanig.cn","root":"/"},"pages":[{"title":"404 Not Found:该页无法显示","date":"2019-09-10T10:43:12.545Z","updated":"2019-09-10T10:43:12.545Z","comments":false,"path":"/404.html","permalink":"http://blog.wkaanig.cn//404.html","excerpt":"","text":""},{"title":"关于","date":"2019-09-10T10:43:12.552Z","updated":"2019-09-10T10:43:12.552Z","comments":false,"path":"about/index.html","permalink":"http://blog.wkaanig.cn/about/index.html","excerpt":"","text":"个人详细介绍"},{"title":"书单","date":"2019-09-10T10:43:12.555Z","updated":"2019-09-10T10:43:12.555Z","comments":false,"path":"books/index.html","permalink":"http://blog.wkaanig.cn/books/index.html","excerpt":"","text":""},{"title":"分类","date":"2019-10-08T10:10:45.514Z","updated":"2019-10-08T10:10:45.514Z","comments":false,"path":"categories/index.html","permalink":"http://blog.wkaanig.cn/categories/index.html","excerpt":"","text":""},{"title":"相册","date":"2019-10-04T07:17:23.000Z","updated":"2019-10-04T07:18:13.465Z","comments":true,"path":"gallery/index.html","permalink":"http://blog.wkaanig.cn/gallery/index.html","excerpt":"","text":""},{"title":"友情链接","date":"2019-09-10T10:43:12.561Z","updated":"2019-09-10T10:43:12.561Z","comments":true,"path":"links/index.html","permalink":"http://blog.wkaanig.cn/links/index.html","excerpt":"","text":""},{"title":"","date":"2019-09-10T11:27:51.363Z","updated":"2019-09-10T11:27:51.363Z","comments":true,"path":"links/links.json","permalink":"http://blog.wkaanig.cn/links/links.json","excerpt":"","text":"{\"Name\":{\"link\":\"http://docs.wkaanig,cn\",\"avatar\":\"http://example.com/avatar.png\",\"desc\":\"这是一个描述\"}}"},{"title":"Repositories","date":"2019-09-10T10:43:12.565Z","updated":"2019-09-10T10:43:12.565Z","comments":false,"path":"repository/index.html","permalink":"http://blog.wkaanig.cn/repository/index.html","excerpt":"","text":""},{"title":"标签","date":"2020-04-17T18:13:21.672Z","updated":"2020-04-17T18:13:21.672Z","comments":false,"path":"tags/index.html","permalink":"http://blog.wkaanig.cn/tags/index.html","excerpt":"","text":""}],"posts":[{"title":"前端面试知识(Js篇)","slug":"前端面试知识(js篇)","date":"2020-04-18T08:28:10.000Z","updated":"2020-04-21T16:52:48.119Z","comments":true,"path":"post/7ce2f84d.html","link":"","permalink":"http://blog.wkaanig.cn/post/7ce2f84d.html","excerpt":"","text":"JavaScript 原型链 事件流事件流描述的是从页面中接收事件的顺序,DOM2级事件流包括下面几个阶段。事件捕获阶段-处于目标阶段事件冒泡阶段addEventListener:addEventListener 是DOM2 级事件新增的指定事件处理程序的操作,这个方法接收3个参数:要处理的事件名、作为事件处理程序的函数和一个布尔值。最后这个布尔值参数如果是true,表示在捕获阶段调用事件处理程序;如果是false,表示在冒泡阶段调用事件处理程序。 图片的懒加载和预加载预加载:提前加载图片,当用户需要查看时可直接从本地缓存中渲染。懒加载:懒加载的主要目的是作为服务器前端的优化,减少请求数或延迟请求数。两种技术的本质:两者的行为是相反的,一个是提前加载,一个是迟缓甚至不加载。懒加载对服务器前端有一定的缓解压力作用,预加载则会增加服务器前端压力。 改变函数内部this指针的指向函数(bind,apply,call的区别)通过apply和call改变函数的this指向,他们两个函数的第一个参数都是一样的表示要改变指向的那个对象,第二个参数,apply是数组,而call则是arg1,arg2…这种形式。通过bind改变this作用域会返回一个新的函数,这个函数不会马上执行。 Ajax解决浏览器缓存问题在ajax发送请求前加上 anyAjaxObj.setRequestHeader(“If-Modified-Since”,“0”)。在ajax发送请求前加上 anyAjaxObj.setRequestHeader(“Cache-Control”,“no-cache”)。在URL后面加上一个随机数: “fresh=” + Math.random()。在URL后面加上时间戳:“nowtime=” + new Date().getTime()。如果是使用jQuery,直接这样就可以了 $.ajaxSetup({cache:false})。这样页面的所有ajax都会执行这条语句就是不需要保存缓存记录。 js的节流和防抖防抖动:防抖技术即是可以把多个顺序地调用合并成一次,也就是在一定时间内,规定事件被触发的次数。节流函数:只允许一个函数在 X 毫秒内执行一次,只有当上一次函数执行后过了你规定的时间间隔,才能进行下一次该函数的调用。rAF:16.7ms 触发一次 handler,降低了可控性,但是提升了性能和精确度。 将原生的ajax封装成promise12345678910111213141516var myNewAjax=function(url){ return new Promise(function(resolve,reject){ var xhr = new XMLHttpRequest(); xhr.open('get',url); xhr.send(data); xhr.onreadystatechange=function(){ if(xhr.status==``200``&&readyState==``4``){ var json=JSON.parse(xhr.responseText); resolve(json) } else if(xhr.readyState==``4``&&xhr.status!=``200``){ reject(``'error'``); } } })} Job queue中的执行顺序script(主程序代码)—>process.nextTick—>Promises…——>setTimeout——>setInterval——>setImmediate——> I/O——>UI rendering例1:12345678910111213setTimeout(function(){console.log(1)},0);new Promise(function(resolve,reject){ console.log(2); setTimeout(function(){resolve()},0)}).then(function(){console.log(3)}).then(function(){console.log(4)});process.nextTick(function(){console.log(5)});console.log(6);//输出的是 2 6 5 1 3 4promise的构造中,没有同步的resolve,因此promise.then在当前的执行队列中是不存在的,只有promise从pending转移到resolve,才会有then方法,而这个resolve是在一个setTimout时间中完成的,因此3,4最后输出。例2:123456789101112setTimeout(function(){console.log(1)},0);new Promise(function(resolve,reject){ console.log(2); resolve();}).then(function(){console.log(3)}).then(function(){console.log(4)});process.nextTick(function(){console.log(5)});console.log(6);//输出2,6,5,3,4,1在定义promise的时候,promise构造部分是同步执行的,这样问题就迎刃而解了。","categories":[{"name":"前端","slug":"前端","permalink":"http://blog.wkaanig.cn/categories/前端/"}],"tags":[{"name":"js","slug":"js","permalink":"http://blog.wkaanig.cn/tags/js/"}]},{"title":"前端面试知识(Css篇)","slug":"前端面试知识(CSS篇)","date":"2020-04-17T12:14:48.000Z","updated":"2020-04-21T16:56:47.125Z","comments":true,"path":"post/71c59ada.html","link":"","permalink":"http://blog.wkaanig.cn/post/71c59ada.html","excerpt":"","text":"CSS3 css 盒模型box-sizing(有3个值):border-box,padding-box,content-box.标准盒子模型:IE盒子模型: flex 布局 (弹性布局 详见flex)display + position +floato12345678.box{ display:flex; display: inline-flex;/*行内元素*/ display: -webkit-flex; /* Safari */ display: flex;}容器属性12345678.box{ flex-direction:row | row-reverse | column | column-reverse; flex-wrap: nowrap | wrap | wrap-reverse; flex-flow: <flex-direction> || <flex-wrap>; justify-content: flex-start | flex-end | center | space-between | space-around; align-items: flex-start | flex-end | center | baseline | stretch; align-content: flex-start | flex-end | center | space-between | space-around | stretch;}项目属性1234567.item{ flex-grow: <number>; /* default 0 放大*/ flex-shrink: <number>; /* default 1 缩小*/ flex-basis: <length> | auto; /* default auto */ flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ];/*一般值为 auto (1 1 auto) 和 none (0 0 auto)*/ align-self: auto | flex-start | flex-end | center | baseline | stretch;} BFC (块级格式化上下文,清除浮动,防止margin重叠)123456这些元素会生成BFC:根元素float不为none的元素position为fixed和absolute的元素display为inline-block、table-cell、table-caption,flex,inline-flex的元素overflow不为visible的元素多行元素的文本省略号123456.box{ display: -webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:3; overflow:hidden;} 浮动清除(详见清除浮动)在浮动元素后使用一个空元素如,并在CSS中赋予.clear{clear:both;}属性给浮动元素的容器添加overflow:hidden;或overflow:auto;给浮动元素的容器也添加上浮动属性即可清除内部浮动什么都不做,给浮动元素后面的元素添加clear属性给浮动元素的容器添加一个clearfix的class,然后给这个class添加一个:after伪元素实现元素末尾添加一个看不见的块元素 CSS3 新特性(详见css3)边框123border-radius:CSS3圆角边框。在 CSS2 中添加圆角矩形需要技巧,我们必须为每个圆角使用不同的图片,在 CSS3 中,创建圆角是非常容易的,在 CSS3 中,border-radius 属性用于创建圆角。border:2px solid;box-shadow:CSS3边框阴影。在 CSS3 中,box-shadow 用于向方框添加阴影。box-shadow:10px 10px 5px #888888;border-image:CSS3边框图片。通过 CSS3 的 border-image 属性,您可以使用图片来创建边框。border-image:url(border.png) 30 30 round;背景12background-size: 属性规定背景图片的尺寸background-origin :属性规定背景图片的定位区域文字12text-shadow:在 CSS3 中,text-shadow 可向文本应用阴影。text-shadow:5px 5px 5px #FFFFFF;word-wrap :允许对长单词进行拆分,并换行:p{word-wrap:break-word;}2D转换( transform)1234567891011translate():元素从其当前位置移动,根据给定的 left(x 坐标) 和 top(y 坐标) 位置参数:transform:translate(50px,100px);值 translate(50px,100px) 把元素从左侧移动 50 像素,从顶端移动 100 像素。rotate():元素顺时针旋转给定的角度。允许负值,元素将逆时针旋转。transform:rotate(30deg);值 rotate(30deg) 把元素顺时针旋转 30 度。scale():元素的尺寸会增加或减少,根据给定的宽度(X 轴)和高度(Y 轴)参数:transform:scale(2,4);值 scale(2,4) 把宽度转换为原始尺寸的 2 倍,把高度转换为原始高度的 4 倍。skew():元素转动给定的角度,根据给定的水平线(X 轴)和垂直线(Y 轴)参数:transform:skew(30deg,20deg);值 skew(30deg,20deg) 围绕 X 轴把元素转动 30 度,围绕 Y 轴转动 20 度。matrix() :matrix() 方法把所有 2D 转换方法组合在一起。matrix() 方法需要六个参数,包含数学函数,允许您:旋转、缩放、移动以及倾斜元素。3D(rotateX(),rotateY())12rotateX():元素围绕其 X 轴以给定的度数进行旋转。transform:rotateX(120deg);rotateY():元素围绕其 Y 轴以给定的度数进行旋转。transform:rotateY(120deg);多列123column-count:属性规定元素应该被分隔的列数。column-gap:属性规定列之间的间隔。column-rule :属性设置列之间的宽度、样式和颜色规则。过渡及动画 元素消失123451. display:none; 2. visibility:hidden; 3. opacity: 0;4. position移到外部5. z-index涂层遮盖等等 元素垂直居中12341. (margin:auto) 定位为上下左右为0,margin:0/auto可以实现脱离文档流的居中.2. (margin负值法) position: absolute;top: 50%;left: 50%; 另 transform:translate(-50%,-50%) 或 margin-top:-(高度/2);margin-left:-(高度/2)3. (table) 父元素display: table-cell布局,子元素设置vertical-align:center/middle;4. (flex) 父元素display:flex,align-items:center;justify-content: center 0.5px 的线(详见chrome 0.5px)12341. viewport2. boxshadow3. 线性渐变linear-gradient4. 使用scale缩放,配合transform-origin: 50% 100%: 实现一个两列等高布局,讲讲思路为了实现两列等高,可以给每列加上123padding-bottom:9999px;margin-bottom:-9999px;同时父元素设置overflow:hidden;","categories":[],"tags":[]},{"title":"Ubuntu 部署python项目(python3.7,nginx,Gunicorn)","slug":"ubuntu 部署python项目","date":"2020-04-13T07:40:55.532Z","updated":"2020-04-17T15:50:33.720Z","comments":true,"path":"post/d295b30b.html","link":"","permalink":"http://blog.wkaanig.cn/post/d295b30b.html","excerpt":"","text":"1.准备所需环境 创建非root用户12345678# 在 root 用户下运行这条命令创建一个新用户newuserroot@localhost:~# useradd -m -s /bin/bash newuser# 把新创建的用户加入超级权限组root@localhost:~# usermod -a -G sudo newuser# 为新用户设置密码root@localhost:~# passwd newuserroot@localhost:~# su - newusernewuser@localhost:~$ 安装 python3本文使用较为简单的环境安装,查找了很多博客都是将 python 安装包下载后解压安装,略显麻烦。以root用户或具有sudo访问权限的用户身份运行以下命令,以更新软件包列表并安装必备组件:12sudo apt update #此处为更新列表,更新软件用这个 sudo apt-get upgradesudo apt install software-properties-common将deadsnakes PPA添加到系统的来源列表中:123sudo add-apt-repository ppa:deadsnakes/ppa sudo apt-get update #重要,一定要更新sudo apt install python3.7 # 安装你想使用的版本具体版本在python版本 PPA查看 安装nginx1sudo apt-get install nginx -y123456789101112# nginx 配置 (位置:/etc/nginx/sites-enabled/你新建的配置)server { listen 80; server_name api.shop.wkaanig.cn; access_log /var/log/nginx/access.log; location / { proxy_pass http://127.0.0.1:5000; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }} 安装mysql1234sudo apt-get install mysql-serversudo apt-get install mysql-clientsudo apt-get install libmysqlclient-devmysql -u root -p #测试数据库 安装 gunicorn (参数)123456789101112131415pip install gunicorn# -w 4 为 4个进程 # -b 为 bind 监听端口gunicorn -w 4 -b 0.0.0.0:5000 入口文件名:app# -D 后台运行gunicorn -D -b 0.0.0.0:5000 入口文件名:app# access日志 gunicorn --timeout 20 --access-logfile access.log --error-logfile error.log -D -b 0.0.0.0:5000 入口文件名:app# 查询 gunicorn 进程pstree -ap|grep gunicorn# 关闭进程kill -9 pid","categories":[{"name":"Python","slug":"Python","permalink":"http://blog.wkaanig.cn/categories/Python/"}],"tags":[{"name":"Flask","slug":"Flask","permalink":"http://blog.wkaanig.cn/tags/Flask/"},{"name":"Django","slug":"Django","permalink":"http://blog.wkaanig.cn/tags/Django/"}]},{"title":"openCV 安装及代码优化","slug":"openCV 安装及代码优化","date":"2020-01-30T06:00:11.850Z","updated":"2020-04-17T15:49:40.586Z","comments":true,"path":"post/d6084e0f.html","link":"","permalink":"http://blog.wkaanig.cn/post/d6084e0f.html","excerpt":"","text":"要安装OpenCV,只需cmd下的一条指令:1pip install opencv-pythonpip是Python的包管理器,如果你还没安装Python,强烈推荐安装Anaconda,它包含了大量的科学计算包,不用后期一个个安装。即使你已经装了Python也没有影响,Anaconda相当于虚拟环境,互不干扰。 评估代码运行时间(性能分析)123456import cv2start = cv2.getTickCount()# 这里写测试代码...end = cv2.getTickCount()print((end - start) / cv2.getTickFrequency())这段代码就是用来测量程序运行时间的(单位:s),其中cv2.getTickCount()函数得到电脑启动以来的时钟周期数,cv2.getTickFrequency()返回你电脑的主频,前后相减再除以主频就是你代码的运行时间(这样解释并不完全准确,但能理解就行)。另外,也可以用Python中的time模块计时:123456import timestart = time.clock()# 这里写测试代码...end = time.clock()print(end - start) 优化原则数据元素少时用Python语法,数据元素多时用Numpy:1234567x = 10z = np.uint8([10])# 尝试比较下面三句话各自的运行时间y = x * x * x # (1.6410249677846285e-06)y = x**3 # (2.461537451676943e-06)y = z * z * z # 最慢 (3.1179474387907945e-05)所以Numpy的运行速度并不一定比Python本身语法快,元素数量较少时,请用Python本身格式。尽量避免使用循环,尤其嵌套循环,因为极其慢!!!优先使用OpenCV/Numpy中封装好的函数尽量将数据向量化,变成Numpy的数据格式尽量避免数组的复制操作","categories":[{"name":"python","slug":"python","permalink":"http://blog.wkaanig.cn/categories/python/"}],"tags":[{"name":"基础知识","slug":"基础知识","permalink":"http://blog.wkaanig.cn/tags/基础知识/"}]},{"title":"写博客必备神器","slug":"写博客必备神器","date":"2019-10-04T06:13:37.721Z","updated":"2020-04-17T15:46:35.665Z","comments":true,"path":"post/914428cf.html","link":"","permalink":"http://blog.wkaanig.cn/post/914428cf.html","excerpt":"","text":"完成了博客的搭建之后,接下来就是是内容创作了。而创作的过程中,我们又会有一系列的问题,比如:我们用什么工具来编写文章呢?怎么才能快速生成格式化的Markdown表格?怎么样才能画出一些高逼格的图片呢?这些图片的存储和处理怎么办呢?文章中的代码高亮如何实现呢?要解决这些问题其实并不难,无非就是引入不同的工具来帮助我们,好的工具可以让我们的创作事半功倍! Markdown编辑器先来推荐一下我们要用的最重要的一个工具:Marddown编辑器。我们需要使用它来完成所有的创作内容,本人尝试了非常多的编辑器,最终锁定在下面这款Typora,因此推荐给大家。推荐工具:Typora官方地址:https://www.typora.io/推荐理由:作为一款免费编辑器,可以说是相当的良心,是我目前所知道的最好用的免费编辑器了,没有之一!!!它支持多个主流的操作系统,不论你是Windows用户还是Mac用户,都能轻易的安装和使用它!除此之外,它还有多种不同的主题选择、导出一些常用格式(PDF、Word、HTML)等等非常有用的功能!img Markdown表格生成器对于强迫症来说,写Markdown表格是一件很痛苦的事情,在语法对齐的问题上我真的是受尽了折磨,所以强烈推荐一个在线Markdown表格生成工具,它除了能快速生成格式化后的Markdown表格外,还支持导入各种数据,在线编辑,简直强大!推荐工具:Table Convert Online官方地址:https://tableconvert.com/推荐理由:作为一款免费在线工具,支持Excel、JSON、HTML、CSV甚至是从URL中提取HTML表格转为Markdown表格,多功能集一身,并且融合在一个界面,使用非常方便,不需要切换页面。还可以像编辑Excel一样编辑生成各种表格,不愧为表格中的瑞士军刀!img 画图工具对于我们这些写技术文章的博主来说,画画流程图、架构图是辅助描述文章内容的最佳途径,下面要推荐的ProcessOn就是目前我用得最多的画图工具。推荐工具:ProcessOn官方地址:https://processon.com/推荐理由:难得的国产在线图片编辑器,支持多人协作。同时,还有大量好看的图标支持,可以让我们的绘图更加生动!img 图片存储可能有人会问,为什么要图片存储呢?我们直接存Wordpress或者Hexo的目录下不就好了吗?实际上,使用这些主要是为了经济性的考虑,随着访问量的增大,图片对于我们的虚拟主机或ECS的空间以及带宽消耗都会造成一定的压力,使用类似图床的平台可以帮我们减轻这些压力。推荐工具:外链工厂官方地址:http://www.wailian.work/推荐理由:简单好用、足够稳定,释放自己虚拟空间或虚拟主机的存储和带宽消耗,但是记得做好备份哦!img 代码高亮如果你跟我一样是一名程序猿,那么代码高亮是必备的。大多Hexo的主题中都包含了高亮插件,但是有些并没有,那么我们需要知道鼎鼎大名的hightlight.js。对于一些已经有这个插件的主题,也可以通过官网来做一些定制,没有的直接引入来使用即可。推荐工具:hightlight.js官方地址:https://highlightjs.org/推荐理由:适用于所有主流编程语言,兼容性好,多种多样的预设样式,总有一款适合你!","categories":[{"name":"杂项","slug":"杂项","permalink":"http://blog.wkaanig.cn/categories/杂项/"}],"tags":[{"name":"个人博客","slug":"个人博客","permalink":"http://blog.wkaanig.cn/tags/个人博客/"},{"name":"工具","slug":"工具","permalink":"http://blog.wkaanig.cn/tags/工具/"}]},{"title":"Docker 远程访问及守护进程的配置和操作(04)","slug":"Docker 入坑(4)","date":"2019-09-22T07:59:15.433Z","updated":"2020-04-17T15:48:09.647Z","comments":true,"path":"post/82185f4b.html","link":"","permalink":"http://blog.wkaanig.cn/post/82185f4b.html","excerpt":"","text":"一、Docker守护进程的配置和操作 1.查看守护进程的运行状态(2种方式)121. ps -ef |grep docker 2. sudo service docker status 2. service 命令管理守护进程123service docker stopservice docker startservice docker restart 3.Docker 守护进程的启动选项1234567891011121314151617docker -d [OPTIONS]-D,--debug-e,--exec-driver=\"native\"-g,--graph=\"/var/lib/docker\" --ice=true-l,--log-level=\"info\" 日志级别--label=[]-p,--pidfile=\"/var/run/docker.pid\"服务器相关-G,--group=\"docker\"-H,--host=[] tcp://host:port|unix:///path/to/socket|fd://* or fd://socketfd 默认为:-H unix:///var/run/docker.sock--tls=false--tlscacert=\"/home/sven/.docker/ca.pem\"--tlscert=\"/home/sven/.docker/cert.pem\"--tlskey=\"/home/sven/.docker/key.pem\"--tlsverify=false... 4.修改Docker守护进程的启动配置文件12vim /etc/default/dockerDOCKER_OPTS=“启动选项命令” 二、Docker的远程访问环境准备:123另一台 Docker 的服务器修改 Docker 守护进程启动选项,区别服务器(即 --lable 参数 DOCKER_OPTS=\"--lable name=server_01\")保证Client API 与 Server API 版本一致Server 端12345vim /etc/default/docker...DOCKER_OPTS=\"--lable name=server_01 -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock\" # 可支持2375端口的远程访问,也可支持本地默认访问 ...service docker restartClient 端1234567891011vim /etc/default/docker...DOCKER_OPTS=\"--lable name=server_02\"...service docker restart# 链接远程的 docker 服务器export DOCKER_HOST=\"tcp://Server的ip:2375\"docker info# 链接本地的 docker 服务器export DOCKER_HOST=\"\"docker info 三、容器的网络连接 1. 自定义 docker 的网络接口安装网桥管理工具12apt-get install bridge-untilsbrctl show添加Linux虚拟网桥12sudo brctl addbr br0sudo ifconfig br0 192.168.100.1 netmask 255.255.255.0更改守护进程启动配置1DOCKER_OPS=\"-b=br0\" 2. 容器之间互联允许所有容器之间互联方法一:默认互通即 DOCKER_OPS="--icc=true" 无需修改任何配置方法二:docker run link 指令1docker run --link=[CONTAINER_NAME]:4w[ALIAS(别名)] [IMAGE] [COMMAND]拒绝容器之间互联1DOCKER_OPS=\"--icc=false\"允许特定容器之间互联 (DOCKER_OPS 与 docker run link 配合使用)12DOCKER_OPS=\"--icc=false --iptables=true\"docker run --link=[CONTAINER_NAME]:[ALIAS(别名)] [IMAGE] [COMMAND] 3. Docker 外部访问链接允许端口映射访问1ip_forward=true(默认)限制ip访问容器(iptables 工具)1sudo iptables -I DOCKER -s 起始ip -d 目标ip -p TCP --dport 80 -j DROP拓展: iptables 的常用命令12sudo iptables -F 清除iptables设置sudo iptables -L -n 查看iptables的详情","categories":[{"name":"Docker","slug":"Docker","permalink":"http://blog.wkaanig.cn/categories/Docker/"}],"tags":[{"name":"Linux","slug":"Linux","permalink":"http://blog.wkaanig.cn/tags/Linux/"}]},{"title":"Docker 如何对镜像进行构建查看和删除等操作(03)","slug":"Docker 入坑(3)","date":"2019-09-17T09:37:08.817Z","updated":"2020-04-17T15:47:58.126Z","comments":true,"path":"post/ebc79fe5.html","link":"","permalink":"http://blog.wkaanig.cn/post/ebc79fe5.html","excerpt":"","text":"一、查看和删除镜像方法一:一般情况下镜像的存储地址为 /var/lib/docker方法二:通过docker info 查看镜像信息 1. 列出镜像12345docker images [OPTSIONS] [REPOSITORY]-a ,--all-f , --filter=[]--no-trunc(使用截断的方式显示)-q,--quiet(只显示ID) 2. 镜像标签和仓库REPOSITORY 仓库(独立的镜像)RESGISTRY 仓库(镜像存储服务)TAG (ubuntu:14.04 ubuntu:latest) 3. 查看镜像1docker inspect [OPTIONS] CONTAINER|IMAGE [ CONTAINER|IMAGE...] 4. 删除镜像123docker rmi [OPTIONS] IMAGE-f,--force 强制删除--no-prune (不会删除未打标签的父镜像)扩展:docker 并没有删除多个镜像的操作删除所有 ubuntu 镜像 docker rmi $(docker images -q ubuntu) 二、获取和推送镜像 1. 查找镜像方法一:Docker Hub(需注册账户)方法二:命令行搜索12345docker search [OPTIONS] TERM-- automated (自动化构建镜像)--no-trunc (截断形式)-s,--stars=0 (评分)示例:docker search -s 3 ubuntu(搜索3星以上的 ubuntu 镜像) 2. 拉取镜像12docker pull [OPTIONS] NAME [:TAG]-a,--all-tags (所有标记)使用–registry-mirror选项,添加国内镜像进行加速修改:vim /etc/default/docker添加:DOCKER_OPTS="--registry-mirror=镜像地址"我们这里使用daocloud(需注册账户),使用加速器生成的链接配置以上的镜像地址重新启动 docker 守护进程 service docker restart查看 docker 状态 ps -ef |grep docker 3. 推送镜像1docker push [OPTIONS] NAME [:TAG] 三、构建镜像1234优点:- 保存对容器的修改,并再次使用- 自定义镜像的能力- 以软件的形式打包并分发服务及其运行环境 方法一:docker commit 通过容器构建镜像1234docker commit [OPTIONS] CONTAINER [REPOSITORY]-a,--author-m,--message-p,--pause (是否暂停正在运行的容器)示例:(用前面的 web 容器生成 ubuntu/commit_test1镜像,再生成以 ubuntu/commit_test1 镜像为基础的两个 nginx_web 容器)1234567891011121314151617root@wkaanig:~# docker commit -a 'wkaanig' -m 'nginx' web ubuntu/commit_test1 # 将web容器构建成 ububtu/commit_test1 的镜像文件sha256:27b64732dde89f0f6f466e9dc0da7b06bdc7547cf37a878515b4b42167f2f657root@wkaanig:~# docker images # 查看镜像REPOSITORY TAG IMAGE ID CREATED SIZEubuntu/commit_test1 latest 27b64732dde8 About a minute ago 206MBubuntu latest a2a15febcdf3 4 weeks ago 64.2MBhello-world latest fce289e99eb9 8 months ago 1.84kBroot@wkaanig:~# docker run -d --name nginx_web1 ubuntu/commit_test1 nginx -g \"daemon off;\" # 以前台方式运行镜像到 nginx_web1 的容器中43b432b814019b7e1ba111ef064bb800e986476e38e4947730c189511e7b1d49root@wkaanig:~# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES43b432b81401 ubuntu/commit_test1 \"nginx -g 'daemon of…\" 6 seconds ago Up 5 seconds 80/tcp nginx_web1root@wkaanig:~# docker run -d --name nginx_web2 -p 80 ubuntu/commit_test1 nginx -g \"daemon off;\" # 以前台方式运行镜像到 nginx_web2 的容器中 指定端口为803674c7cef4f4f7e9c2d7040fd5dd2d8776f08761d7db3934dca5c23132f2b9afroot@wkaanig:~# docker ps # 查看镜像CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES3674c7cef4f4 ubuntu/commit_test1 \"nginx -g 'daemon of…\" 8 seconds ago Up 7 seconds 0.0.0.0:32769->80/tcp nginx_web2123456789root@wkaanig:~# curl http://127.0.0.1:32769 # 测试访问端口<html><head> <title>Nginx in docker<title><head> <body> <h1>hello Docker</h1><body><html> 方法二:docker bulid 通过Dockerfile文件构建 (1)写入dockerfile 文件Dockerfile文件内容:(基础指令必须存在,其余指令视情况而定)基础指令12345678910111213141516# 示例:dockerfile_01# FROM <image>必须是已存在的镜像即基础镜像FROM ubuntu:14.04 # MAINTAINER <name>指定镜像的作者信息,包含镜像所有者和联系信息MAINTAINER wkaanig \"wkaanig721@163.com\" # RUN 指定当前镜像中运行的命令,有以下两种方式# 1.RUN <command> (shell 模式 以 /bin/sh -c command 执行命令 例:RUN echo hello )# 2.RUN[\"executable\",\"param1\",\"param2\"] (exec 模式 例:RUN [\"/bin/bash\",\"-c\",\"echo hello\"]) RUN apt-get update RUN apt-get insatll -y nginx# EXPOSE <port> [<port>] 指定运行该镜像的容器使用的一个或多个端口 # 出于安全考虑 docker 并不会打开端口 ,需要在运行中添加对端口的映射,即:-p 80# 例:docker run -d --name nginx_web1 -p 80 ubuntu/commit_test1 nginx -g EXPOSE 80其余指令1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162# 1.在容器执行时运行命令的指令 # CMD 在容器运行中的指令 不同于RUN RUN在镜像构建中运行,CMD在容器运行中运行,RUN 可以覆盖 CMD# 1.CMD [\"executable\",\"param1\",\"param2\"](exec 模式)# 2.CMD command param1 param2 (shell 模式)# 3.CMD[\"param1\",\"param2\"](作为ENTERPOINT指令的默认参数)# 示例:dockerfile_02FROM ubuntu:14.04 MAINTAINER wkaanig \"wkaanig721@163.com\" RUN apt-get update RUN apt-get insatll -y nginxEXPOSE 80CMD [\"/usr/sbin/nginx\",\"-g\",\"daemon off;\"]# ENTERYPOINT 不会被docker RUN 命令所覆盖,若想覆盖可以使用docker run --enterpoint 覆盖# 示例1:dockerfile_03FROM ubuntu:14.04 MAINTAINER wkaanig \"wkaanig721@163.com\" RUN apt-get update RUN apt-get insatll -y nginxEXPOSE 80ENTERYPOINT [\"/usr/sbin/nginx\",\"-g\",\"daemon off;\"]# 示例2:dockerfile_04 ENTERYPOINT 和 CMD 组合命令FROM ubuntu:14.04 MAINTAINER wkaanig \"wkaanig721@163.com\" RUN apt-get update RUN apt-get insatll -y nginxEXPOSE 80ENTERYPOINT [\"/usr/sbin/nginx\"]CMD [\"-g\"] # 可被 docker run 命令覆盖# 2.设置镜像的目录和文件# ADD 与 COPY 的区别,ADD 包含类似tar的解压功能。如果单纯复制文件,Docker推荐使用COPY# ADD <src>...<dest> 来源地址(本地的相对路径(推荐)或URL)和目标地址(镜像中的绝对路径)# COPY <src>...<dest> 来源地址(本地的相对路径(推荐)或URL)和目标地址(镜像中的绝对路径)# 示例:dockerfile_05FROM ubuntu:14.04 MAINTAINER wkaanig \"wkaanig721@163.com\" RUN apt-get update RUN apt-get insatll -y nginxCOPY index.html /usr/share/nginx/html/ # 通过本地编写的 index.html(在 dockerfile 的同级目录下)替换 nginx 的默认页EXPOSE 80ENTERYPOINT [\"/usr/sbin/nginx\",\"-g\",\"daemon off;\"]# VOLUME [\"/data\"] 添加卷# 3.镜像构建及容器运行中的环境设置# WORKDIR /path/to/workdir 设置工作目录,enterpoint和cmd都会在这个目录下执行# ENV <key>=<value> 指定环境# USER daemon 指定用户模式# 4.镜像触发器 # ONBUILD [INSTRUCTION] 当一个镜像被其他镜像作为基础镜像时执行,在构建过程中插入# 示例:dockerfile_06FROM ubuntu:14.04MAINTAINER wkaanig \"wkaanig721@163.com\" RUN apt-get update RUN apt-get insatll -y nginxONBUILD COPY index.html /usr/share/nginx/html/ # 通过本地编写的 index.html(在 dockerfile 的同级目录下)替换 nginx 的默认页EXPOSE 80ENTERYPOINT [\"/usr/sbin/nginx\",\"-g\",\"daemon off;\"]# 注意:示例 dockerfile_06 的 ONBUILD 会在以该镜像为基础镜像构建的子镜像中执行,在本次构建过程中不会执行 (2) docker bulid 构建镜像1234567docker bulid [OPTIONS] PATH|URL|- # PATH和URL指的是dockerfile的路径--force-rm--no-cache--pull-q,--quiet--rm-t,--tag示例:12docker bulid -t=\"wkaanig/docker_file_test1\" . # 在当前文件夹下构建名为wkaanig/docker_file_test1 的镜像docker run -p 80 --name cmd_test1 -d wkaanig/docker_file_test1 # 以 80 端口和守护模式运行该镜像的 cmd_test1 容器","categories":[{"name":"Docker","slug":"Docker","permalink":"http://blog.wkaanig.cn/categories/Docker/"}],"tags":[{"name":"Linux","slug":"Linux","permalink":"http://blog.wkaanig.cn/tags/Linux/"}]},{"title":"Docker 在容器中部署静态网站(02)","slug":"Docker 入坑(2)","date":"2019-09-17T08:34:17.888Z","updated":"2020-04-17T15:47:49.184Z","comments":true,"path":"post/603eaf11.html","link":"","permalink":"http://blog.wkaanig.cn/post/603eaf11.html","excerpt":"","text":"Docker 中 Nginx 部署流程设置端口映射12345678run [-P] [-p]-P,--publish-all(全部映射)示例:docker run -P -i -t ubuntu /bin/bash-p,--publish=[](指定映射)示例:docker run -p 80 -i -t ubuntu /bin/bashdocker run -p 8080:80 -i -t ubuntu /bin/bashdocker run -p 0.0.0.0:80 -i -t ubuntu /bin/bashdocker run -p 0.0.0.0:8080:80 -i -t ubuntu /bin/bash 1. 创建映射 80 端口的交互式容器1docker run -p 80 --name web -i -t ubuntu /bin/bash 2. 安装 Nginx12apt-get update(更新源)apt-get install -y nginx 3. 安装文本编辑器 vim1apt-get install -y vim 4. 创建静态页面123mkdir -p /var/www/htmlcd /var/www/html/vim index.html12345678<html><head> <title>Nginx in docker<title><head> <body> <h1>hello Docker</h1><body><html> 5. 修改 Nginx 配置文件123whereis nginxls /etc/nginx/sites-enabled (一般都在这个位置,视具体而定)vim /etc/nginx/sites-enabled/default12345server{ ... root /var/www/html; ...} 6. 运行 Nginx123cd /nginxps -ef (查看nginx运行状态)Ctrl+P Ctrl+Q (后台运行) 7. 验证网站访问方法一:宿主机端口访问1234567891011root@wkaanig:~# docker port web80/tcp -> 0.0.0.0:32768root@wkaanig:~# curl http://127.0.0.1:32768<html><head> <title>Nginx in docker<title><head> <body> <h1>hello Docker</h1><body><html>方法二:容器ip访问12345678910111213141516root@wkaanig:~# docker inspect web 查找到 \"Networks\": { ... \"IPAddress\": \"172.17.0.3\", ... }root@wkaanig:~# curl http://172.17.0.3<html><head> <title>Nginx in docker<title><head> <body> <h1>hello Docker</h1><body><html> 8. 完善性测试123456docker stop web docker start -i webps -ef (发现nginx并未开启)docker exec web nginxdocker top webcurl IP地址 (注意:此时ip地址及映射地址已经改变,按以上方法重新查看ip)","categories":[{"name":"Docker","slug":"Docker","permalink":"http://blog.wkaanig.cn/categories/Docker/"}],"tags":[{"name":"Linux","slug":"Linux","permalink":"http://blog.wkaanig.cn/tags/Linux/"}]},{"title":"Docker 入坑(01)","slug":"Docker 入坑(1)","date":"2019-09-15T09:52:48.666Z","updated":"2020-04-17T15:47:40.114Z","comments":true,"path":"post/5b3d2e5b.html","link":"","permalink":"http://blog.wkaanig.cn/post/5b3d2e5b.html","excerpt":"","text":"一、Docker是什么?Docker 依赖unix内核 运行在Linux上的容器不同于虚拟机,Docker 让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,便可以实现虚拟化。 Docker改变了虚拟化的方式,使开发者可以直接将自己的成果放入Docker中进行管理。 二、Docker的技术简介(每个容器都单独分配计算机进程、root文件系统、IP地址、cpu、内存等资源)Namespaces 命名空间PID(Process ID)进程隔离NET(Network)管理网络接口IPC(IntePrcess Communication)管理跨进程通信的访问MNT(Mount)挂载点(文件系统)UTS(Unix Timesharing System)隔离内核和版本标识Unix Control groups 控制组资源限制优先级设定资源计量资源控制Docker 基于Control groups 分配计算机资源给各个容器,是一个通过联合加载技术形成的只读文件系统。 三、安装Docker(Ubuntu)**方法一:*需要检查 Ubuntu 内核版本是否支持 Docker,官方已经将安装docker的过程写入一个shell脚本中,我们只需要下载并执行这个脚本即可检查是否安装 curl (若安装可跳过)1sudo apt-get install -y curl获取脚本并安装(示例:Ubuntu的安装方式)1curl -fsSL https://get.docker.com | sudo sh方法二:命令行安装如果之前安装过docker,执行下面命令删除12apt-get remove docker docker-engine docker.iosudo apt-get update安装必要的软件包以允许apt通过HTTPS使用存储库,具体如下:1sudo apt-get install apt-transport-https ca-certificates curl software-properties-common添加GPG密钥,可以添加官方的和阿里的,我添加的阿里的,国内的快啊1234// 官方curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -// 阿里curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -添加完毕后可以执行以下命令验证:1sudo apt-key fingerprint 0EBFCD88正常情况下会输出如下内容,说明 Ok,继续:1234pub rsa4096 2017-02-22 [SCEA] 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88uid [ 未知 ] Docker Release (CE deb) <docker@docker.com>sub rsa4096 2017-02-22 [S]设定稳定仓储库,这一步我被坑了好久,具体参考 docker 配置仓储库时出错:无法安全地用该源进行更新,所以默认禁用该源,也可以不设置,不设置默认使用官方的,具体是:deb [arch=amd64] https://download.docker.com/linux/ubuntu xenial stable同样可以用阿里 的镜像:设置命令如下:1sudo add-apt-repository \"deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable\"*注意:*其中的lsb_release -cs相当于一个函数,直接获取Ubuntu下的最新版本,设置完毕再次执行1sudo apt-get update安装docker1sudo apt-get -y install docker-ce也可以指定想安装 的docker版本,执行如下命令命令查看有哪些版本1apt-cache madison docker-ce输出如下:1234docker-ce | 5:18.09.0~3-0~ubuntu-bionic | http://mirrors.aliyun.com/docker-ce/linux/ubuntu bionic/stable amd64 Packagesdocker-ce | 18.06.1~ce~3-0~ubuntu | http://mirrors.aliyun.com/docker-ce/linux/ubuntu bionic/stable amd64 Packagesdocker-ce | 18.06.0~ce~3-0~ubuntu | http://mirrors.aliyun.com/docker-ce/linux/ubuntu bionic/stable amd64 Packagesdocker-ce | 18.03.1~ce~3-0~ubuntu | http://mirrors.aliyun.com/docker-ce/linux/ubuntu bionic/stable amd64 Packages选择要安装的版本,执行1sudo apt-get install -y docker-ce=<VERSION>安装完成 后执行1docker -v如果正常输出说明安装成功 四、非root用户使用Docker非root用户使用docker会异常卡顿,官方推荐了一种非root用户使用的方式添加docker 用户组1sudo groupadd docker将当前用户添加到用户组中1sudo gpasswd -a '你的用户名' docker重启 docker1sudo service docker restart运行 docker 命令1docker version注意:需注销当前用户重新登录,不然会报错(FATA[0000])! 五、 容器的基本操作1234docker run IMAGE [COMMAND] [ARG..](启动命令格式)例:docker run ubuntu echo 'hello world'root@wkaanig:~# docker run ubuntu echo 'hello world'hello world 1. 启动交互式命令(只执行一次)123456789docker run -i-t IMAGE /bin/bash (启动交互式命令 -i --interactive 标准服务 -t --tty 打开tty终端)例:docker run -i -t ubantu /bin/bashroot@wkaanig:~# docker run -i -t ubuntu /bin/bashroot@72328d172f8f:/# ps -efUID PID PPID C STIME TTY TIME CMDroot 1 0 2 07:40 pts/0 00:00:00 /bin/bashroot 10 1 0 07:40 pts/0 00:00:00 ps -efroot@72328d172f8f:/# exit exit 2. 查看容器123456docker ps [-a] [-l](-a 所有的容器 -l 最新的容器)docker inspect \"你想查询的 CONTAINER ID\" (查看详情)示例:root@wkaanig:~# docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES81046a796b82 ubuntu \"echo 'hello world'\" 3 minutes ago Exited (0) 3 minutes ago dazzling_hugle72328d172f8f ubuntu \"/bin/bash\" 4 minutes ago Exited 3. 自定义容器名12docker run --name=自定义名 -i -t IMAGE /bin/bash查询:docker inspect 自定义名 4. 重新启动停止的容器1docker start [-i] 容器名 5. 删除已停止的容器1docker rm 容器名 小结123456docker run -i -t --namedocker ps -a -ldocker inspectdocker start -idocker start -idocker rm 六、守护式容器 1. 以守护形式运行容器123456docker run -i -t IMAGE /bin/bashCtrl+P Ctrl+Q (使容器后台运行)示例:root@wkaanig:~# docker run -i -t ubuntu /bin/bashroot@7b296d75cd4b:/# root@wkaanig:~# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES7b296d75cd4b ubuntu \"/bin/bash\" 15 seconds ago Up 14 seconds busy_boyd 2. 附加到运行中的容器(即将 docker 容器放置前台运行)1docker attach 容器名(ID 或 Name) 3. 启动守护式容器(以后台的方式)123456docker run -d IMAGE [COMMAND] [ARG..]示例:root@wkaanig:~# docker run --name dc1 -d ubuntu /bin/sh -c \"while true;do echo hello word;sleep 1;done\"df0b3043010d986371a4a9d94fa72f28fddc4f69a38d89690078ced9cca528cbroot@wkaanig:~# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESdf0b3043010d ubuntu \"/bin/sh -c 'while t…\" 10 seconds ago Up 9 seconds dc1 4. 查看容器的运行情况(即日志)12345678docker logs [-f] [-t] [--tail] 容器名-f --follows 跟踪-t --timestamps 时间戳--tail=\"all\" 日志数量示例:root@wkaanig:~# docker logs -ft --tail=0 dc12019-09-17T08:19:57.987090981Z hello word2019-09-17T08:19:58.988018019Z hello word 5. 查看容器内进程1docker top 容器名 6. 在运行中的容器内启动新进程1docker exec [-d] [-i] [-t] 容器名 [COMMAND] [ARG...] 7. 停止守护式容器12docker stop 容器名docker kill 容器名 (快速停止) 小结123456Ctrl+P Ctrl+Qdocker run -ddocker logsdocker topdocker execdocker stop/kill","categories":[{"name":"Docker","slug":"Docker","permalink":"http://blog.wkaanig.cn/categories/Docker/"}],"tags":[{"name":"Linux","slug":"Linux","permalink":"http://blog.wkaanig.cn/tags/Linux/"}]},{"title":"算法分析","slug":"算法分析","date":"2019-09-11T12:04:39.628Z","updated":"2020-04-17T15:46:19.658Z","comments":true,"path":"post/d68e5e2f.html","link":"","permalink":"http://blog.wkaanig.cn/post/d68e5e2f.html","excerpt":"","text":"算法的时间性能分析通常有两种衡量算法时间性能的方法事后统计法事前估算法 算法时间分析复杂度计算算法的频度 T(n)T(n)T(n)求出算法所有原操作的执行次数。T(n)用O表示T(n)用O表示T(n)用O表示不同的时间复杂度存在以下关系:O(1)<O(log2n)<O(n)<O(nlog2n)<O(n2)<O(2n)<O(n!)O(1) < O(\\log_2n)< O(n) < O(n\\log_2n) < O(n^2) < O(2n) < O(n!)O(1)<O(log2n)<O(n)<O(nlog2n)<O(n2)<O(2n)<O(n!)简化的算法时间复杂度分析找出最深的语句分析频度T(n)=n2=O(n2)T(n) = n^2=O(n^2)T(n)=n2=O(n2)时间复杂度的求和、求积定理为了计算算法的时间复杂度,有以下两个定理。求和定理:假设 T1(n)T_1(n)T1(n)和T2(n)T_2(n)T2(n)是程序段P1P_1P1、P2P_2P2的执行时间,并且T1(n)=O(f(n))T_1(n)=O(f(n))T1(n)=O(f(n)),T2(n)=O(g(n))T_2(n)=O(g(n))T2(n)=O(g(n)),那么先执行P1P_1P1,再执行P2P_2P2的总执行时间T1(n)+T2(n)=O(MAX(f(n),g(n)))T_1(n)+T_2(n)=O(MAX(f(n),g(n)))T1(n)+T2(n)=O(MAX(f(n),g(n)))。求积定理:假设 T1(n)T_1(n)T1(n)和T2(n)T_2(n)T2(n)是程序段P1P_1P1、P2P_2P2的执行时间,并且T1(n)=O(f(n))T_1(n)=O(f(n))T1(n)=O(f(n)),T2(n)=O(g(n))T_2(n)=O(g(n))T2(n)=O(g(n)),那么T1(n)×T2(n)=O(f(n)×g(n)T_1(n)\\times T_2(n)=O(f(n)\\times g(n)T1(n)×T2(n)=O(f(n)×g(n)。 算法空间性能分析算法空间复杂度是对一个算法在运行过程中占用的存储空间大小的量度。只需考虑临时空间,不必考虑形参空间,形参空间会在调用该算法的算法中考虑。一般也作为问题的规模n的函数,以数量级形式给出,记作:S(n)=O(g(n))S(n) = O(g(n))S(n)=O(g(n))","categories":[{"name":"算法","slug":"算法","permalink":"http://blog.wkaanig.cn/categories/算法/"}],"tags":[{"name":"基础知识","slug":"基础知识","permalink":"http://blog.wkaanig.cn/tags/基础知识/"}]},{"title":"数据结构是什么?","slug":"数据结构","date":"2019-09-11T10:06:19.645Z","updated":"2020-04-17T15:47:14.361Z","comments":true,"path":"post/8ca0dce9.html","link":"","permalink":"http://blog.wkaanig.cn/post/8ca0dce9.html","excerpt":"","text":"数据结构定义数据的逻辑结构数据的存储结构(物理结构)数据的运算 逻辑结构表示图表表示二原组表示 B = (D, R)类型集合线性结构树形结构图形结构12345678910# 树形结构B = ( D, R )D = {a, b, c, d}R = { r } r = {<a, b>,<a, c>,<a, d>}# 图形结构B = ( D, R )D = {a, b, c, d}R = { r } r = {(a, b),(a, c),(b, c)} 存储结构顺序存储 (dict)链式存储 (*next)索引存储 (key, address,查找效率高,需建立索引表)哈希(散列)存储(哈希函数计算出存储地址,只对数据进行存储,不对逻辑关系存储) 数据运算常用的运算有检索、插入、删除、更新和排序等。运算定义运算实现逻辑结构映射=>存储结构 数据类型和抽象类型数据类型C/C++ 常用的数据类型基本数据类型(int, short int, long int, unsigned int, bool, float, double, char)指针类型(int i,*p; i 是整型变量,p 是指针变量。&i表示变量 i 的地址,将 p 指向 i 的运算为p=&i。*p是取 p 所指变量的值。)数组类型 (int a[10])结构体类型共用体类型(共享存储单元)存储空间分配静态分配方式(int a[10];)动态分配方式(用malloc()函数为指针变量分配连续的空间,不需要时用free(p)释放p所指向的空间。)12345678910111213141516# 结构体类型struct Test{ int no; int age;};struct Test t; t.no=10;# 共用体类型union Test1{ short int n; char ch[2];};union Test1 u;u.n = 12;1234567# 动态存储空间分配char *p;p = (char *)malloc(10 * sizeof(char)); // p 为指针变量属于自动变量由系统自动分配和释放,(char *) 转化为字符指针strcpy(p,\"China\");printf(\"%c\\n\",*p); // 输出Cprintf(\"%s\\n\",p); // 输出Chinafree(p);抽象类型(Abstract Data Type)抽象类型有两个重要特征,数据抽象和数据封装。抽象类型由数据逻辑结构和运算定义两部分组成。ADTADT的实现运算定义运算实现逻辑结构映射=>存储结构示例123456789101112ADT 抽象数据类型名(例:Complex){ 数据对象: D = {e1,e2|e1,e2 均为实数} 数据关系: R = {<e1,e2>|e1 是实数部分,e2 是虚数部分} 基本运算: AssingComplex(&z,v1,v2):构造复数 z,实部 v1 、虚部v2。 DestoryComplex(&z):销毁复数 GetReal(z,&real):用 real 返回 z 的实部 GetImag(z,&imag):用 imag 返回 z 的虚部 Add(z1,z2,&sum):用 sum 返回 z1,z2 相加的结果}","categories":[{"name":"数据结构","slug":"数据结构","permalink":"http://blog.wkaanig.cn/categories/数据结构/"}],"tags":[{"name":"基础知识","slug":"基础知识","permalink":"http://blog.wkaanig.cn/tags/基础知识/"}]},{"title":"Hexo 新建及发布文章","slug":"Hexo 新建及发布文章","date":"2019-09-10T13:15:36.618Z","updated":"2020-04-17T15:55:24.904Z","comments":true,"path":"post/5dd1c26f.html","link":"","permalink":"http://blog.wkaanig.cn/post/5dd1c26f.html","excerpt":"","text":"创建新文章 方法一:进入你的博客目录,在 /source/_posts 文件夹下直接建立一个.md文件。*注意:*文件的开头有固定的格式123456789---title: Hexo新建及发布文章 # 标题date: 2019-01-03 23:00:32 #时间categories: - Hexo # 分类tags: - 杂项 # 标签toc: true # 是否启用内容索引--- 方法二:12cd <folder>hexo new \"title\"这样就会在 /source/_posts 文件夹下,新建好一个 .md 文件,同时该文件中的头部信息 也会给你默认生成。 部署文章generate 生成静态页面1hexo generate # 可简写成 hexo gdeploy 将内容部署到 Github 网站1hexo deploy # 可以简写成 hexo d 异地修改123451. git clone 你的博客地址2. hexo c # 清理缓存3. hexo g # 重新生成静态文件4. hexo s # 本地预览4. hexo d # 部署至Github 关于图片引用12一般为需要安装 hexo-asset-image 并改写(有bug)详情及解决办法详见hexo引用本地图片无法显示 关于中自定义 URL详情看 hexo链接持久化终极解决之道","categories":[{"name":"Hexo","slug":"Hexo","permalink":"http://blog.wkaanig.cn/categories/Hexo/"}],"tags":[{"name":"杂项","slug":"杂项","permalink":"http://blog.wkaanig.cn/tags/杂项/"}]},{"title":"Hexo Github-Page 搭建及部署个人博客","slug":"Hexo Github-Page 搭建及部署个人博客","date":"2019-09-10T12:34:53.827Z","updated":"2020-04-17T15:49:07.466Z","comments":true,"path":"post/48da8957.html","link":"","permalink":"http://blog.wkaanig.cn/post/48da8957.html","excerpt":"","text":"Github 仓库首先你必须有一个 github 账号然后新建一个仓库,这一有第一个坑,我之前用了不同于 github 用户名(Hugking)来作为项目名称(wkaanig.github.io),一直没能搭建成功,后来看到其他大牛的经验,才发现项目名一定要是用户名(Hugking).github.io 的形式(README.md 可选可不选)在 github 中 setting 添加生成页面的选项 Source 选择 master branch注意:如果你之前没有用 git 关联过自己的 github 库,需要配置 SSH 等参数,否则无法成功,这部分搜 git 就有很多相关教程 安装前提hexo 有中文的文档,这一点非常方便,但是在安装过程中还是很容易有疏忽的地方,导致安装失败。安装 Hexo 之前,必须保证自己的电脑中已经安装好了 Node.js 和 Git。因为这两个软件我之前都安装过,这里就不重复安装过程了,检验方式如下:12$git --version$node --v 安装 Hexo安装好 node.js 和 git 后,可以通过 npm 来安装 Hexo。123npm install -g hexo-clihexo v # 查看版本npm install hexo-deployer-git --save # 安装 git 插件 初始化之后就可以在电脑里新建一个文件夹来作为存放博客全部内容。我们直接用 hexo 命令来初始化文件夹:123hexo init <folder>cd <folder>npm install<folder>就是文件夹的名字在创建的时候 ,文件夹初始化已经把需要的内容都下载进去了。注意:<folder>必须是一个空的文件夹,否者会创建失败 本地运行1hexo s # 启动服务器,在本地查看内容在 source->_posts 文件夹下,有一篇 helloworld 的初始化文章,在地址栏中输入http://localhost:4000/我们就可以看到博客内容,我们的博客运行成功啦!!! 配置打开配置文档_config.yml,对它做如下修改,repo 后面的内容是 git@gitbub.com:username/库地址的形式1234deploy: type: git repo: git@github.com:Hugking/Hugking.github.io.git branch: master注意:属性和内容之间一定要有一个空格,配置文件有自己的格式规范。 上传项目12hexo ghexo d第一次部署的时候,我们会重点用到 hexo init 这个命令外,在平时写博客和发布过程中最常用的就是:1234hexo n <filename> 新建文章hexo s 启动服务器,在本地查看内容hexo g 生成静态页面hexo d 部署到网站以上四个步骤。其实以上命令我觉得就足够了,文档里还有很多功能,搭建好后我们在https://用户名(Hugking).github.io就可以看到博客内容。 主题选择在 hexo 官网上下载自己喜欢的 theme,点击图片可以预览主题,点击图片下面的文字就可以打开 github 下载链接。复制源码的 url,在 git hash 命令窗口下载主题,输入git clone url,注意得手动粘贴,Ctrl+v无效接着,将配置文件_config.yml 中的 theme 改为新的主题的名字,记住一定要将下载下来的文件夹放到 themes 文件夹里! 文件解释新建好的文件夹目录如下:1234567├── _config.yml├── package.json├── scaffolds├── source| ├── _drafts| └── _posts└── themes_config.yml博客的配置文件,博客的名称、关键词、作者、语言、博客主题…设置都在里面。package.json应用程序信息,新添加的插件内容也会出现在这里面,我们可以不修改这里的内容。scaffoldsscaffolds 就是脚手架的意思,这里放了三个模板文件,分别是新添加博客文章(posts)、新添加博客页(page)和新添加草稿(draft)的目标样式。这部分可以修改的内容是,我们可以在模板上添加比如 categories 等自定义内容sourcesource 是放置我们博客内容的地方,里面初始只有两个文件夹,一个是 drafts(草稿),一个 posts(文章),但之后我们通过命令新建 tags(标签)还有 categories(分类)页后,这里会相应地增加文件夹。themes放置主题文件包的地方。Hexo 会根据这个文件来生成静态页面。初始状态下只有 landscape 一个文件夹,后续我们可以添加自己喜欢的。 总结以上为初次使用Hexo的基本步骤,下次我们来说如何创建并发布一篇新文章,作为小白,要走的路还很长,加油吧!","categories":[{"name":"Hexo","slug":"Hexo","permalink":"http://blog.wkaanig.cn/categories/Hexo/"}],"tags":[{"name":"杂项","slug":"杂项","permalink":"http://blog.wkaanig.cn/tags/杂项/"},{"name":"个人博客","slug":"个人博客","permalink":"http://blog.wkaanig.cn/tags/个人博客/"},{"name":"GitHub-Page","slug":"GitHub-Page","permalink":"http://blog.wkaanig.cn/tags/GitHub-Page/"}]},{"title":"Git Hook 远程推送至服务器实现自动部署","slug":"GitHook自动部署","date":"2019-09-10T12:34:31.660Z","updated":"2020-04-17T15:48:42.889Z","comments":true,"path":"post/e06b0099.html","link":"","permalink":"http://blog.wkaanig.cn/post/e06b0099.html","excerpt":"","text":"应用场景搭建Git 服务器需要准备一台运行 Linux 的机器,强烈推荐用 Ubuntu 或 Debian ,这样,通过几条简单的 apt 命令就可以完成安装。假设你已经有 sudo 权限的用户账号,下面,正式开始安装。 1. 服务器安装 git1$ sudo apt-get install git 2. 创建一个 git 用户用来运行 git 服务1$ sudo adduser git当然你也可以创建你想管理 git 的用户名 3. 创建证书登录收集所有需要登录的用户客户端的公钥,就是他们自己的 id_rsa.pub 文件,把所有公钥导入到/home/git/.ssh/authorized_keys 文件里,一行一个,下次你用git时就不需要输入用户名和密码了。 4. 服务器初始化Git仓库:先选定一个目录作为Git仓库,假定是 /home/git/code/test.git ,在目录下输入命令:1$ sudo git init --bare test.gitGit就会创建一个裸仓库,裸仓库没有工作区,因为服务器上的Git仓库纯粹是为了共享,所以不让用户直接登录到服务器上去改工作区,并且服务器上的Git仓库通常都以 .git 结尾。然后,把 owner 改为 git :1$ sudo chown -R git:git test.git一个空的git仓库就在服务器上建好了,仓库的地址为(可以本地测试一下 git clone 这个远程仓库):ssh://git@你的服务器ip:/home/git/code/test.git 5. 网站的根目录 git clone 服务器仓库123$ cd /var/www/html$ sudo git clone /home/git/code/test.git$ sudo chmod -R 777 ./test 6.为远程仓库设置 hook12$ cd /home/git/code/test.git/hooks$ vim post-receivepost-receive1234567#!/bin/shunset GIT_DIRDeployPath=\"/var/www/html/test\"cd $DeployPathgit pull origin masterecho \"推送完成\"exit 0为脚本添加可执行权限1$ sudo chmod +x post-receive 7. 客户端添加服务器远程仓库以后往这个服务器远程仓库 push 代码时,就会自动触发上面的脚本。12$ git remote add test git@你的服务器ip:/home/git/code/test.git //添加远程仓库并命名为 test$ git push test master 8. 后续代码的更新:github 有更新的时候 pull 更新本地部署仓库然后本地先 push 到测试服务器进行测试测试通过之后 push 到正式服务器进行上线代码的回滚:服务器端回滚:推荐1git reset --hard HEAD^本地仓库回滚: 无需登陆服务器即可实现代码回滚1git reset HEAD^保留代码回滚,然后使用1git push remote_name local_branch_name -f #强制推送状态查询命令 git status 9. 禁用 shell 登录出于安全考虑,第二步创建的 git 用户不允许登录 shell,这可以通过编辑 /etc/passwd 文件完成。找到类似下面的一行:1git:x:1001:1001:,,,:/home/git:/bin/bash改为:1git:x:1001:1001:,,,:/home/git:/usr/bin/git-shell这样, git 用户可以正常通过 ssh 使用 git,但无法登录 shell,因为我们为 git 用户指定的 git-shell 每次一登录就自动退出。 10.linux 拓展 1. 创建证书登录默认情况下,用户的 SSH 密钥存储在其 ~/.ssh 目录下。 进入该目录并列出其中内容,你便可以快速确认自己是否已拥有密钥:12[root@localhost ~] ls ~/.sshauthorized_keys id_rsa.pub在服务器端打开 RSA 认证在文件 /etc/ssh/sshd_config 中添加下列三行内容:123RSAAuthentication yesPubkeyAuthentication yesAuthorizedKeysFile .ssh/authorized_keys服务器导入 id_rsa.pub1234[root@localhost ~] cd ~git/.ssh[root@localhost .ssh] cat id_rsa.pub >> authorized_keys[root@localhost ~] cat authorized_keysssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCyQ6mcBiyiYiScdh9hBua8cXoOx59VVudyAkA+m+Gc+hUF09oKAyf5LlI1RJkbobX90L3afUexqnHT+hka1oaX4Gu7tfHYu7nJyGVPcteebJ14wNec750kUH0sS+f87U+Sb37Ynmh/FCCTUU+m/goimH5oe/gH8uSh3mFBlA+NKcBPRWCx7W44L5MK4YqcbddmjXsp+JAO6tHaYBn3GnLB3UzLbQHX222AGO6nByHNBmRHMXePaIzH76zWiy/OjiciJzRon/riftO+O+qOA9/+ZoB0KzycA0MeEOwqx5iWwRHzx8WrYufC9PZdvlKe/a4KxSG1XA15y69y0dFfl0CL root@localhost.localdomain 2.Linux 上用户创建与删除1234[root@localhost ~] adduser haha # 创建用户 haha 是用户名[root@localhost ~] passwd haha # 为该用户设置密码[root@localhost ~] userdel -r haha # 完全删除用户[root@localhost ~] find / -name \"*haha\" # 再使用 find 命令查看,用户相关文件已经删除。","categories":[{"name":"Git","slug":"Git","permalink":"http://blog.wkaanig.cn/categories/Git/"}],"tags":[{"name":"自动部署","slug":"自动部署","permalink":"http://blog.wkaanig.cn/tags/自动部署/"}]},{"title":"Python-Flask 使用 Sqlacodegen 从数据库表生成model.py","slug":"python-flask 使用 sqlacodegen 从数据库表生成model","date":"2019-09-10T12:32:49.039Z","updated":"2020-04-17T15:50:48.295Z","comments":true,"path":"post/7601b0d2.html","link":"","permalink":"http://blog.wkaanig.cn/post/7601b0d2.html","excerpt":"","text":"1、安装工具123456789PS E:\\Flask> pip install flask-sqlacodegenCollecting flask-sqlacodegen Downloading https://files.pythonhosted.org/packages/3b/2a/e47611e4fec19e33af5fc90dd57ec2b064056f6c433804742d66e80b2f57/flask_sqlacodegen-1.1.6.1-py2.py3-none-any.whlCollecting inflect>=0.2.0 (from flask-sqlacodegen) Downloading https://files.pythonhosted.org/packages/86/02/e6b11020a9c37d25b4767a1d0af5835629f6e75d6f51553ad07a4c73dc31/inflect-2.1.0-py2.py3-none-any.whl (40kB) |████████████████████████████████| 51kB 21kB/sRequirement already satisfied: SQLAlchemy>=0.6.0 in e:\\-avpfbmcx\\lib\\site-packages (from flask-sqlacodegen) (1.2.11)Installing collected packages: inflect, flask-sqlacodegenSuccessfully installed flask-sqlacodegen-1.1.6.1 inflect-2.1.0 2、生成model.py文件(这里我只生成两个表的模型)1flask-sqlacodegen 'mysql+cymysql://root:password@127.0.0.1/test' --tables goods,goods_attribute --outfile \"test.py\" --flask 3、查看文件1$ cat test.py12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455# coding: utf-8from sqlalchemy import Column, DateTime, Integer, Numeric, String, Textfrom flask_sqlalchemy import SQLAlchemydb = SQLAlchemy()class Good(db.Model): __tablename__ = 'goods' create_time = db.Column(db.DateTime) update_time = db.Column(db.DateTime) delete_time = db.Column(db.DateTime) id = db.Column(db.Integer, primary_key=True) category_id = db.Column(db.Integer, nullable=False, index=True) goods_sn = db.Column(db.String(255), nullable=False, index=True) name = db.Column(db.String(255), nullable=False) brand_id = db.Column(db.Integer, nullable=False, index=True) goods_num = db.Column(db.Integer, nullable=False, index=True) keywords = db.Column(db.String(255), nullable=False) goods_brief = db.Column(db.String(255), nullable=False) goods_desc = db.Column(db.Text) is_on_sale = db.Column(db.Integer, nullable=False) sort_order = db.Column(db.Integer, nullable=False, index=True) is_delete = db.Column(db.Integer, nullable=False) attribute_category = db.Column(db.Integer, nullable=False, index=True) counter_price = db.Column(db.Numeric(10, 2), nullable=False) extra_price = db.Column(db.Numeric(10, 2), nullable=False) is_new = db.Column(db.Integer, nullable=False) goods_unit = db.Column(db.String(255), nullable=False) primary_pic_url = db.Column(db.String(255), nullable=False) list_pic_url = db.Column(db.String(255), nullable=False) retail_price = db.Column(db.Numeric(10, 2), nullable=False) sell_volume = db.Column(db.Integer, nullable=False) primary_product_id = db.Column(db.Integer, nullable=False) unit_price = db.Column(db.Numeric(10, 2), nullable=False) promotion_desc = db.Column(db.String(255), nullable=False) promotion_tag = db.Column(db.String(255), nullable=False) app_exclusive_price = db.Column(db.Numeric(10, 2), nullable=False) is_app_exclusive = db.Column(db.Integer, nullable=False) is_limited = db.Column(db.Integer, nullable=False) is_hot = db.Column(db.Integer, nullable=False)class GoodsAttribute(db.Model): __tablename__ = 'goods_attribute' create_time = db.Column(db.DateTime) update_time = db.Column(db.DateTime) delete_time = db.Column(db.DateTime) id = db.Column(db.Integer, primary_key=True) goods_id = db.Column(db.Integer, nullable=False, index=True) attribute_id = db.Column(db.Integer, nullable=False, index=True) values = db.Column(db.Text) 大功告成!","categories":[{"name":"Python","slug":"Python","permalink":"http://blog.wkaanig.cn/categories/Python/"}],"tags":[{"name":"工具","slug":"工具","permalink":"http://blog.wkaanig.cn/tags/工具/"},{"name":"Flask","slug":"Flask","permalink":"http://blog.wkaanig.cn/tags/Flask/"}]},{"title":"商城系统项目搭建","slug":"商城系统项目搭建","date":"2019-09-10T12:32:49.035Z","updated":"2020-04-17T18:22:25.550Z","comments":true,"path":"post/9a26d224.html","link":"","permalink":"http://blog.wkaanig.cn/post/9a26d224.html","excerpt":"","text":"准备环境使用 python3 创建虚拟环境1python3 -m venv py3venv #创建一个py3venv的虚拟环境激活虚拟环境1source ./py3venv/bin/activate创建项目目录1mkdir shop为项目 shop 安装依赖1cd shop安装和卸载包12pip install flask # 安装包pip uinstall flask # 卸载包退出虚拟环境1deactivate: 退出虚拟环境初始化环境安装依赖12pip freeze >requirements.txt #生成全部依赖 requirements.txt用来记录项目所有的依赖包和版本号,只需要一个简单的pip命令就能完成。pip install -r requirements.txt #安装全部依赖requirements.txt1234567flaskflask-sqlalchemyflask-debugtoolbarmysqlclientflask_scriptrequestsuwsgi #Linux部署用,window会无法安装环境(application.py)1export ops_config=base #基本环境1export ops_config=local #本地环境1export ops_config=production #生产环境 mysql 踩坑 用 vscode 连接 mysql 时出现报错ER_NOT_SUPPORTED_AUTH_MODE: Client does not support authentication protocol requested by server; consider upgrading MySQL client```12345678910### **_node 使用 mysql 报错_**原因:登录数据库的客户端跟 mysql8.0 不兼容了,mysql8.0 密码认证采用了新的密码格式解决办法:在系统 mysql 终端输入下面命令```mysql//password 是你的数据库账户密码,root和host也是ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password'; 搭建项目目录创建项目根目录 shop1mkdir shop在 shop 目录下创建包 config 用来管理配置文件通用配置文件config/base_setting.py1234# -- coding: utf-8 --SERVER_PORT = 5000DEBUG = FalseSQLALCHEMY_ECHO = False本地配置文件config/local_setting.py123456# -- coding: utf-8 --DEBUG = TrueSQLALCHEMY_ECHO = TrueSQLALCHEMY_DATABASE_URI = 'mysql://root:mysql@127.0.0.1/mysql?charset=utf8mb4'SQLALCHEMY_TRACK_MODIFICATIONS = FalseSQLALCHEMY_ENCODING = \"utf8mb4\"生产配置文件config/production_setting.py1# -- coding: utf-8 --在 shop 目录下创建 application.py 封装 flask 的全局变量application.py12345678910111213141516171819# -- coding: utf-8 --from flask import Flaskfrom flask_script import Managerfrom flask_sqlalchemy import SQLAlchemyimport osclass Application( Flask ): def __init__(self,import_name): super( Application,self ).__init__( import_name ) self.config.from_pyfile( 'config/base_setting.py' ) if \"ops_config\" in os.environ: self.config.from_pyfile( 'config/%s_setting.py'%os.environ['ops_config'] ) db.init_app( self )db = SQLAlchemy()app = Application( __name__ )manager = Manager( app )在 shop 目录下创建 www.py 封装 HTTP 相关初始化www.py12345# -- coding: utf-8 --from application import appfrom web.controllers.index import route_indexapp.register_blueprint( route_index,url_prefix = \"/\" )在 shop 目录下创建 manager.py 启动入口manager.py123456789101112131415161718# -- coding: utf-8 --from application import app,managerfrom flask_script import Serverimport www##web servermanager.add_command( \"runserver\", Server( host='0.0.0.0',port=app.config['SERVER_PORT'],use_debugger = True ,use_reloader = True) )def main(): manager.run()if __name__ == '__main__': try: import sys sys.exit( main() ) except Exception as e: import traceback traceback.print_exc()在 shop 目录下创建 readme.mdreadme.md12345678910111213141516171819202122232425262728293031323334353637383940Python Flask 商城系统=====================##启动* export ops_config=local|production && python manage.py runserver##flask-sqlacodegen flask-sqlacodegen 'mysql://root:password@127.0.0.1/shop_db' --outfile \"common/models/model.py\" --flask flask-sqlacodegen 'mysql://root:password@127.0.0.1/shop_db' --tables user --outfile \"common/models/user.py\" --flask## 所见即所得编辑器ueditor <script src=\"{{ buildStaticUrl('/plugins/ueditor/ueditor.config.js') }}\"></script> <script src=\"{{ buildStaticUrl('/plugins/ueditor/ueditor.all.min.js') }}\"></script> <script src=\"{{ buildStaticUrl('/plugins/ueditor/lang/zh-cn/zh-cn.js') }}\"></script> UE.getEditor('editor',{ toolbars: [ [ 'undo', 'redo', '|', 'bold', 'italic', 'underline', 'strikethrough', 'removeformat', 'formatmatch', 'autotypeset', 'blockquote', 'pasteplain', '|', 'forecolor', 'backcolor', 'insertshopedlist', 'insertunshopedlist', 'selectall', '|','rowspacingtop', 'rowspacingbottom', 'lineheight'], [ 'customstyle', 'paragraph', 'fontfamily', 'fontsize', '|', 'directionalityltr', 'directionalityrtl', 'indent', '|', 'justifyleft', 'justifycenter', 'justifyright', 'justifyjustify', '|', 'touppercase', 'tolowercase', '|', 'link', 'unlink'], [ 'imagenone', 'imageleft', 'imageright', 'imagecenter', '|', 'insertimage', 'insertvideo', '|', 'horizontal', 'spechars','|','inserttable', 'deletetable', 'insertparagraphbeforetable', 'insertrow', 'deleterow', 'insertcol', 'deletecol', 'mergecells', 'mergeright', 'mergedown', 'splittocells', 'splittorows', 'splittocols' ] ], enableAutoSave:true, saveInterval:60000, elementPathEnabled:false, zIndex:4, serverUrl:common_ops.buildUrl( '/upload/ueditor' ) });##可参考资料* [python-Flask(jinja2)语法:过滤器](https://www.jianshu.com/p/3127ac233518)* [SQLAlchemy 各种查询语句写法](https://wxnacy.com/2017/08/14/python-2017-08-14-sqlalchemy-filter/)在 shop 目录下创建 requirements.txtrequirements.txt123456flaskflask-sqlalchemyflask-debugtoolbarmysqlclientflask_scriptrequests在 shop 目录下创建 common 包 存放公用部分common/__init__.py1# -- coding: utf-8 --common/libs/__init__.py1# -- coding: utf-8 --common/models/__init__.py1# -- coding: utf-8 --在 shop 目录下创建 doc 目录 存放存放文档doc/mysql.md12数据库变更记录==================在 shop 目录下创建 jobs 包 用来存放一些定时的任务jobs/__init__.py_1# -- coding: utf-8 --jobs/task/__init__.py_1# -- coding: utf-8 --在 shop 目录下创建 web 包用来存放蓝图web/__init__.py1# -- coding: utf-8 --web/controllers/index.py1234567from flask import Blueprintroute_index = Blueprint( 'index_page',__name__ )@route_index.route(\"/\")def index(): return 'hello'web/controllers/__init__.py1# -- coding: utf-8 -- 简单测试在终端添加环境变量1export ops_config=local启动项目1python manage.py runserver输入测试 url1http://127.0.0.1:5000/","categories":[{"name":"Python","slug":"Python","permalink":"http://blog.wkaanig.cn/categories/Python/"}],"tags":[{"name":"Flask","slug":"Flask","permalink":"http://blog.wkaanig.cn/tags/Flask/"},{"name":"商城","slug":"商城","permalink":"http://blog.wkaanig.cn/tags/商城/"}]},{"title":"操作系统引论","slug":"操作系统引论","date":"2019-09-10T12:32:49.018Z","updated":"2020-04-17T15:49:52.274Z","comments":true,"path":"post/f9a25cd7.html","link":"","permalink":"http://blog.wkaanig.cn/post/f9a25cd7.html","excerpt":"","text":"一、操作系统的目标与作用操作系统(Operating System)是配置在计算机硬件上的第一层软件,是对计算机系统的首次扩充。其主要作用是管理好这些设备,提高他们的利用率和系统的吞吐量,并为用户和应用程序提供一个简单的接口,便于用户使用。 操作系统的目标方便性有效性可扩充性开放性 操作系统的作用os作为用户与计算机硬件系统之间的接口os作为计算机系统资源的管理者os实现了对计算机资源的抽象 推动操作系统发展的主要动力不断提高计算机资源的利用率方便用户器件不断的更新换代计算机体系结构的不断发展不断提出新的应用需求 二、计算机操作系统发展的过程 未配置操作系统的计算机系统人工操作方式脱机输入输出方式单道批处理系统单道批处理系统最主要的缺点是系统中的资源得不到充分利用多道批处理系统的优缺点资源利用率高。系统吞吐量大能提高系统存储量的主要原因,可归纳为CPU和其他资源保持忙碌状态仅当作业完成时或运行不下去时才进行切换系统开销小平均周转时间长无交互能力分时系统(time sharing system)推动分时系统形成和发展的主要动力则是为了满足用户对人机交互的需求,由此形成了一种新型os实时系统(Real time system)实时系统最主要的特征是将时间作为关键参数,它必须对所接收到的某些信号作出及时或实时的反应。实时系统的类型工业武器控制系统信息查询系统多媒体系统。嵌入式系统。 三、操作系统的基本特征并发并行与并发并行是指两个或多个事件在同一时刻发生并发是指两个或多个事件在同一时间间隔内发生引用进程在一个未引入进程的系统中,在属于同一个应用程序的计算机程序和I/O程序之间只能是顺序执行,既只有在计算机程序执行告一段落后才引起I/o执行,反之在程序执行I/O操作时,计算机程序也不能执行,但在为计算程序和Io程序分别建立一个进程后,两个进程便可并发执行。这样便能极大的提高系统资源的利用率,增加系统的吞吐量。共享互斥共享方式。同时访问方式。虚拟时分复用技术。空分复用技术。异步 四、操作系统的主要功能处理机管理功能。进程控制进程同步进程通信调度存储器管理功能内存分配,内存保护地址映设内存扩充设备管理功能。缓冲管理,设备分配,设备处理。文件管理功能文件存储空间的管理目录管理文件读写管理与保护。操作系统与用户之间的接口用户接口与程序接口。现代操作系统的新功能系统安全网络的功能和服务支持多媒体。","categories":[{"name":"操作系统","slug":"操作系统","permalink":"http://blog.wkaanig.cn/categories/操作系统/"}],"tags":[{"name":"杂项","slug":"杂项","permalink":"http://blog.wkaanig.cn/tags/杂项/"}]},{"title":"腾讯云 Ubuntu 开启 Root 用户登录并修改系统语言为中文","slug":"ubuntu 开启 root 用户登录","date":"2019-09-10T12:32:49.010Z","updated":"2020-04-17T15:50:22.745Z","comments":true,"path":"post/d436f64e.html","link":"","permalink":"http://blog.wkaanig.cn/post/d436f64e.html","excerpt":"","text":"一、腾讯讯云主机开启 root 用户登录如下:腾讯云主机ubuntu 系统默认用户名为 ubuntu1.修改root密码1234sudo passwd rootEnter new UNIX password: // 输入新密码Retype new UNIX password: // 重复密码passwd: password updated successfully // 修改成功2.修改 sshd_config 配置如下12345vi /etc/ssh/sshd_config# Authentication:LoginGraceTime 120PermitRootLogin yesStrictModes yes3.最后重启下ssh1sudo service ssh restart 二、修改系统语言为中文1.查看当前语言环境1echo $LANG2.查看当前系统是否有中文语言包(zh_CN.utf8)1locale -a3.安装中文语言包1apt install language-pack-zh-hans4.再次查看是否有中文语言包1locale -a5.修改系统环境变量1vi ~/.bashrc加入下面这一行:1LANG=\"zh_CN.utf8\"6.执行修改1source ~/.bashrc此时已更改成功 三、更新系统(可选)12apt-get update apt-get dist-upgrade","categories":[{"name":"Linux","slug":"Linux","permalink":"http://blog.wkaanig.cn/categories/Linux/"}],"tags":[{"name":"ubuntu","slug":"ubuntu","permalink":"http://blog.wkaanig.cn/tags/ubuntu/"}]},{"title":"Linux 文件常用操作命令","slug":"Linux 文件常用操作命令","date":"2019-09-10T12:32:49.004Z","updated":"2020-04-17T15:49:17.337Z","comments":true,"path":"post/61f63005.html","link":"","permalink":"http://blog.wkaanig.cn/post/61f63005.html","excerpt":"","text":"压缩与解压文件123456tar-c: 建立压缩档案-x:解压-t:查看内容-r:向压缩归档文件末尾追加文件-u:更新原压缩包中的文件这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用但只能用其中一个。下面的参数是根据需要在压缩或解压档案时可选的。-z:有gzip属性的-j:有bz2属性的-Z:有compress属性的-v:显示所有过程-O:将文件解开到标准输出下面的参数-f是必须的-f: 使用档案名字,切记,这个参数是最后一个参数,后面只能接档案名。示例:12345678910tar -cf all.tar *.jpg这条命令是将所有.jpg的文件打成一个名为all.tar的包。-c是表示产生新的包,-f指定包的文件名。tar -rf all.tar *.gif这条命令是将所有.gif的文件增加到all.tar的包里面去。-r是表示增加文件的意思。tar -uf all.tar logo.gif这条命令是更新原来tar包all.tar中logo.gif文件,-u是表示更新文件的意思。tar -tf all.tar这条命令是列出all.tar包中所有文件,-t是列出文件的意思tar -xf all.tar这条命令是解出all.tar包中所有文件,-t是解开的意思 压缩123456tar -cvf jpg.tar *.jpg //将目录里所有jpg文件打包成tar.jpg tar -czf jpg.tar.gz *.jpg //将目录里所有jpg文件打包成jpg.tar后,并且将其用gzip压缩,生成一个gzip压缩过的包,命名为jpg.tar.gztar -cjf jpg.tar.bz2 *.jpg //将目录里所有jpg文件打包成jpg.tar后,并且将其用bzip2压缩,生成一个bzip2压缩过的包,命名为jpg.tar.bz2tar -cZf jpg.tar.Z *.jpg //将目录里所有jpg文件打包成jpg.tar后,并且将其用compress压缩,生成一个umcompress压缩过的包,命名为jpg.tar.Zrar a jpg.rar *.jpg //rar格式的压缩,需要先下载rar for linuxzip jpg.zip *.jpg //zip格式的压缩,需要先下载zip for linux 文件压缩tar -zcvf 打包后生成的文件名全路径 要打包的目录把/xahot文件夹打包后生成一个/home/xahot.tar.gz的文件。1tar -zcvf /home/xahot.tar.gz /xahotzip 压缩方法:压缩当前的文件夹 zip -r ./xahot.zip ./ -r表示递归*1zip [参数] [打包后的文件名] [打包的目录路径] 解压123456tar -xvf file.tar //解压 tar包tar -xzvf file.tar.gz //解压tar.gztar -xjvf file.tar.bz2 //解压 tar.bz2tar -xZvf file.tar.Z //解压tar.Zunrar e file.rar //解压rarunzip file.zip //解压zip 总结1234567891、*.tar 用 tar -xvf 解压2、*.gz 用 gzip -d或者gunzip 解压3、*.tar.gz和*.tgz 用 tar -xzf 解压4、*.bz2 用 bzip2 -d或者用bunzip2 解压5、*.tar.bz2用tar -xjf 解压6、*.Z 用 uncompress 解压7、*.tar.Z 用tar -xZf 解压8、*.rar 用 unrar e解压9、*.zip 用 unzip 解压示例:解压jdk到指定文件夹:1tar -xzvf jdk-8u131-linux-x64.tar.gz -C /usr/local/java","categories":[{"name":"Linux","slug":"Linux","permalink":"http://blog.wkaanig.cn/categories/Linux/"}],"tags":[{"name":"命令","slug":"命令","permalink":"http://blog.wkaanig.cn/tags/命令/"}]},{"title":"C# 中常用的类和结构","slug":"C# 中常用的类和结构","date":"2019-09-10T12:32:48.967Z","updated":"2020-04-17T15:46:49.002Z","comments":true,"path":"post/12e9bef1.html","link":"","permalink":"http://blog.wkaanig.cn/post/12e9bef1.html","excerpt":"","text":"String类(C#中 String 与 string 具有相同的含义)静态CompareConcatFormat非静态方法ContainsCompareToEqualsIndexOfInsertRemoveReplaceSplitSubstringTrim","categories":[{"name":"C#","slug":"C","permalink":"http://blog.wkaanig.cn/categories/C/"}],"tags":[{"name":"基础知识","slug":"基础知识","permalink":"http://blog.wkaanig.cn/tags/基础知识/"}]}],"categories":[{"name":"前端","slug":"前端","permalink":"http://blog.wkaanig.cn/categories/前端/"},{"name":"Python","slug":"Python","permalink":"http://blog.wkaanig.cn/categories/Python/"},{"name":"python","slug":"python","permalink":"http://blog.wkaanig.cn/categories/python/"},{"name":"杂项","slug":"杂项","permalink":"http://blog.wkaanig.cn/categories/杂项/"},{"name":"Docker","slug":"Docker","permalink":"http://blog.wkaanig.cn/categories/Docker/"},{"name":"算法","slug":"算法","permalink":"http://blog.wkaanig.cn/categories/算法/"},{"name":"数据结构","slug":"数据结构","permalink":"http://blog.wkaanig.cn/categories/数据结构/"},{"name":"Hexo","slug":"Hexo","permalink":"http://blog.wkaanig.cn/categories/Hexo/"},{"name":"Git","slug":"Git","permalink":"http://blog.wkaanig.cn/categories/Git/"},{"name":"操作系统","slug":"操作系统","permalink":"http://blog.wkaanig.cn/categories/操作系统/"},{"name":"Linux","slug":"Linux","permalink":"http://blog.wkaanig.cn/categories/Linux/"},{"name":"C#","slug":"C","permalink":"http://blog.wkaanig.cn/categories/C/"}],"tags":[{"name":"js","slug":"js","permalink":"http://blog.wkaanig.cn/tags/js/"},{"name":"Flask","slug":"Flask","permalink":"http://blog.wkaanig.cn/tags/Flask/"},{"name":"Django","slug":"Django","permalink":"http://blog.wkaanig.cn/tags/Django/"},{"name":"基础知识","slug":"基础知识","permalink":"http://blog.wkaanig.cn/tags/基础知识/"},{"name":"个人博客","slug":"个人博客","permalink":"http://blog.wkaanig.cn/tags/个人博客/"},{"name":"工具","slug":"工具","permalink":"http://blog.wkaanig.cn/tags/工具/"},{"name":"Linux","slug":"Linux","permalink":"http://blog.wkaanig.cn/tags/Linux/"},{"name":"杂项","slug":"杂项","permalink":"http://blog.wkaanig.cn/tags/杂项/"},{"name":"GitHub-Page","slug":"GitHub-Page","permalink":"http://blog.wkaanig.cn/tags/GitHub-Page/"},{"name":"自动部署","slug":"自动部署","permalink":"http://blog.wkaanig.cn/tags/自动部署/"},{"name":"商城","slug":"商城","permalink":"http://blog.wkaanig.cn/tags/商城/"},{"name":"ubuntu","slug":"ubuntu","permalink":"http://blog.wkaanig.cn/tags/ubuntu/"},{"name":"命令","slug":"命令","permalink":"http://blog.wkaanig.cn/tags/命令/"}]}