VUE
VUE 如何实现数据的双向绑定
采用数据劫持结合发布者-订阅者模式的方式,通过 Object.defineProperty() 来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应监听回调。当把一个普通 Javascript 对象传给 Vue 实例来作为它的 data 选项时,Vue 将遍历它的属性,用 Object.defineProperty() 将它们转为 getter/setter。
链接:https://www.jianshu.com/p/97debc2d8785
VUE 生命周期
VUE 实例创建到销毁的过程。
开始创建、初始化数据,编译模板,挂载 DOM -> 渲染、更新 -> 渲染、销毁等一系列过程。
vue 父子组件传值
- 子组件通过 props 方法接受父组件的值。
- 子组件通过 $emit 方法向父组件发送数据。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="../lib/vue.js"></script>
<link rel="stylesheet" href="../lib/bootstrap.min.css">
</head>
<body>
<!-- 子组件向父组件传值使用事件绑定机制 -->
<!-- 父组件向子组件传值使用属性绑定机制 -->
<div id="app">
<!-- 1. 将父组件的msg绑定到子组件上,子组件通过访问绑定的属性来获取父组件内容 -->
<son-component :parentsmsg="msg" @func="getSonMsg"></son-component>
<h1>{{sonmsg}}</h1>
</div>
<template id="sonTemp">
<div>
<!-- 3. 在子组件中使用 -->
<h1>这是子组件 ------ {{parentsmsg}}</h1>
<input type="button" class="btn btn-primary" @click="sendMsg" value="点击,控制台输出子组件内容">
</div>
</template>
<script>
var sonTemplate = {
template: '#sonTemp',
//2. 在子组件中显示的定义parentsMes属性
props: ['parentsmsg'],
data() {
return {
msg: '这是子组件的内容'
}
},
methods: {
sendMsg() {
this.$emit("func", this.msg)
}
}
}
var vm = new Vue({
el: '#app',
data: {
msg: '这是父组件的内容',
sonmsg: ''
},
methods: {
getSonMsg(data){
this.sonmsg = data
console.log(this.sonmsg)
}
},
components: {
//注意: 驼峰法写的组件名称 使用时必须使用 - 分割
sonComponent: sonTemplate
}
})
</script>
</body>
</html>
VUE 的通信方法
-
父子组件件的通信
-
VUEX。
VUEX 是什么
VUEX 是 VUE 配套的状态管理模式,VUEX 可以把一些需要共享的数据保存到 VUEX 中,方便应用中的任何组件能直接获取或修改共享的公共数据。
VUEX 的使用
// 1.导入vuex
import Vuex from 'vuex';
// 2.手动安装 Vuex
Vue.use(Vuex);
// 3.创建 store(数据仓库)
var store = new Vuex.Store({
state: {
// 存放共享的数据,相当于 vue 的 data 属性
count: 0
},
mutations: {
// 存放操作共享数据的函数方法,相当于 vue 中的 methods
// 其他组件想要修改 state 中的工现象数据,最好使用 mutations 中定义的方法
// 这样能防止其他组件对 state 中的数据随意修改
increment() {
state.count++;
},
decrease() {
state.count--;
}
}
});
VUEX 数据的获取与操作
<template>
<div>
<!-- 调用 Vuex 中的数据 -->
<p>{{ this.$store.state.count }}</p>
<hr>
<!-- 修改 Vuex 中的数据 -->
<button @click="add()">count+1</button>
<button @click="reduce()">count-1</button>
</div>
</template>
<style>
</style>
<script>
export default {
methods: {
add: function() {
this.$store.commit('increment');
},
reduce() {
this.$store.commit('decrease');
}
}
}
</script>
VUE 的 data 属性的返回值为什么是对象
data 必须声明为返回一个初始数据对象的函数,因为组件可能被用来创建多个实例。如果 data 仍然是一个纯粹的对象,则所有的实例将共享引用同一个数据对象!通过提供 data 函数,每次创建一个新实例后,我们能够调用 data 函数,从而返回初始数据的一个全新副本数据对象。
v-if 与 v-show 的区别?
v-if 是真正的条件渲染,每次都会创建和删除元素,有较大的切换开销 - 创建删除.
v-show 只是控制元素的display 为 none,有较大的的渲染开销 - 显示隐藏.
需要频繁的切换则使用v-show,若在运行时条件不太容易改变则使用v-if(购物车).
VUE 与其他框架的区别
如何让 css 在当前的组件中起作用?
在 style 标签中 使用 scoped 属性。
前端
CSS 的性能优化
- 压缩 CSS 文件。
- 去除代码中无用的 CSS。
- 不要使用 @import 引入 CSS,它会影响浏览器的并行下载。
盒子模型
内容区(content)
内边距(padding)
边框(border)
外边距(margin)
如何解决盒模型塌陷问题
两个呈嵌套关系的盒子,对子盒子设置 margin-top时父盒子会随着子盒子同时下移,并且 margin-top看不到效果。
如何解决:
- 给父盒子设置边框。
- 父盒子添加溢出隐藏: overfl: hidde;
- 在父盒子中设置内边距代替子盒子的外边距。
清除浮动
清除浮动的方法:
- 给父盒子设置高度。
- 给父盒子使用伪元素清除浮动。
.clearfix:after{
content: "";
display: block;
clear: both;
}
- 额外标签法,在浮动元素后面添加额外标签。
<div style="clear:both;"> </div>
- 给父盒子设置overflow:hidden。
具体大代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>float</title>
<style type="text/css">
/* float 使盒子脱离标准流,浮动的盒子在一行上显示 */
/* 行内元素浮动后转为行内块 */
.div1 {
background-color: pink;
/* overflow: hidden; */
}
.red,.green,.yellow{
width: 300px;
height: 300px;
}
.red{
background: red;
float: left;
}
.green{
background: green;
float: left;
}
.yellow{
background: yellow;
float: right;
}
.clearfix:after {
content: '';
display: block;
clear: both;
}
/* 让.clearfix兼容IE浏览器 */
.clearfix {
zoom: 1;
}
</style>
</head>
<body>
<div class="div1">
<!-- <div class="div1 clearfix"> -->
<div class="red"></div>
<div class="green"></div>
<div class="yellow"></div>
<!-- <div style="clear: both;"></div> -->
</div>
</body>
</html>
在浏览器中输入URL后,执行的全部过程
-
DNS解析
将域名地址解析为 IP 地址。解析过程如下:检查浏览器 DNS 缓存。
检查系统 DNS 缓存(host文件,中保留了一些以前访问过的网站的域名和IP的数据)。
检查路由器 DNS 缓存。
查询 ISP DNS 缓存。ISP:互联网服务提供商。
递归查询。从根域名服务器到顶级域名服务器再到极限域名服务器依次搜索对应目标域名的IP。 -
TCP 三次握手
-
浏览器向服务器发送 HTTP 请求
-
浏览器接收服务器的响应
-
断开 TCP 连接(四次握手)
-
浏览器渲染页面
页面渲染过程如下:
根据 HTML 构建 DOM 树。
根据 CSS 构建 CSSOM(CSS 对象模型:包含DOM和CSS规则)。
根据 DOM 树和 CSS Rule Tree 构建 rendering tree(渲染树)。
更据渲染树绘制每个节点。最终完成浏览器页面的渲染。
DOM 和 CSSOM 的构建是异步进行的,遇到 JS 文件后,会终止DOM 和 CSSOM 的构建,这就是为什么将 js 文件放在 HTML 最后的原因。
JS 会阻塞UI线程的执行,是因为 JS 能控制 UI 的展示,而页面加载的规则是要顺序执行,所以在碰到 JS 代码时候 UI 线程会首先执行它
检测数组
var arr = [1, 2, 3];
- Array.isArray()
Array.isArray([1, 2, 3]); // true
Array.isArray({foo: 123}); // false
-
arr instanceof Arrary
-
toString.call([])
var arr = [1,2,3];
console.log(toString.call(arr));//输出: [object Array]
数组方法
前端性能优化
- 减少 http 请求。
- 使用 精灵图。
- 使用 延时加载。
- CSS 放在页面最上部,JS 放在页面底部:让浏览器尽快下载 css 渲染页面。
浏览器页面渲染过程
document.ready 和 document.load
document.ready 和 document.load 指页面加载的两个阶段。
DOM文档加载的步骤
(1)解析域名
(2)解析html结构
(3)加载外部脚本和样式表文件
(4)解析并执行脚本代码
(5)构造HTML DOM模型 //ready
(6)加载图片等外部文件
(7)页面加载完毕 //load
什么是闭包?
闭包就是有权访问另一个函数作用域中变量的函数。
function func() {
var str = "hello";
return function(){
console.log(str);
}
}
var func2 = func();
func2();// 输出: "hello"
闭包的作用
1.可以间接调用函数内部的局部变量。
2.可以让这些变量的值始终保持在内存中。(因此要注意不能滥用闭包)
3.可以暂存数据,给变量开辟私密空间,避免外部污染。
内存泄漏
ES6 新特性
1.声明变量的关键字:const 和 let
2.顶层对象的属性
顶层对象,浏览器中指的是window对象,在Node中指的是global对象。
ES5中,顶层对象的属性和全局变量是等价的。
3.模板字符串
let name = ‘Bob’,time = ‘today’;
Hello ${name},how are you ${time}
4.箭头函数
ES6中允许使用“箭头”(=>)定义函数。
5.使用export和import实现模块化
由于JavaScript是没有模块这一系统的,前辈们为了解决这一问题,提出来很多规范,其中最长用的就是 CommonJs 和 AMD 两种。前者用于服务器,后者用于浏览器。
promise 及其作用与原理
promise 是以一个对象,代表了一个以异步操作的最终完成或失败。
作用:
- 解决回调地狱。
- promise 可以支持多个并发的请求,获取并发请求中的数据。
处理异步并发的可以是Promise.all(),Promise.race()。他们的差别是 all 全部返回 resolve 才会执行 then ,若碰到一次 reject,则终止返回 catch。
而 race 谁最快返回,就结束,返回最快的结果。
promise 的状态
promise 有三种状态:
- pending: 初始(执行)状态,既不是成功,也不是失败。
- resolved: 异步操作成功。
- rejected: 异步操作失败。
JS是单线程还是多线程?
单线程。
单线程是如何实现异步的?
JS 中 this 指向
this 是在运行时确定的,this 永远指向最后调它的对象。
例1:
var name = "windowName";
function func1() {
var name = "func1Name";
console.log(this);
console.log(this.name);
}
func1();// this 指向最后调用它的对象 window
// 输出 "window","windowName"
例2:
var name = "windowName";
var stu = {
name: "stuName",
sayName: function() {
:
console.log(this.name);
}
}
stu.sayName(); //this 指向最后调用它的对象 stu
// 输出"stuName"
window.stu.sayName(); //this 指向最后调用它的对象 stu
// 输出"stuName"
例3:
var name = "windowName";
var stu1 = {
// name: "stuName",
sayName: function() {
console.log(this.name);
}
}
stu1.sayName(); //this 指向最后调用它的对象 stu1
// 因为 stu1 中没有 name 属性,故输出"undefined"
window.stu1.sayName();//this 指向最后调用它的对象 stu1
// 因为 stu1 中没有 name 属性,故输出"undefined"
例4:
var name = "windowName";
var stu2 = {
name: null,
sayName: function() {
console.log(this.name);
}
}
var f = stu2.sayName;//sayNmae()并没有调用
f();//f 被 window 对象调用,this 指向最后调用它的对象 window
如何改变 JS 中 this 的指向
ES6 的箭头函数,call、apply、bind 都可以改变 this 的指向。
- ES6 的箭头函数:
箭头函数的 this 始终指向函数定义时的 this,而非执行时。
箭头函数中没有 this 绑定,必须通过查找作用域链来决定 this 的值,如果箭头函数被非箭头函数包含,则 this 绑定的是最近一层非箭头函数的 this,否则 this 为 undefined。
- 使用 apply()
func.apply(thisArg, [argsArray]);
注意:apply() 的第二个参数是数组
var name = "windowName";
var stu = {
name: "stuName",
func: function(a, b) {
console.log(a + b);
console.log(this.name);
}
}
stu.func(1, 2);// 输出: 3, "stuName"
stu.func.apply(window, [1, 2]);// 输出: 3, "windowName"
stu.func.apply(window, [1, 2]); apply() 将 func 中的 this 指向了 window 对象
- 使用 call()
func.call(thisArg[, arg1[, arg2]]);
var name = "windowName";
var stu1 = {
name: "stu1Name",
func: function(a, b) {
console.log(a * b);
console.log(this.name);
}
}
stu1.func(1, 2);//输出:2, "stu1Name"
stu1.func.call(window, 1, 2);//输出:2, "windowName"
stu1.func.call(window, 1, 2); call() 将 func 中的 this 指向 window 对象
- 使用 bind()
func.bind(thisArg[, arg1[,arg2]])();
var name = "windowName";
var stu2 = {
name: "stu2Name",
func: function(a, b) {
console.log(a - b);
console.log(this.name);
}
}
stu2.func(1, 2);//输出:-1, "stu2Name"
stu2.func.bind(window, 1, 2)();//输出:-1, "windowName"
bind()是创建了一个新的函数,必须要手动去调用。
apply()、call()、bind() 的区别:
他们的调用方法和参数形式不同。
事件流,事件冒泡,事件捕获?
事件流:描述的是从页面中接受事件的顺序。以下面的代码为例,解释事件冒泡和事件捕获。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件冒泡</title>
</head>
<body>
<div id="myDiv">
<button>click</button>
</div>
</body>
</html>
事件冒泡:IE 的事件流,即事件开始是由最具体的元素接收,然后逐级向上传播到较为不具体的节点。
若点击了 button 元素,那 click 事件会按照如下顺序传播:
1. <button>
2. <div>
3. <body>
4. <html>
5. documnet
所有的浏览器都支持事件冒泡,但具体实现上会有一些差异。
事件捕获:Netscape 的事件流,与事件冒泡刚好相反,指不太具体的节点应该更早地接受到事件,而最具体的节点应该最后接受事件。
若点击了 button 元素,那 click 事件会按照如下顺序传播:
1. documnet
2. <html>
3. <body>
4. <div>
5. <button>
老版的浏览器不支持事件捕获。
原型、原型链?
原型:每个javascript对象(null除外)都和一个对象相关联,这个对象就是原型,每个对象都从原型继承属性。以下面的stu对象为例,protp 就是 stu 的原型。
var stu = {
"name": "小明",
"age": "23",
sayName: function() {
console.log(this.name);
}
}
原型链:
JS 创建对象的几种方式
以创建一个学生对象为例:该学生对象有姓名、年龄属性和 sayName() 方法。
- 字面量
var stu = {
"name": "小明",
"age": "23",
sayName: function() {
console.log(this.name);
}
}
stu.sayName();
- 工厂模式
function createStudent(name, age) {
var Obj = new Object();
//属性--特征 名词
Obj.name = name;
Obj.age = age;
//方法
Obj.sayName = function () {
console.log(this.name);
};
return Obj;
}
var stu = createStudent("小明", 23);
- 构造函数模式
function Student(name, age) {
//属性--特征 名词
this.name = name;
this.age = age;
//方法
this.sayName = function () {
console.log(this.name);
};
}
var stu = new Student("小明", 23);
- 原型模式
function Student() {
}
Student.prototype.name = "小明";
Student.prototype.age = 23;
Student.prototype.sayName = function() {
console.log(this.name);
};
var stu = new Student();
console.log("stu: ",stu);
var stu1 = new Student();
console.log("stu1: ",stu1);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-piZXXv5l-1587303551892)(G:\web\Vue学习\vueInterview\image\原型模式创建对象.JPG)]
- Object.create()
var stu = Object.create({
"name": "小明",
"age": "23",
sayName: function() {
console.log(this.name);
}
});
console.log(stu);
- es6中创建对象的方法
class Student {
constructor(name, age) {
this.name = name;
this.age = age;
}
sayName = function() {
console.log(this.name);
}
}
var stu = new Student("小明", 23);
console.log(stu);
AJAX请求示例
AJAX 使得浏览器能通过异步的方式获取服务器端的信息,使得浏览器无需刷新整个页面就能从服务器获取数据,然后通过 DOM 将数据插入或更新到页面。
AJAX 请求需配合服务器响应使用。
客户端 AJAX 请求代码如下(get请求):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>AJAX</title>
</head>
<body>
<p id="getAjax">点击按钮获取 info.txt 内容</p>
<button type="button" onclick="get()">GET 获取</button>
<hr>
<p id="postAjax">使用 POST 获取数据</p>
<button type="button" onclick="post()">POST 获取</button>
<script>
function get() {
// 创建 XMLHttpRequest 请求
var xmlHttpRequest = new XMLHttpRequest();
// var xmlHttpRequest = getHttpRequest();
// 指定 XMLHttpRequest 请求
xmlHttpRequest.open('GET', 'http://localhost:3000/data/info.txt');
// 取得相应响应
xmlHttpRequest.onreadystatechange = function() {
if (xmlHttpRequest.readyState === 4 && xmlHttpRequest.status === 200) {
var el = document.getElementById('getAjax');
console.log(xmlHttpRequest.responseText);
el.innerHTML = xmlHttpRequest.responseText;
}
}
// 指定可选的请求主体,并向服务器发送请求主体,get 方法没有主体,所以应该传 null 或省略这个参数
xmlHttpRequest.send(null);
}
function post() {
// 创建 XMLHttpRequest 请求
var xmlHttpRequest = getHttpRequest();
// 指定 XMLHttpRequest 请求
xmlHttpRequest.open('POST', 'http://localhost:3000/data/postAjax');
// 取得相应响应
xmlHttpRequest.onreadystatechange = function() {
if (xmlHttpRequest.readyState === 4 && xmlHttpRequest.status === 200) {
var el = document.getElementById('postAjax');
console.log(xmlHttpRequest.responseText);
el.innerHTML = xmlHttpRequest.responseText;
}
}
// 指定可选的请求主体,并向服务器发送请求主体,get 方法没有主体,所以应该传 null 或省略这个参数
xmlHttpRequest.setRequestHeader("content-Type", "application/json");
xmlHttpRequest.send(JSON.stringify({"name":"wmt","eml":"111@qq.com"}));
}
function getHttpRequest() {//为兼容低版本浏览器
if (typeof XMLHttpRequest == "undefined") {
XMLHttpRequest = function() {
try {
return new ActiveXObject("Msxml2.XMLHTTP.6.0"); //IE 浏览器实现XMLHTTP对象
} catch (e) {}
try {
return new ActiveXObject("Msxml2.XMLHTTP.3.0");
} catch (e) {}
try {
return new ActiveXobject("Msxml2.XMLHTTP");
} catch (e) {}
return false;
};
}
return new XMLHttpRequest(); //其他浏览器实现XMLHTTP对象
}
</script>
</body>
</html>
服务端代码(node.js开发):
const http = require('http');
const url = require('url');
const fs = require('fs');
const path = require('path');
const querystring = require('querystring');
http.createServer().on('request', function(req, res) {
var urlObj = url.parse(req.url);
req.pathname = urlObj.pathname;
req.query = urlObj.query;
// 解决跨域问题
res.setHeader("Access-Control-Allow-Origin", "*");
// console.log(req);
if (req.pathname === '/') {
fs.readFile('../cilent/index.html', 'utf-8', (err, data) => {
if (err) {
throw err;
} else {
// 设置响应报文头
res.writeHead(200, { "content-Type": "text/html; charset=utf-8" });
res.write(data);
res.end();
}
});
} else if (req.pathname === '/data/info.txt' && req.method === 'GET') {
// 读取 infi.txt 文件
fs.readFile(path.join(__dirname, 'data', "info.txt"), 'utf-8', (err, data) => {
if (err) {
throw err;
} else {
res.writeHead(200, { "content-Type": "text/plain; charset=utf-8" });
res.write(data);
res.end();
}
});
} else if(req.pathname === '/data/postAjax' && req.method === 'POST') {
// 获取post提交的数据
var post = '';
req.on('data', (chunk) => {
post += chunk;
});
// 处理 post 方法提交的数据
req.on('end', () => {
fs.readFile(path.join(__dirname, 'data', 'userInfo.json'), 'utf-8', (err, data) => {
var list = JSON.parse(data || '[]');
list.push(JSON.parse(post));
fs.writeFile(path.join(__dirname, 'data', 'userInfo.json'), JSON.stringify(list), 'utf-8', (err)=> {
if (err) {
throw err;
} else {
var date = new Date();
// 设置响应报文头
res.writeHead(200, { "content-Type": "text/plain; charset=utf-8" });
res.write(date.toString());
res.end();
}
});
})
});
} else {
// 设置响应报文头
res.writeHead(404, { "content-Type": "text/plain; charset=utf-8" });
res.write("NOT FOUND");
res.end();
}
}).listen(3000, function() {
console.log("服务器已启动...");
console.log("请访问:http://localhost:3000");
});
点击“GET 获取”按钮,浏览器会发送 AJAX 请求获取 URL 为:“http://localhost:3000/data/info.txt” 的数据。待服务器响应成功后,会将 id=“ajax” 的内容改变为服务器响应的数据。
JSONP 技术
script 元素可以作为一种 AJAX 的传输机制:只需设置 script 元素的 src 属性(没有的话,可动态创建),然后浏览器就会发送一个 HTTP 请求以下载 src 属性所指向的 URL。这种使用 script 元素作为 Ajax 传输的技术称为 JSONP。
使用 script 元素进行 Ajax 传输原因
- script 元素的 src 属性的 HTTP 请求弩手同源策略的影响。
- 包含 JSON 编码数据的响应体会自动解码(执行)。
注:使用 script 元素进行 Ajax 传输,必须允许 Web 页面可以执行远程服务器发送过来的任何 JavaScript 代码。这是攻击者可通过此方法,接管网页,运行他自己的代码。
JSON 的相关方法
var str = '{"name": "wmt", "age" = 25}';
// 将字符串转为 JavaScript 对象
JSON.parse(str);
var list = [{"name": "wmb", "age" = 25}, {"name": "wmt", "age" = 23}];
// 返回指定值对应的JSON字符串
var strList = JSON.stringify(list);
POST 和 GET 提交表单的区别:
- GET 方法将表单数据以名称/值对的形式附加到 URL 中,POST 数据则不在 URL 中显示。故不要使用 GET 方法来传输敏感信息!
POST 的安全性更高。 - 在 URL 中放置的数据量是有限制的(不同的浏览器有差别),所以 GET 方法无法确保所有表单数据得到正确地传输,而 POST 则 没有容量限制
处理 GET 和 POST 方法发送的数据
接收并处理 GET 方法提交的数据:
GET 方法提交数据是在 URL 中显示的,如:http://localhost:3000/get?name=wmt&email=111@qq.com
const url = require('url');
const querystring = require('querystring');//字符串处理模块
var urlObj = new URL('http://localhost:3000/get?name=wmt&email=111@qq.com');
// 获取提交的数据字符串
var query = urlObj.query();//"name=wmt&email=111@qq.com"
// 通过 querystring.parse() 将字符串转变为 json 数据
var data = querystring.parse(query);
console.log(data);//{"name": "wmt", "email": "111@qq.com"}
接收并处理 POST 方法提交的数据:
POST 方法提交的数据是不在 URL 中显示的,适合大量数据的提交
var post = '';
// 监听 'data' 事件
req.on('data', () => {
data += chunk;
});
// 监听 'end' 事件,在 post 数据传输完成后,使用回调函数处理 post 字符串
req.on('end', ()=> {
// 数据处理程序
console.log(post);
})
URL 解析
URL 格式如下:
// ┌────────────────────────────────────────────────────────────────────────────────────────────────┐
// │ href │
// ├──────────┬──┬─────────────────────┬────────────────────────┬───────────────────────────┬───────┤
// │ protocol │ │ auth │ host │ path │ hash │
// │ │ │ ├─────────────────┬──────┼──────────┬────────────────┤ │
// │ │ │ │ hostname │ port │ pathname │ search │ │
// │ │ │ │ │ │ ├─┬──────────────┤ │
// │ │ │ │ │ │ │ │ query │ │
// " https: // user : pass @ sub.example.com : 8080 /p/a/t/h ? query=string #hash "
// │ │ │ │ │ hostname │ port │ │ │ │
// │ │ │ │ ├─────────────────┴──────┤ │ │ │
// │ protocol │ │ username │ password │ host │ │ │ │
// ├──────────┴──┼──────────┴──────────┼────────────────────────┤ │ │ │
// │ origin │ │ origin │ pathname │ search │ hash │
// ├─────────────┴─────────────────────┴────────────────────────┴──────────┴────────────────┴───────┤
// │ href │
// └────────────────────────────────────────────────────────────────────────────────────────────────┘
C 语言
变量声明和变量定义的区别
把分配内存空间的声明称之为"定义",把不需要分配内存空间称的声明之为"声明"。
C语言编译过程
预编译、编译、汇编、链接。
以a.c源文件为例。
预编译:展开头文件、宏定义替换、去掉注释、条件编译。生成.i文件,指令如下:
gcc -E a.c -o a.i
编译:语法检查、汇编。生成.s汇编文件,指令如下:
gcc -S a.i -o a.s
汇编:将汇编转换为机器码。生成.o文件,指令如下:
gcc -c a.s -o a.o
链接:将目标文件最终生成可执行文。生成.exe文件,指令如下:
gcc a.o -o a.exe
红黑数
平衡二叉树
MySQL
创建数据库(使用dos进入mysql):
CREATE DATABASE table_name;
创建数据表(选择新建的数据库):
CREATE TABLE IF NOT EXISTS `userinfo` (
`id` INT UNSIGNED AUTO_INCREMENT,
`username` VARCHAR(100) NOT NULL,
`password` VARCHAR(40) NOT NULL,
`email` VARCHAR(40),
`token` VARCHAR(100),
PRIMARY KEY ( `id` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
插入数据
INSERT INTO userinfo (username, password, email) VALUES ("admin", "admin", "admin@eamil.com");
删除数据表:
DROP TABLE table_name;
若报 ERROR 1051 (42S02): Unknown table ‘xx.xx’,请仔细检查数据表的名称有没有写正确。
删除数据表中的一条记录:
DELETE FROM userinfo WHERE 字段1 = "xx" and 字段1 = 2;
如果有主键,则直接利用主键确定某一行。
查询表
- 查询表的所有记录:
select * from userinfo;
- 查询表中满足要求的记录:
select * from userinfo where username="xx" and password="xx";
更新数据表:
update userinfo set token="nksd5mhw" where username="admin";