学习笔记_学习笔记一 - CSDN
精华内容
参与话题
  • 学习笔记(个人记录)

    千次阅读 2017-12-27 20:15:55
    nginx学习笔记,记录用

    nginx学习笔记(一)—-关于nginx的性能优化

    笔记用于记录一下nginx的学习,大部分都是转载网络上的知识,自己加以理解和整理。

     在工作中使用nginx-rtmp模块作为直播服务器,但是在部署应用过程中碰到了一些问题的,所以学习下nginx的性能优化,吸收下前辈们学习的经验。
    

    1.nginx的异步非阻塞
    今天看到一篇文章,讲的是 Nginx的异步非阻塞,正好项目中碰到点nginx的问题,先学习记录下,下面是文章的连接。

    http://blog.csdn.net/dutsoft/article/details/55224755
    配置是这样的:

    events {
        worker_connections  1024;
        use kqueue;  # 在Linux中配置:use epoll;
    }

    意思是开启nginx的异步非阻塞工作方式,使用这种方式能轻松处理高并发的问题(此功能在windows下无法开启,识别不了两种方式,待研究)


    2.设置nginx进程

    worker_processes 3;

    一般来说,服务器有几个逻辑cpu就设置几个进程,逻辑cpu就是我们通常说的几核
    这里先记录下,测试ab -n 20000 -k http://www.1990y.com/p.php 还有加-c的问题(之后研究)


    3.优化 Nginx 连接超时时间

    https://www.cnblogs.com/pzk7788/p/6923614.html
    (1) keepalive_timeout :该参数用于设置客户端连接保持会话的超时时间,超过这个时间服务器会关闭该连接
    (2) client_header_timeout :该参数用于设置读取客户端请求头数据的超时时间,如果超时客户端还没有发送完整的 header 数据,服务器将返回 “Request time out (408)” 错误
    (3) client_body_timeout :该参数用于设置读取客户端请求主体数据的超时时间,如果超时客户端还没有发送完整的主体数据,服务器将返回 “Request time out (408)” 错误
    (4) send_timeout :用于指定响应客户端的超时时间,如果超过这个时间,客户端没有任何活动,Nginx 将会关闭连接
    (5) tcp_nodelay :默认情况下当数据发送时,内核并不会马上发送,可能会等待更多的字节组成一个数据包,这样可以提高 I/O 性能,但是,在每次只发送很少字节的业务场景中,使用 tcp_nodelay 功能,等待时间会比较长

    这里还要考虑,nginx-rtmp模块可以用的设置

    展开全文
  • 学习笔记---个人觉得很好用的网站

    千次阅读 2018-07-15 10:28:01
    从2015年上大学开始就一直学习前端啦,从一开始的小白,到现在的入门,真的说前端要学习的东西真的还有很多。在这里分享一下我常用的小网站或者我在学习的时候看到别人推荐的网站。1.http://www.bootcss.com/基本...

    从2015年上大学开始就一直学习前端啦,从一开始的小白,到现在的入门,真的说前端要学习的东西真的还有很多。

    在这里分享一下我常用的小网站或者我在学习的时候看到别人推荐的网站。

    1.http://www.bootcss.com/

    基本入门都会学习这个吧,我学习的时候是三,最近我去看发现它出四了,真的很厉害,而且这个是中文的,我一个前端小白慢慢琢磨也就会用了,首页的底下有一些链接网站,我就是在那里看到很多其他很好用的工具。


    2.http://www.iconfont.cn/plus

    这个是提供图标的网站,我很喜欢里面那些精致的图表,虽然有一些图表不是那么容易的能够搜索到,但是使用起来很方便,选好之后加入项目里面,就会打包下载下来,然后解压打开里面提供的三个网页,分别代表三种不同的方法,根据方法添加到代码里面就可以的了。还可以直接下载图片,这个连登录都不用就可以下载图片。最开始我还被这个网站的动态背景惊艳了一下呢!

    3.开源中国

    这里有很多开源的资源,我在这里用过很多前端的插件,比如说有一个名字叫做H5DS的点石H5编辑器,还有JSearch网页搜索的插件等等,这里也可以下载编辑器,我是觉得像逛街一样在这里淘自己想学的小东西

    4.在学JQuery的时候遇到的几个网站:

    4-1:jQuery之家

    一开始是为了找图片轮播,这里的图片轮播真的厉害,我一开始想学习图片轮播的时候以为只有下面有个小数字然后一张张播放的样子,后面才知道有好多种,比如风琴式,巨幕式,我要学的还有很多。

    4-2jQuery EasyUI中文网

    这个网站什么时候开始用的不记得了,但是在我用LayUI的时候觉得这两个很像

    5.接下这两个是UI那边的,渐变色,我最近很喜欢用渐变色来做背景,很有高级感

    5-1:uigradients


    5-2CoolHue

    6.慕课网

    我在这里学完了js和jQuery的基础,这里的老师讲课是一方面,我觉得在孤独的学习代码的时候看下网友的评论就蛮有动力的,而且网友真的很有才啊!

    还有好多网站的,只是我暂时只能熟练操作这几个网站,适合和我一样的新手小白学习前端的时候用哦!

    展开全文
  • JavaScript学习笔记(三)Js正则、DOM

    千次阅读 多人点赞 2018-09-23 00:09:03
    学习目标 DOM 正则表达式 一、DOM 1、概述 DOM对象:Document Object Model 文档对象模型、作用、通过DOM对象可以访问和操作html文件的每个标签、 html文档加载到浏览器的内存中后、我们认为形成了一颗DOM...

    学习目标

    DOM

    正则表达式

    一、DOM

    1、概述

    DOM对象:Document Object  Model 文档对象模型、作用、通过DOM对象可以访问和操作html文件的每个标签、

    html文档加载到浏览器的内存中后、我们认为形成了一颗DOM树、而任何一个html签、标签属性和文本都是这个树上的节点元素。

    我们可以通过js的DOM组件中的方法对内存中的DOM树上的结构和内容进行修改,即通过js动态修改内存中的那一份html及css的代码。

    当浏览器把一个html文件加载到内存中之后,这个html文件,就是一个Document对象。可以使用js技术结合Document对象,对html文件中的所有标签,进行各种操作。

    在浏览器把html文件加载完成之后,标签被称作标签对象(元素节点),标签中的文件称为文本节点(文本对象),标签的属性称为属性节点(属性对象)。

    1、获取id

    document.getElementById("ID名");                返回指定的id对象

    
    <input type="submit" value="点击" id="btn" />
    <script>
        window.onload = function () {
            // id 编号
            var btn = document.getElementById("btn");
    
            btn.onclick = function () {
                alert("获取成功!");
            }
        }
    </script>
    

    2、获取name值 

    document.getElementsByName("name名");      返回指定name值的对象集合

    <input type="text" name="tname" value="王者荣耀_1" /> <br />
    <input type="text" name="tname" value="王者荣耀_2" /> <br />
    <input type="text" name="tname" value="王者荣耀_3" /> <br />
    <input type="button" name="ok" value="保存" />
    
    <script>
        window.onload = function () {
            // name = tname 的标签
            var inputs = document.getElementsByName("tname");
            alert("inputs.length = " + inputs.length);
    
            // 遍历
            for (var i = 0; i < inputs.length; i++) {
                // 取出每一个
                alert(i + " = " + inputs[i].value);
    
                // 给 input 每一个标签绑定一个 onchange 事件.
                inputs[i].onchange = function () {
                    // 内容发生更改, 需要查询 `当前元素 this` 更改后的内容
                    alert(this.value);
                }
            }
        }
    </script>
    

    2.1、获取类名:

    document.getElementsByClassName("class名"); 返回指定class名的对象集合

    <input type="text" name="tname" value="王者荣耀_1" class = "test"/> <br />
    <input type="text" name="tname" value="王者荣耀_2" class="test" /> <br />
    <input type="text" name="tname" value="王者荣耀_3" /> <br />
    <input type="button" name="ok" value="保存" />
    
    <script>
    window.onload = function () {
            // class = test 的标签
            var inputs = document.getElementsByClassName("test");
            alert("inputs.length = " + inputs.length);
    
        }
    </script>
    

    2.2、获取标签名:

    document.getElementsByTagName("标签名");          返回指定标签名的对象集合

    <select name="edu" id="edu">
        <option value="博士">博士</option>
        <option value="硕士">硕士</option>
        <option value="本科">本科</option>
        <option value="幼儿园">幼儿园</option>
    </select>
    
    <script>
        window.onload = function () {
            // tagName 标签名称
            var options = document.getElementsByTagName("option");
            alert(options.length);
    
            for (var i = 0; i < options.length; i++) {
                alert(i + " = " + options[i].value);
            }
        }
    </script>
    

    2.3、获取标签内容:

    element.innerHTML;        获取标签内部的所有内容

    element.innerText;                 获取标签内部的文本内容

    <body>
        <div id="box">
            来不来。
            <h1>一起吃饭去!</h1>
        </div>
    </body>
    
    <script>
        window.onload = function () {
    
            var box = document.getElementById("box");
    
            // innerHTML  (推荐使用)
            alert(box.innerHTML);  // <h1>内容<h1>
    
            // innerText
            alert(box.innerText);
        }
    </script>
    

    3、节点/元素的操作

    3.1、判断是否有子节点

    hasChildNodes();    判断是否含有子节点,返回true或false

    <body>
    <div id="go">
        来不来。
        <h1  id = "come">一起吃饭去!</h1>
    </div>
    <div id = "empty"></div>
    </body>
    
    <script>
        window.onload = function () {
    
            // hasChildNodes 是否包含子节点
            // 1. go 标签
            var go = document.getElementById("go");
            alert(go.hasChildNodes());          // true
            
            // 2. come 标签
            var come = document.getElementById("come");
            alert(come.hasChildNodes());        // true
    
            // 3. empty 标签
            var empty = document.getElementById("empty");
            alert(empty.hasChildNodes());       // false
        }
    </script>
    

    3.2、删除节点

    remove();                                    删除当前标签对象,等同于自杀

    removeChild(childElement);         通过父标签对象删除子标签对象

    parentElement                                  父标签对象

     

    <body>
        <ul id="city">
            <li id="bj">北京</li>
            <li id="sh">上海</li>
            <li id="gz">广州</li>
        </ul>
    </body>
    
    <script>
        window.onload = function () {
    
            // 直接删除北京  remove();
            var bj = document.getElementById("bj");
            bj.remove();
    
            // 通过 city 删除上海  parent 调用 removeChild 删除孩子.
            var city = document.getElementById("city");
            var sh = document.getElementById("sh");
            city.removeChild(sh);
    
            // 通过父节点自杀
            var gz = document.getElementById("gz");
            gz.parentElement.removeChild(gz);
        }
    </script>
    

    3.3、替换节点

    replaceChild(newChild,oldChild); 替换父节点下的子节点. 注意: 需要使用父节点对象调用该方法

    你喜欢的城市 : <br />
    <ul id="city">
        <li id="bj">北京</li>
        <li id="sh">上海</li>
    </ul>
    
    你喜欢的游戏 : <br />
    <ul>
        <li id="fk" value="fankong">反恐精英</li>
        <li id="ms" value="moshou">魔兽</li>
    </ul>
    
    <script>
        window.onload = function () {
            // 需求: 点击 `北京` 节点, 使用 `反恐精英` 节点实现替换
            // replaceChild(newChild, oldChild);  注意: 该方法需要使用 `父节点` 实现调用.
    
            // 1. 获取标签对象
            var city = document.getElementById("city");
            var bj = document.getElementById("bj");
            var fk = document.getElementById("fk");
    
            // 2. 调用方法
            bj.onclick = function () {
                city.replaceChild(fk, bj);
            }
        }
    </script>
    

    3.4、创建元素

    document.createElement("tagName");         创建标签对象

    需要与appendChild() insertBefore()方法联合使用

    // 创建节点
    document.createElement("li");
    

    ​​​​​3.5、新增子节点

    appendChild(newChild);              向父标签内部末尾处追加子节点
     

    <ul id="city">
        <li id="bj" value="beijing">北京</li>
        <li id="sh" value="shanghai">上海</li>
        <li id="cq" value="chongqing">重庆</li>
    </ul>
    
    <script>
        window.onload = function () {
    
            // 1. 创建节点
            var newLi = document.createElement("li");
            // 2. 设置内容
            newLi.innerHTML = "天津";
    
            // 3. 拼接节点
            var city = document.getElementById("city");
            city.appendChild(newLi);
        }
    </script>
    

    insertBefore(newChild,refChild);	向父标签下指定的子节点前添加标签对象. 注意:使用父标签调用该方法
    <script>
        window.onload = function () {
    
            // 1. 创建节点
            var newLi = document.createElement("li");
            // 2. 设置内容
            newLi.innerHTML = "天津";
    
            // 需求 : 将城市节点 <li>天津</li> 放置到北京和上海的中间
            var city = document.getElementById("city");
            var sh = document.getElementById("sh");
            city.insertBefore(newLi, sh);
        }
    </script>
    

    4、标签属性的操作

    4.1、获取属性

    element.getAttribute("name")  或者  element.属性名    :获得属性的值

    一般来说,我们直接使用element.属性名即可,如果这种方法不行,就采用上述的方式来获取。

    <input type="text" id="txt" value="请输入用户名" class="baidu" />
    <script>
        window.onload = function () {
    
            // 1. 获取 input 标签
            var input = document.getElementById("txt");
    
            // 2. 获取属性
            alert(input.value);
    
            alert(input.getAttribute("value"));
    
            alert(input.getAttribute("class"));
        }
    </script>
    

    4.2、设置属性

    element.setAttribute("name","value"):设置属性的值。以直接采用element.属性名通过单等号来赋值

    // 需求 : 给input添加一个name属性   name="username"

    <script>
        window.onload = function () {
    
            // 1. 获取 input 标签
            var input = document.getElementById("txt");
    
            // 需求 : 给input添加一个name属性   name="username"
            // input.name = "username";
    
            input.setAttribute("name", "username2");
        }
    </script>
    
    <input type="text" id="txt" value="请输入用户名" class="baidu" />

    在浏览器开发者工具里可以看到:如下图

    4.3、删除属性

    element.removeAttribute("name"); 删除某个属性

    // 需求 : 删除 input 的 value 属性

    <input type="text" id="txt" value="请输入用户名" class="baidu" />
    <script>
        window.onload = function () {
    
            // 1. 获取 input 标签
            var input = document.getElementById("txt");
    
            // 需求 : 删除 input 的 value 值
            input.removeAttribute("value");
        }
    </script>
    

    5、css样式的修改

    obj.style.样式名               获取值    

    obj.style.样式名=值         修改值       修改的值的格式必须跟css一模一样,也就是说有单位的必须加单位

    <div id="box" style="width: 200px; height: 200px; background-color: pink;"></div>
    <script>
        window.onload = function () {
    
            // 1. 获取 box 标签
            var box = document.getElementById("box");
    
            // 2. 设置 box 的属性值
            box.style.width = "100px";
            box.style.height = "100px";
            box.style.backgroundColor = "skyblue";
        }
    </script>
    

    6、案列

    6.1、商品全选全不选反选 

    html代码:

    <body>
        <table id="table" border="1" width="100%" align="center" style="text-align: center;">
            <tr>
                <td colspan="5" align="left">
                    <input id="uncheckBtn" type="button" value="全不选" />
                    <input id="reverseBtn" type="button" value="反选" />
                </td>
    
            </tr>
            <tr>
                <th>全选<input id="all" type="checkbox" /></th>
                <th>分类ID</th>
                <th>分类名称</th>
                <th>分类描述</th>
                <th>操作</th>
            </tr>
            <tr>
                <td><input type="checkbox" class="itemSelect" /></td>
                <td>1</td>
                <td>手机数码</td>
                <td>手机数码类商品</td>
                <td><a href="javascript:;">修改</a>|<a href="javascript:;">删除</a></td>
            </tr>
            <tr>
                <td><input type="checkbox" class="itemSelect" /></td>
                <td>2</td>
                <td>电脑办公</td>
                <td>电脑办公类商品</td>
                <td><a href="javascript:;">修改</a>|<a href="javascript:;">删除</a></td>
            </tr>
            <tr>
                <td><input type="checkbox" class="itemSelect" /></td>
                <td>3</td>
                <td>鞋靴箱包</td>
                <td>鞋靴箱包类商品</td>
                <td><a href="javascript:;">修改</a>|<a href="javascript:;">删除</a></td>
            </tr>
            <tr>
                <td><input type="checkbox" class="itemSelect" /></td>
                <td>4</td>
                <td>家居饰品</td>
                <td>家居饰品类商品</td>
                <td><a href="javascript:;">修改</a>|<a href="javascript:;">删除</a></td>
            </tr>
        </table>
    </body>
    

    js代码实现:

    <script>
        window.onload = function () {
    
            // 需求 : 全选
            // 1.1 获取全选按钮的选择框元素
            var all = document.getElementById("all");
            // 1.2 获取所有的 itemSelect 标签
            var itemSelects = document.getElementsByClassName("itemSelect");
    
            // 2. 给全选按钮绑定单击事件
            all.onclick = function () {
    
                // 3. 获取全选按钮的当前状态属性值
                // var checked = all.getAttribute("checked");  不适用
                var checked = all.checked;
                // alert("checked = " + checked);
    
                // 4. 遍历 itemSelects 数组
                for (var i = 0; i < itemSelects.length; i++) {
                    itemSelects[i].checked = checked;
                }
            }
    
            // 需求 : 全不选
            var uncheckBtn = document.getElementById("uncheckBtn");
            uncheckBtn.onclick = function () {
                for (var i = 0; i < itemSelects.length; i++) {
                    itemSelects[i].checked = false;
                }
                all.checked = false;
            }
    
            // 需求 : 反选
            var reverseBtn = document.getElementById("reverseBtn");
            reverseBtn.onclick = function () {
    
                // 定义一个 count 计算器
                var count = 0;
    
                // 遍历 itemSelects 数组
                for (var i = 0; i < itemSelects.length; i++) {
    
                    // 方式一 : 判断
                    if (itemSelects[i].checked == true) {
                        itemSelects[i].checked = false;
                    } else {
                        itemSelects[i].checked = true;
                        // 计算为 true 的数量
                        count++;
                    }
    
                    // 方式二 : 取反
                    // itemSelects[i].checked = !itemSelects[i].checked;
    
                    // 方式三 : 让 checkbox 被点击一下. 方法: click();
                    // itemSelects[i].click();
                }
    
                // 遍历结束后, 实现判断
                if (count == itemSelects.length) {
                    all.checked = true;
                } else {
                    all.checked = false;
                }
            }
        }
    </script>
    

    6.2、隔行换色

    思路 : 获取 tr 行, 设置背景色.

    html代码:同上

    js代码:

    <script>
        window.onload = function () {
    
            // getElementsByTagName(tr标签);
            // 1. 获取所有的 tr 标签
            var trs = document.getElementsByTagName("tr");
            // alert("trs.length = " + trs.length);
    
            // 2. 遍历 trs 数组
            for (var i = 2; i < trs.length; i++) {
    
                // 3. 判断
                if (i % 2 == 0) {
                    trs[i].style.backgroundColor = "yellow";
                } else {
                    trs[i].style.backgroundColor = "skyblue";
                }
            }
        }
    </script>
    

     

    6.3、鼠标移入变色, 移除还原 :  onmouseover, onmouseout

    html代码同上:

    js代码如下:

    <script>
        window.onload = function () {
    
            // getElementsByTagName(tr标签);
            // 1. 获取所有的 tr 标签
            var trs = document.getElementsByTagName("tr");
            // alert("trs.length = " + trs.length);
    
            // 定义一个 color 属性
            var color;
    
            // 2. 遍历 trs 数组
            for (var i = 2; i < trs.length; i++) {
    
                // 3. 判断
                if (i % 2 == 0) {
                    trs[i].style.backgroundColor = "yellow";
                } else {
                    trs[i].style.backgroundColor = "skyblue";
                }
    
                // 4. 为每一行绑定一个 `鼠标移入 onmouseover` 事件
                trs[i].onmouseover = function () {
                    // 记录当前行颜色
                    color = this.style.backgroundColor;
                    // trs[i].style.backgroundColor = "#ccc";  // 行不通. (在函数内部不能使用循环变量 i)
                    // 当前行实现变色
                    this.style.backgroundColor = "#ccc";
                }
    
                // 5. 为每一行绑定一个 `鼠标移出 onmouseout` 事件
                trs[i].onmouseout = function () {
                    this.style.backgroundColor = color;
                }
            }
        }
    </script>
    

     

    6.4、下拉列表、二级联动

    效果图:

    html代码:

    <body>
        <select id="province">
            <option value="none">--请选择省--</option>
            <option value="0">北京市</option>
            <option value="1">上海市</option>
            <option value="2">广州市</option>
        </select>
        <select id="city">
            <option value="none">--请选择市--</option>
        </select>
    </body>
    

    实现方案一 : city.innerHTML

    <script>
        window.onload = function () {
    
            // 1. 先准备区县的数组
            var cities = [
                ["朝阳区", "海淀区", "丰台区", "昌平区", "西城区", "东城区", "通州区", "大兴区"],
                ["浦东新区", "闵行区", "静安区", "徐汇区", "杨浦区", "嘉定区", "黄埔区"],
                ["白云区", "天河区", "花都区", "番禺区"]
            ];
    
            // 2. 获取 `省` 和 `市` 的标签
            var province = document.getElementById("province");
            var city = document.getElementById("city");
    
            // 3. 监听省份发生更改事件
            province.onchange = function () {
    
                // 注意: 清除 `区县` 信息
                city.innerHTML = "<option value=\"none\">--请选择市--</option>";
    
                // 4. 获取 `省份` 对应的value数值
                var index = province.value;
    
                // 5. 根据获取的 index, 遍历 cities 二维数组中对应的 `一维数组`.
                for (var i = 0; i < cities[index].length; i++) {
    
                    // 方式一 : innerHTML
                    city.innerHTML += "<option value=\"none\">"+ cities[index][i] +"</option>";
                }
            }
        }
    </script>
    

    实现方案二 : city.appendChild();

    <script>
        window.onload = function () {
    
            // 1. 先准备区县的数组
            var cities = [
                ["朝阳区", "海淀区", "丰台区", "昌平区", "西城区", "东城区", "通州区", "大兴区"],
                ["浦东新区", "闵行区", "静安区", "徐汇区", "杨浦区", "嘉定区", "黄埔区"],
                ["白云区", "天河区", "花都区", "番禺区"]
            ];
    
            // 2. 获取 `省` 和 `市` 的标签
            var province = document.getElementById("province");
            var city = document.getElementById("city");
    
            // 3. 监听省份发生更改事件
            province.onchange = function () {
    
                // 注意: 清除 `区县` 信息
                city.innerHTML = "<option value=\"none\">--请选择市--</option>";
    
                // 4. 获取 `省份` 对应的value数值
                var index = province.value;
    
                // 5. 根据获取的 index, 遍历 cities 二维数组中对应的 `一维数组`.
                for (var i = 0; i < cities[index].length; i++) {
    
                    // 方式二 : appendChild();
                    // 创建一个 option 标签对象
                    var option = document.createElement("option");
                    // 设置内容
                    option.innerHTML = cities[index][i];
                    // 拼接标签
                    city.appendChild(option);
                }
            }
        }
    </script>
    

    实现方案三 : city.options.add(option对象);

    <script>
        window.onload = function () {
    
            // 1. 先准备区县的数组
            var cities = [
                ["朝阳区", "海淀区", "丰台区", "昌平区", "西城区", "东城区", "通州区", "大兴区"],
                ["浦东新区", "闵行区", "静安区", "徐汇区", "杨浦区", "嘉定区", "黄埔区"],
                ["白云区", "天河区", "花都区", "番禺区"]
            ];
    
            // 2. 获取 `省` 和 `市` 的标签
            var province = document.getElementById("province");
            var city = document.getElementById("city");
    
            // 3. 监听省份发生更改事件
            province.onchange = function () {
    
                // 注意: 将 options 数组长度设置为 1
                city.options.length = 1;
    
    
                // 4. 获取 `省份` 对应的value数值
                var index = province.value;
    
                // 5. 根据获取的 index, 遍历 cities 二维数组中对应的 `一维数组`.
                for (var i = 0; i < cities[index].length; i++) {
    
                    // 方式三 : select 标签中拥有一个 options 数组.
                    // 创建 option 对象, 使用 new 关键字.
                    var option = new Option(cities[index][i]);
                    // 将 option 对象添加到 options 数组中.
                    city.options.add(option);
                }
            }
        }
    </script>
    

     

    二、正则表达式

    1、概述

    正则表达式是字符模式的对象、主要用来验证客户端的输入数据、。用户填写完表单单击按钮之后,表单就会被发送到服务器,在服务器端通常会用Java 、PHP、等服务器脚本对其进行进一步处理。因为客户端验证,可以节约大量的服务器端的系统资源,并且提供更好的用户体验

    2、正则语法

    2.1、创建正则表达式

    方法一、采用new运算符、

    var box = new RegExp('box'); //第一个参数字符串
    var box = new RegExp('box', 'ig'); //第二个参数可选模式修饰符

    方法二、采用字面量方式

    注意:不用加双引号

    var box = /box/; //直接用两个反斜杠
    var box = /box/ig; //在第二个斜杠后面加上模式修饰符

    模式修饰符可选 参数

    2.2、测试正则表达式

    /*使用new 运算符的test 方法示例*/
    var pattern = new RegExp('box', 'i'); //创建正则模式,不区分大小写
    var str = 'This is a Box!'; //创建要比对的字符串
    alert(pattern.test(str)); //通过test()方法验证是否匹配
    
    /*使用字面量方式的test 方法示例*/
    var pattern = /box/i; //创建正则模式,不区分大小写
    var str = 'This is a Box!';
    alert(pattern.test(str));
    
    /*使用一条语句实现正则匹配*/
    alert(/box/i.test('This is a Box!')); //模式和字符串替换掉了两个变量
    
    /*使用exec 返回匹配数组*/
    var pattern = /box/i;
    var str = 'This is a Box!';
    alert(pattern.exec(str)); //匹配了返回数组,否则返回null

    2.3、使用字符串的正则表达式方法

    除了test()和exec()方法,String 对象也提供了4 个使用正则表达式的方法。

    /*使用match 方法获取获取匹配数组*/
    var pattern = /box/ig; //全局搜索
    var str = 'This is a Box!,That is a Box too';
    alert(str.match(pattern)); //匹配到两个Box,Box
    alert(str.match(pattern).length); //获取数组的长度
    
    /*使用search 来查找匹配数据*/
    var pattern = /box/ig;
    var str = 'This is a Box!,That is a Box too';
    alert(str.search(pattern)); //查找到返回位置,否则返回-1
    
    PS:因为search 方法查找到即返回,也就是说无需g 全局
    
    /*使用replace 替换匹配到的数据*/
    var pattern = /box/ig;
    var str = 'This is a Box!,That is a Box too';
    alert(str.replace(pattern, 'Tom')); //将Box 替换成了Tom
    
    /*使用split 拆分成字符串数组*/
    var pattern = / /ig;
    var str = 'This is a Box!,That is a Box too';
    alert(str.split(pattern)); //将空格拆开分组成数组

    2.4、正则表达式元字符

    (1)、常用元字符

    (2)、常用限定符

    (3)、常用反义词

    (4)、元字符

    案例

    <script>
    
        // 需求 : 校验用户名必须是 4~12 位字母数字下划线的组合, 不能以数字开头. (正则对象)
        // [0-9] 可以使用 \d 表示.
        // [a-zA-Z_0-9] 可以使用 \w 表示.
    
        var regex = /^[a-zA-Z]\w{3,11}$/;
    
        var result = regex.test("Jack_xie");
        if (result == true) {
            alert("用户名可用.");
        } else {
            alert("请更换用户名.");
        }
    
    </script>
    

    3、表单验证

    html代码

    <body>
        <form action="server" method="post" id="myform" onsubmit="return checkAll()">
            <table class="main" border="0" cellspacing="0" cellpadding="0">
                <tr>
                    <td>
                        <img src="../img/logo.jpg" alt="logo" />
                        <img src="../img/banner.jpg" alt="banner" width="350px" />
                    </td>
                    
                </tr>
                <tr>
                    <td class="hr_1">新用户注册</td>
                </tr>
                <tr>
                    <td style="height:10px;"></td>
                </tr>
                <tr>
                    <td>
                        <table width="100%" border="0" cellspacing="0" cellpadding="0">
                            <tr>
                                <!-- 长度为4~16个字符,并且以英文字母开头 -->
                                <td class="left">用户名:</td>
                                <td class="center">
                                    <input id="user" name="user" type="text" class="in" onblur="checkUser()"/>
                                    <span style="color: red" id="userInfo"></span>
                                </td>
                            </tr>
                            <tr>
                                <!-- 不能为空, 输入长度大于6个字符 -->
                                <td class="left">密码:</td>
                                <td class="center">
                                    <input id="pwd" name="pwd" type="password" class="in" onblur="checkPassword()"/>
                                    <span style="color: red" id="pwdInfo"></span>
                                </td>
                            </tr>
                            <tr>
                                <!-- 不能为空, 与密码相同 -->
                                <td class="left">确认密码:</td>
                                <td class="center">
                                    <input id="repwd" name="repwd" type="password" class="in" onblur="checkRepassword()"/>
                                    <span style="color: red" id="repwdInfo"></span>
                                </td>
                            </tr>
                            <tr>
                                <!-- 不能为空, 邮箱格式要正确 -->
                                <td class="left">电子邮箱:</td>
                                <td class="center">
                                    <input id="email" name="email" type="text" class="in" onblur="checkMail()"/>
                                    <span id="emailInfo" style="color: red;"></span>
                                </td>
                            </tr>
                            <tr>
                                <!-- 不能为空, 使用正则表达式自定义校验规则,1开头,11位全是数字 -->
                                <td class="left">手机号码:</td>
                                <td class="center">
                                    <input id="mobile" name="mobile" type="text" class="in" onblur="checkMobile()"/>
                                    <span id="mobileInfo" style="color: red;"></span>
                                </td>
                            </tr>
                            <tr>
                                <!-- 不能为空, 要正确的日期格式 -->
                                <td class="left">生日:</td>
                                <td class="center">
                                    <input id="birth" name="birth" type="text" class="in" onblur="checkBirth()"/>
                                    <span id="birthInfo" style="color: red;"></span>
                                </td>
                            </tr>
                            <tr>
                                <td class="left">&nbsp;</td>
                                <td class="center">
                                    <input type="image" src="../img/register.jpg" />
                                </td>
                            </tr>
                        </table>
                    </td>
                </tr>
            </table>
        </form>
    </body>
    

    表单验证js代码

    <script>
        // 检查所有 : 控制了表单的提交事件
        function checkAll() {
            return checkUser() && checkMail() && checkPassword() 
            && checkRepassword() && checkMobile() && checkBirth();
        }
    
        // 校验用户名
        function checkUser() {
            <!-- 长度为4~16个字符,并且以英文字母开头 -->
            var regex = /^[a-zA-Z]\w{3,15}$/;
            return regexMethod(regex, "user");
        }
    
        // 校验邮箱
        function checkMail() {
            <!-- 不能为空, 邮箱格式要正确 -->
            var regex = /^\w+@\w+(\.[a-zA-Z]{2,3}){1,2}$/;
            return regexMethod(regex, "email");
        }
    
        // 校验密码
        function checkPassword() {
            var regex = /^[a-zA-Z0-9]{6,20}$/;
            return regexMethod(regex, "pwd");
        }
    
        // 校验重复密码
        function checkRepassword() {
            // 1. 获取两次密码的数值
            var pwd = document.getElementById("pwd").value;
            var repwd = document.getElementById("repwd").value;
            // 2. 判断
            if (pwd != repwd) {
                document.getElementById("repwdInfo").innerHTML = "两次密码不一致";
                return false;
            }
            document.getElementById("repwdInfo").innerHTML = "<img src='../img/gou.png' width='15px' />";
            return true;
        }
    
        // 校验手机号码
        function checkMobile() {
            var regex = /^1[34578]\d{9}$/;
            return regexMethod(regex, "mobile");
        }
    
        // 校验生日
        function checkBirth() {
            // 1988-09-01
            // 2008-12-31
            var regex = /^((19\d{2})|(200\d))-(0?[1-9]|1[0-2])-(0?[1-9]|[1-2]\d|3[0-1])$/; // type=date
            return regexMethod(regex, "birth");
        }
    
        // 定义一个函数  (正则封装)
        function regexMethod(regex, name) {
            var value = document.getElementById(name).value;
            if (regex.test(value) == false) {
                document.getElementById(name + "Info").innerHTML = "格式不正确!";
                return false;
            }
            document.getElementById(name + "Info").innerHTML = "<img src='../img/gou.png' width='15px'/>";
            return true;
        }
    </script>
    

     

    展开全文
  • 计算机二级Python学习笔记(九)

    千次阅读 多人点赞 2018-09-16 01:02:34
    上一篇:二级Python学习笔记(八)  距离上一篇已经过去大半个月了,明天我都要考试了,才勉强把这最后一篇更完,想想惭愧。这期间也做了不少题,不知道会不会考原题,今天第一天考的童鞋在群里说挺难,再发篇博客...

    上一篇:二级Python学习笔记(八)

         距离上一篇已经过去大半个月了,明天我都要考试了,才勉强把这最后一篇更完,想想惭愧。这期间也做了不少题,不知道会不会考原题,今天第一天考的童鞋在群里说挺难,再发篇博客攒攒人品吧......为日后考试的小伙伴们提供一点便利,记住多学多练,加油!

         最后三章一起了,还以为我一章一篇博客呢,怎么可能这么轻易被猜透?

    **************************比第一篇华丽的分割线****************************

    第9章 Python标准库概览

    9.1 turtle库概述

    turtle库:Python重要的标准库之一,进行基本的图形绘制。

    三种引入方式:

    import turtle
    turtle.circle(200)
    
    from turtle import *
    circle(200)
    
    import turtle as t
    t.circle(200)
    

    9.2 turtle库与基本绘图

    窗体函数:

    turtle.setup(width, height, startx, starty)
    
    作用:设置主窗体的大小和位置
    参数:
    width :窗口宽度,如果值是整数,表示的像素值;如果值是小数,表示窗口宽度与屏幕的比例;
    height: 窗口高度,如果值是整数,表示的像素值;如果值是小数,表示窗口高度与屏幕的比例;
    startx:窗口左侧与屏幕左侧的像素距离,如果值是None,窗口位于屏幕水平中央;
    starty:窗口顶部与屏幕顶部的像素距离,如果值是None,窗口位于屏幕垂直中央;

    画笔状态函数:

    画笔运动函数:

     9.3 random库概述

    random库:生成随机数。

    9.4 random库与随机数运用

    常用函数:

    随机数种子:准确复现随机数序列,用于重复程序的运行轨迹。如果没有设置,默认以当前系统的运行时间为种子产生随机序列。

    9.5 time库概述

    time库:时间处理、时间格式化和计时。可以用来分析程序性能,也可让程序暂停运行时间。

    时间处理:time.time()、time.gmtime()、time.localtime() 、time.ctime()。
    时间格式化:time.mktime()、time.strftime()、time.strptime()。
    计时:time.sleep()、time.monotonic()、time.perf_counter()

    #使用time.time()获取当前时间戳
    >>>import time
    >>>time.time()
    1516939876.6022282
    
    #使用time.gmtime(secs)获取当前时间戳对应的struct_time对象
    >>> time.gmtime(now)
    time.struct_time(tm_year=2018, tm_mon=1, tm_mday=26, tm_hour=4, tm_min=11, tm_sec=16, tm_wday=4, tm_yday=26, tm_isdst=0)
    
    #使用time.localtime(secs)获取当前时间戳对应的本地时间的struct_time对象
    #注意结果与gmtime的区别,UTC时间已自动转换为北京时间
    >>> time.localtime(now)
    time.struct_time(tm_year=2018, tm_mon=1, tm_mday=26, tm_hour=12, tm_min=11, tm_sec=16, tm_wday=4, tm_yday=26, tm_isdst=0)
    
    #使用time.ctime(secs)获取当前时间戳对应的易读字符串表示,内部会调用time.localtime()函数以输出当地时间。
    >>> time.ctime(now)
    'Fri Jan 26 12:11:16 2018'
    
    调用time.mktime(t)函数
    >>> t = time.localtime(now)
    >>> time.mktime(t)
    1516939876.0
    >>> time.ctime(time.mktime(t))
    'Fri Jan 26 12:11:16 2018'
    
    time.strftime()函数是时间格式化最有效的方法,几乎可以以任何通用格式输出时间。该方法利用一个格式字符串,对时间格式进行表达。
    >>> lctime = time.localtime()
    >>> lctime
    time.struct_time(tm_year=2018, tm_mon=1, tm_mday=26, tm_hour=12, tm_min=55, tm_sec=20, tm_wday=4, tm_yday=26, tm_isdst=0)
    >>> time.strftime("%Y-%m-%d %H:%M:%S", lctime)
    '2018-01-26 12:55:20'
    
    strptime()方法与strftime()方法完全相反,用于提取字符串中时间来生成strut_time对象,可以很灵活的作为time模块的输入接口
    >>> timeString = '2018-01-26 12:55:20'
    >>> time.strptime(timeString, "%Y-%m-%d %H:%M:%S")
    time.struct_time(tm_year=2018, tm_mon=1, tm_mday=26, tm_hour=12, tm_min=55, tm_sec=20, tm_wday=4, tm_yday=26, tm_isdst=-1)
    

    strftime()方法的格式化控制符:

    9.6 time库与程序计时

    以1千万次循环为主体,模拟实际程序的核心模块,用time.sleep()来模拟实际程序的其他模块。

    import time
    def coreLoop():
        limit = 10**8
        while (limit > 0):
            limit -= 1
     
    def otherLoop1():
        time.sleep(0.2)
     
    def otherLoop2():
        time.sleep(0.4)
    
    def main():
        startTime = time.localtime()
        print('程序开始时间:', time.strftime('%Y-%m-%d %H:%M:%S', startTime))
        startPerfCounter = time.perf_counter()
        otherLoop1()
        otherLoop1PerfCounter = time.perf_counter()
        otherLoop1Perf = otherLoop1PerfCounter - startPerfCounter
        coreLoop()
        coreLoopPerfCounter = time.perf_counter()
        coreLoopPerf = coreLoopPerfCounter - otherLoop1PerfCounter
        otherLoop2()
        otherLoop2PerfCounter = time.perf_counter()
        otherLoop2Perf = otherLoop2PerfCounter - coreLoopPerfCounter
        endPerfCounter = time.perf_counter()
        totalPerf = endPerfCounter - startPerfCounter
        endTime = time.localtime()
        print("模块1运行时间是:{}秒".format(otherLoop1Perf))
        print("核心模块运行时间是:{}秒".format(coreLoopPerf))
        print("模块2运行时间是:{}秒".format(otherLoop2Perf))
        print("程序运行总时间是:{}秒".format(totalPerf))
        print('程序结束时间:', time.strftime('%Y-%m-%d %H:%M:%S', endTime))
        
    main()
    

    程序运行的输出效果如下:

    程序开始时间: 2017-12-26 13:46:39
    模块1运行时间是:0.20003105182731706秒
    核心模块运行时间是:5.987101639820927秒
    模块2运行时间是:0.40018931343066555秒
    程序运行总时间是:6.587323585324574秒
    程序结束时间: 2017-12-26 13:46:45


    第10章 Python第三方库概览

    10.1 Python第三方库的获取和安装

    三个方法:pip工具安装、自定义安装和文件安装。

    pip工具安装:最高效,最主要。pip install <拟安装库名>

    自定义安装:按照第三方库提供的步骤和方式安装。以科学计算用的numpy为例,开发者维护的官方主页是:http://www.numpy.org/浏览该网页找到下载链接,如下:http://www.scipy.org/scipylib/download.html进而根据指示步骤安装。

    文件安装:为了解决这类第三方库安装问题,美国加州大学尔湾分校提供了一个页面,帮助Python用户获得Windows可直接安装的第三方库文件,http://www.lfd.uci.edu/~gohlke/pythonlibs/

    pip工具使用:

    #列出pip常用的子命令
    pip -h
    
    #安装
    pip -install
    
    #下载不安装
    pip -download
    
    #卸载
    pip -uninstall
    
    #列出当前系统中已经安装的第三方库
    pip -list
    
    #联网搜索库名或摘要中关键字
    pip -search
    
    #列出某个已经安装库的详细信息
    pip show <拟查询库名>
    

    10.2 PyInstaller库概述

    PyInstaller库:将Python源文件打包,变成直接可运行的可执行文件

    10.3 PyInstaller库与程序打包

    #对Python源文件打包
    :\>PyInstaller <Python源程序文件名>
    
    #对Python源文件生成一个独立的可执行文件
    :\>PyInstaller -F <Python源程序文件名>
    

    常用参数:

    10.4  jieba库概述

    jieba库:中文分词。

    精确模式,将句子最精确地切开,适合文本分析。

    全模式,把句子中所有可以成词的词语都扫描出来,速度非常快,但是不能解决歧义。

    搜索引擎模式,在精确模式基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词。

    10.5 jieba库与中文分词

    jieba.lcut(s) 用于精准模式,将字符串分割成等量的中文词组,返回结果是列表类型
    >>>import jieba
    >>>ls = jieba.lcut("全国计算机等级考试Python科目")
    >>>print(ls)
    ['全国', '计算机', '等级', '考试', 'Python', '科目']
    
    jieba.lcut(s, cut_all = True)用于全模式,即将字符串的所有分词可能均列出来,返回结果是列表类型,冗余性最大。
    >>>import jieba
    >>>ls = jieba.lcut("全国计算机等级考试Python科目", cut_all=True)
    >>>print(ls)
    ['全国', '国计', '计算', '计算机', '算机', '等级', '考试', 'Python', '科目']
    
    jieba.lcut_for_search(s)返回搜索引擎模式,首先执行精确模式,然后再对其中长词进一步切分获得最终结果。
    >>>import jieba
    >>>ls = jieba.lcut_for_search("全国计算机等级考试Python科目")
    >>>print(ls)
    ['全国', '计算', '算机', '计算机', '等级', '考试', 'Python', '科目']
    
    jieba.add_word()函数,向jieba词库增加新的单词。
    >>>import jieba
    >>>jieba.add_word("Python科目")
    >>>ls = jieba.lcut("全国计算机等级考试Python科目")
    >>>print(ls)
    ['全国', '计算机', '等级', '考试', 'Python科目']
    

    10.6 wordcloud库概述

    worldcloud库:根据文本生成词云。

    10.7 wordcloud库与可视化词云

    import jieba
    from wordcloud import WordCloud
    txt = '程序设计语言是计算机能够理解和识别用户操作意图的一种交互体系,它按照特定规则组织计算机指令,使计算机能够自动进行各种运算处理。'
    words = jieba.lcut(txt)        # 精确分词
    newtxt = ' '.join(words)       # 空格拼接
    wordcloud = WordCloud(font_path="msyh.ttc").generate(newtxt) 
    wordcloud.to_file('词云中文例子图.png')        # 保存图片

    WordCloud对象创建的常用参数:


    第11章 Python第三方库纵览

    11.1 网络爬虫方向

    requests、scrapy

    11.2 数据分析方向

    numpy、scip、pandas  

    11.3 文本处理方向

    pdfminer、openpyxl、python-docx、beautifulsoup4

    11.4 数据可视化方向

    matplotib、TVTK

    11.5 用户图形界面方向

    pyqt5、wxpython、pygtk

    11.6 机器学习方向

    Scikit-learn、TensorFlow、Theano

    11.7 Web开发方向

    Django、Pyramid、Flask

    11.8 游戏开发方向

    Pygame、Panda3D、cocos2d

    11.9 更多第三方库

    PIL:图像处理
    SymPy:支持符号计算
    NLTK:自然语言处理(尤其对中文支持良好)
    WeRoBot:微信公众号开发框架
    MyQR:生产二维码

     

    最后扯两句,学习是好事,但是要劳逸结合,年轻不是资本,早睡早起身体好。祝大家逢考必过!

    展开全文
  • Js学习笔记

    千次阅读 2019-09-01 09:59:06
    1、基本的数据类型 number(包含整型和浮点型)、null(空)、undefined(当函数没有返回值时打印)、Boolean、string。 2、常用函数 typeof 和Pythono中type函数功能一样,trim()函数和python的strip()函数功能一样。...
  • web前端学习笔记(三)

    万次阅读 多人点赞 2018-08-28 15:12:47
    ...所有的布局类标签都主要用来构建页面的内容区域,是双标签类型,是双标签类型,默认显示为块状元素。 通用的布局标签:&lt;div&gt;...语义:无明确的含义,通常就是代表“盒子”;应用:根据布局的需要,可以...
  • 软件学习笔记

    2020-07-30 23:31:58
    浏览器先将HTML解析为DOM树,DOM树的每一节点对应HTML文档中的元素和文本,然后解析css,根据css的选择器规则找到对应的树节点,为其增加css中书写的样式。... ...外部样式表(推荐) <link rel="stylesheet" href=...
  • 学习笔记

    2018-07-08 18:04:36
    通过这两天的学习,对于Linux系统有了一个初步的了解以及熟悉了一些常用的shell命令。1. LinuxLinux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和UNIX的多用户、多任务、支持多线程和多CPU的操作...
  • 学习 笔记

    2018-11-16 23:22:13
    c语言指针学习笔记 间接访问和直接访问 (1)直接访问:执行写操作时,给变量赋值,是将值放到变量对应的存储空间,执行读操作时,直接从变量对应的储存空间读取已存放的数据。如: a=4;(写) printf(&amp;...
  • 学习笔记(一)

    2019-04-25 18:00:47
    前端学习(一) 1.学习这8个web开发技术 HTML+CSS+jQuery+JavaScript完成了10个项目,可获得前端开发证书 React+Sass+D3.js完成了10个项目,可获得数据可视化证书 Node.js,+Express+MongoDB完成了10个项目,可获得...
  • Lucene学习笔记(1) Lucene是一套全文检索的API,对其介绍的文章和应用的案例都多,可参考lucene及本文的参考文献。 此次学习,以实用为主,一是简单应用,二是Web应用,三是汉化,四相关应用(Lucene主页上在...
  • Keras学习笔记(一)

    万次阅读 多人点赞 2017-05-23 11:45:41
    1.Dense 全连接层(对上一层的神经元进行全部连接,实现特征的非线性组合) keras.layers.core.Dense(units, activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', ...
  • javaScript学习笔记(一)js基础

    万次阅读 多人点赞 2020-07-15 21:28:52
    ================================= 公众号 关注一波 (一叶知秋博客) 不定期分享视频资料 一、简介 1、概述: ...JavaScript是目前web开发中不可缺少的脚本语言,js不需要编译即可运行,运行在客户端,需要...
  • Deep Learning(深度学习)学习笔记整理系列之(一)

    万次阅读 多人点赞 2013-04-10 12:50:17
    Deep Learning(深度学习)学习笔记整理系列 zouxy09@qq.com http://blog.csdn.net/zouxy09 作者:Zouxy version 1.0 2013-04-08   声明: 1)该Deep Learning的学习系列是整理自网上很大牛和机器学习专家...
  • 〖TensorFlow2.0笔记23〗TensorFlow2.0学习笔记总结!

    千次阅读 多人点赞 2020-08-29 14:22:50
    Tensorflow2.0全套课程学习笔记! tensorflow2.0笔记1:tensorflow2.0介绍以及安装!(2019-10-1 tensorflow2.0正式版发布) tensorflow2.0笔记2:Numpy—实现线性回归问题! tensorflow2.0笔记3:手写数字问题初...
  • zigbee学习笔记(一)之 zigbee简介

    千次阅读 多人点赞 2019-12-16 21:29:29
    zigbee学习笔记(一) zigbee简介 1、什么是zigbee? zigbee是协议,类似于蓝牙、WiFi等等;它是一种标准,该标准定义了短距离、低数据传输速率无线通信的所需要的一系列的通信协议。 2、zigbee无线网络工作的三...
  • 斯坦福大学吴恩达机器学习课程 完整学习笔记+原始版讲义 全是高清版的ppt该课件为中科院一位仁兄在学习斯坦福大学吴恩达机器学习课程时候所做的学习笔记,非常好,吴老师上课略过的一些内容笔记都详细给出,并且还做...
  • 小甲鱼《零基础入门学习Python》学习笔记

    千次阅读 多人点赞 2018-09-06 23:34:31
    根据老师的建议,现在将第二次复习小甲鱼的《零基础入门学习Python》而做的学习笔记,上传到网上,方便今后复习和保存,因为是手写的,所以做了扫描锐化处理,方便阅读。 ...
  • 《C++ Primer》学习笔记/习题答案 总目录

    万次阅读 多人点赞 2020-04-03 21:06:32
    文章目录前言专栏C++学习笔记目录第一章 - 快速入门第二章 - 变量和基本类型第三章 - 标准库类型第四章 - 数组和指针第五章 - 表达式第六章 - 语句第七章 - 函数第八章 - 标准 IO 库第九章 - 顺序容器第十章 - 关联...
  • 我的微信公众号:红色石头的机器学习之路(ID:redstonewill) 欢迎大家关注我!共同学习,共同进步! 上节课我们讲了一个机器学习很重要的工具——Validation。我们将整个训练集分成两...
1 2 3 4 5 ... 20
收藏数 1,145,944
精华内容 458,377
关键字:

学习笔记