前端JavaScript高级面试技巧[1]

第1章 课程介绍

1-1 导学

课程概述

  • 做什么?— 讲解前端 JS 高级面试题
  • 哪些部分?— 高级基础, 框架原理, app混合开发
  • 技术?— JS、ES6、虚拟DOM、vue、React、hybrid

知识点介绍

  • 基础知识:ES6 常用语法、原型高级应用、异步全面讲解
  • 框架原理:虚拟 DOM、MVVM vue、组件化 React
  • 混合开发:hybrid、hybrid vs H5、前端客户端通讯

课程安排

  • 高级基础
    1. ES6 常用语法:Class Module Promise 等
    2. 原型高级应用:结合 jQuery 和 zepto 源码
    3. 异步全面讲解:从原理到 jQuery 再到 Promise
  • 框架原理
    1. 虚拟 DOM:存在价值,如何使用,diff 算法
    2. vue:MVVM,vue 响应式、模板解析、渲染
    3. React:组件化,JSX,vdom,setState
    4. 对比:有主见,自圆其说
  • App混合开发
    1. hybrid:基础、和 h5 对比,上线流程
    2. 通讯:通讯原理,JS-Bridge 封装

讲授方式

  • 先出面试题,带领大家思考
  • 通过题目引出知识点,扩充讲解知识体系
  • 最后通过学到的知识点,解答题目

课程收获

  • 从深度和广度都扩充了自己的知识体系
  • 学会如何高效学习
  • 深入理解常用框架的实现原理和 hybrid 应用

1-2 课程重要提示

1-3 架构-题目

ES6

模块化的使用和编译环境?

Class 与 JS 构造函数的区别?

Promise 的用法?

ES6 其他常用功能?

异步

什么是单线程,和异步有什么关系?

什么是 event-loop?

目前 JS 解决异步的方案有哪些?

如果只用 jquery 如何解决异步?

Promise 的标准?

async/await 的使用?

原型

原型如何实际应用?

原型如何满足扩展?

vdom

什么是 vdom,为何要用 vdom?

vdom如何使用,核心函数有哪些?

了解 diff 算法吗?

MVVM

之前使用 jquery 和现在使用 Vue 或 React 框架的区别?

你如何理解MVVM?

Vue 如何实现响应式?

Vue 如何解析模版?

介绍 Vue 的实现流程?

组件化

对组件化的理解?

JSX 是什么?

JSX 和 vdom 什么关系?

简述 React 的 setState?

简述自己如何比较 React 和 Vue?

hybrid

hybrid 是什么,为何要用hybrid?

hybrid 如何更新上线?

hybrid 和 h5 有何区别?

JS 如何与客户端通信?

第2章 ES6 语法

2-1 开始

ES6

  • 开发环境已经普及使用
  • 浏览器环境却支持不好(需要开发环境编译)
  • 内容很多,重点了解常用语法
  • 面试:开发环境的使用 + 重点语法的掌握

题目

  • ES6 模块化如何使用,开发环境如何打包?
  • Class 和普通构造函数有何区别?
  • Promise 的基本使用和原理?
  • 总结一下 ES6 其他常用功能?

2-2 模块化

【题目】

ES6 模块化如何使用,开发环境如何打包?

【知识点】

1. 模块化的基本语法

  • export 语法
// util1.js
export default {
  a: 100
};

// util2.js
export function fn1() {
  alert('fn1');
};
export function fn2() {
  alert('fn2');
};
  • import 语法
// index.js
import util1 from './util1.js';
import { fn1, fn2 } from './util2.js';

console.log(util1);
fn1();
fn2();

2. 开发环境配置

babel

  • 安装 babel
1. 电脑有 node 环境,运行 npm init
2. npm install --save-dev babel-core babel-preset-es2015 babel-preset-latest
3. 创建 .babelrc 文件,输入以下内容:
    { 
        "presets": ["es2015", "latest"],
        "plugins": []
    }
4. sudo npm install -g babel-cli
5. babel --version
  • 使用 babel
1. 创建:./src/index.js
2. 内容:[1, 2, 3].map(item => item + 1);
3. 运行:babel ./src/index.js

webpack

1. npm install webpack webpack-cli babel-loader@^7.1.2 --save-dev
2. 配置 webpack.config.js,输入以下内容:
    module.exports = { 
        entry: './src/index.js',
        output: { 
          path: __dirname,
          filename: './build/bundle.js'
        },
        module: { 
          rules: [{
            test: /\.js?$/,
            exclude: /{node_modules}/,
            loader: 'babel-loader'
          }]
        }
    }
3. 配置 package.json 中的 scripts
    "scripts": {
        "start": "webpack"
    }
4. 运行 npm start
5. 创建:index.html
    <script type="text/javascript" src="./build/bundle.js"></script>
6. http-server -p 8881
7. 访问 http://localhost:8881/index.html

rollup

  • 安装 rollup

https://www.rollupjs.com/guide/tutorial rollup 中文网

1. npm init
2. npm i rollup rollup-plugin-node-resolve rollup-plugin-babel@^3.0.3 babel-plugin-external-helpers babel-preset-latest babel-core --save-dev
3. 配置 .babelrc
{
  "presets": [
    ["latest", {
      "es2015": {
        "modules": false
      }
    }]
  ],
  "plugins": ["external-helpers"]
}
4. 配置  rollup.config.js
import babel from 'rollup-plugin-babel';
import resolve from 'rollup-plugin-node-resolve';

export default {
  input: 'src/index.js',
  output: {
    file: 'build/bundle.js',
    format: 'cjs'
  },
  plugins: [
    resolve(),
    babel({
        exclude: 'node_modules/**'
    })
  ]
};
  • 使用 rollup
1. 将 webpack 环境的 JS 代码拷贝过来
2. 修改 package.json 的 scripts
  "scripts": {
    "start": "rollup -c rollup.config.js"
  }
3. 运行 npm start
  • 关于工具
rollup 功能单一,webpack 功能强大
参考设计原则和《Linux/Unix设计思想》
工具要尽量功能单一,可集成,可扩展
wangEditor 用的 gulp + rollup

3. 关于 JS 众多模块化标准

  • 没有模块化
  • AMD 成为标准,require.js (也有 CMD)
  • 前端打包工具,是的 nodejs 模块化可以被使用
  • ES6 出现,想统一现在所有模块化标准
  • nodejs 积极支持,浏览器尚未统一
  • 你可以自造 lib ,但是不要自造标准!!!

【解答】

  • 语法: import export (注意有无 default)
  • 环境: babel 编译 ES6 语法,模块化可用 webpack 和 rollup
  • 扩展: 说一下自己对模块化标准统一的期待

2-9 class

【题目】

Class 与 JS 构造函数的区别?

  • Class 在语法上更加贴合面向对象的写法
  • Class 实现继承更加易读、易理解
  • 更易于写 java 等后端语言的使用
  • 本质还是语法糖,使用 prototype

【知识点】

JS 构造函数

function MathHandle(x, y) {
  this.x = x;
  this.y = y;
}

MathHandle.prototype.add = function () {
  return this.x + this.y;
};

var m = new MathHandle(1, 2);
console.log(m.add());

// typeof MathHandle // "function"
// MathHandle === MathHandle.prototype.constructor // true
// m.__proto__ === MathHandle.prototype // true

Class 基本语法

class MathHandle {
  constructor (x, y) {
    this.x = x;
    this.y = y;
  }

  add() {
    return this.x + this.y;
  }
}
const m = new MathHandle(1, 2);
console.log(m.add());
// typeof MathHandle // "function"
// MathHandle === MathHandle.prototype.constructor // true
// m.__proto__ === MathHandle.prototype // true

语法糖

class MathHandle {
  // ...
}

typeof MathHandle // "function"
MathHandle === MathHandle.prototype.constructor // true

继承

  • 继承 - JS
ES6 之前的继承,是把低级构造函数的原型,赋值成高级构造函数的实例这种方式来实现的
// 动物
function Animal() {
  this.eat = function () {
    console.log('animal eat');
  }
}
// 狗
function Dog() {
  this.bark = function () {
    console.log('dog bark');
  }
}
// 绑定原型,实现继承
Dog.prototype = new Animal();
// 哈士奇
var hashiqi = new Dog();
hashiqi.eat(); // animal eat
hashiqi.bark(); // dog bark
  • 继承 - Class
// 动物
class Animal {
  constructor(name) {
    this.name = name;
  }
  eat() {
    console.log(`${this.name} eat`);
  }
}
// 狗
class Dog extends Animal {
  constructor(name) {
    super(name);
    this.name = name;
  }
  say() {
     console.log(`${this.name} say`);
  }
}
// 哈士奇
const dog = new Dog('哈士奇');
dog.say(); // 哈士奇 say
dog.eat(); // 哈士奇 eat

【解答】

class Ad extends Component {
    constructor(props) {
        super(props);
        this.state = {
            data: []
        }
    }
    render() {
        return (
            <div>Hello, World!</div>
        )
    }
    componentDidMount() {

    }
}

2-13 Promise

【题目】

Promise 的用法?

【知识点】

Promise 的基本使用

  • Callback Hell
function loadImg(src, callback, fail) {
  var img = document.createElement('img');
  img.onload = function () {
    callback(img);
  }
  img.onerror = function () {
    fail();
  }
  img.src = src;
}

var src = 'https://www.imooc.com/courseimg/s/cover042_s.jpg';
loadImg(src, function (img) {
  console.log(img.width);
}, function () {
  console.log('failed');
})
  • Promise 语法
function loadImg(src) {
  const promise = new Promise(function (resolve, reject) {
    var img = document.createElement('img');
    img.onload = function () {
      resolve(img);
    }
    img.onerror = function () {
      reject();
    }
    img.src = src;
  })
  return promise;
};

var src = 'https://www.imooc.com/courseimg/s/cover042_s.jpg';
var result = loadImg(src);

result.then(function (img) {
  console.log(img.width);
}, function () {
  console.log('failed');
});

result.then(function (img) {
  console.log(img.height);
});

【解答】

  • new Promise 实例,而且要 return
  • new Promise 时要传入函数,函数有 resolve reject 两个参数
  • 成功时执行 resolve() 失败时执行 reject()
  • then 监听结果

2-16 总结一下 ES6 其他常用功能

题目

总结一下 ES6 其他常用功能?

  • let/const
  • 多行字符串/模板变量
  • 解构赋值
  • 块级作用域
  • 函数默认参数
  • 箭头函数 (this)

知识点

  • let/const
// JS
var i = 10;
i = 100;

// ES6
let i = 10;
i = 100;  // 正确
const j = 20;
j = 200;  // 报错
  • 多行字符串/模板变量
// JS
var name = 'zhangsan', age = 20, html = '';
html += '<div>';
html += ' <p>' + name + '</p>';
html += ' <p>' + age + '</p>';
html += '</div>';

// ES6
const name = 'zhangsan', age = 20;
const html = `<div>
                     <p>${name}</p>
                     <p>${age}</p>
             </div>`;
console.log(html);
  • 解构赋值
// JS
var obj = { a: 100, b: 200 };
var a = obj.a;
var b = obj.b;

var arr = ['xxx', 'yyy', 'zzz'];
var x = arr[0];
// ES6
const obj = { a: 10, b: 20, c: 30 };
const { a, c } = obj;
console.log(a);
console.log(c);

const arr = ['xxx', 'yyy', 'zzz'];
const [x, y, z] = arr;
console.log(x);
console.log(y);
console.log(z);
  • 块级作用域
// JS
var obj = { a: 100, b: 200 };
for (var item in obj) {
  console.log(item);
}
console.log(item); // 'b'

// ES6
const obj = { a: 100, b: 200 };
for (let item in obj) {
  console.log(item);
}
console.log(item); // undefined
  • 函数默认参数
// JS
function fn(a, b) {
  if (b == null) {
    b = 0;
  }
}

// ES6
function fn(a, b=0) {

}
  • 箭头函数
// JS
var arr = [1, 2, 3];
arr.map(function (item) {
  return item + 1;
});

// ES6
const arr = [1, 2, 3];
arr.map(item => item + 1);
arr.map((item, index) => {
  console.log(index);
  return item + 1;
});
function fn() {
  console.log('real', this); // {a: 100}
  var arr = [1, 2, 3];
  // 普通 JS
  arr.map(function (item) {
    console.log('js', this); // window
    return item + 1;
  });
  // 箭头函数
  arr.map(item => {
    console.log('es6', this); // {a: 100}
    return item + 1;
  });
}
fn.call({a: 100});

第3章 原型

3-1 开始

  • 《前端 JS 面试技巧》已经讲解过原型的基础知识
  • 高级面试题,光会原型基础还不够,还要实际应用
  • zepto jquery 中如何用原型?
  • 顺便也算是解读了 zepto 和 jquery 的部分源码

题目

原型如何实际应用?

  • jquery 和 zepto 的简单使用
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <p>jquery test 1</p>
    <p>jquery test 2</p>
    <p>jquery test 3</p>

    <div id="div1">
        <p>jquery test in div</p>
    </div>

    <script type="text/javascript" src="./jquery-3.2.1.js"></script>
    <script type="text/javascript">
        var $p = $('p');
        $p.css('color', 'red'); // css 是原型方法
        console.log($p.html()); // html 是原型方法
        
        var $div1 = $('#div1')
        $div1.css('color', 'blue'); // css 是原型方法
        console.log($div1.html()); // html 是原型方法
    </script>
</body>
</html>
  • zepto 如何使用原型
(function (window) {

  var zepto = {};

  function Z(dom, selector) {
      var i, len = dom ? dom.length : 0;
      for (i = 0; i < len; i++) {
          this[i] = dom[i];
      }
      this.length = len;
      this.selector = selector || '';
  }

  zepto.Z = function (dom, selector) {
      return new Z(dom, selector);
  };

  zepto.init = function (selector) {
      var slice = Array.prototype.slice;
      var dom = slice.call(document.querySelectorAll(selector));
      return zepto.Z(dom, selector);
  };

  var $ = function (selector) {
      return zepto.init(selector);
  };
  window.$ = $

  $.fn = {
      css: function (key, value) {
          alert('css');
      },
      html: function (value) {
          return '这是一个模拟的 html 函数';
      }
  }
  Z.prototype = $.fn;
})(window);
  • jquery 如何使用原型
(function (window) {

    var jQuery = function (selector) {
        return new jQuery.fn.init(selector)
    };

    jQuery.fn = {
        css: function (key, value) {
            alert('css');
        },
        html: function (value) {
            return 'html';
        }
    };

    var init = jQuery.fn.init = function (selector) {
        var slice = Array.prototype.slice;
        var dom = slice.call(document.querySelectorAll(selector));

        var i, len = dom ? dom.length : 0;
        for (i = 0; i < len; i++) {
            this[i] = dom[i];
        }
        this.length = len;
        this.selector = selector || '';
    }

    init.prototype = jQuery.fn;

    window.$ = jQuery;

})(window);

原型如何满足扩展?

第4章 异步

  • 《前端 JS 面试技巧》讲到异步的基础
  • 高级面试会问到更多的内容
  • 如 event-loop Promise Async/Await 等

题目

什么是单线程,和异步有什么关系?

  • 单线程 - 只有一个线程,同一时间只能做一件事
// 循环运行期间,JS 执行和 DOM 渲染暂时卡顿
var i, sum = 0;
for (i = 0; i < 1000000000; i++) {
  sum += i;
}
console.log(sum);

// alert 不处理, JS 执行和 DOM 渲染暂时卡顿
console.log(1);
alert('hello');
console.log(2);
  • 原因 - 避免 DOM 渲染的冲突
浏览器需要渲染 DOM
JS 可以修改 DOM 结构
JS 执行的时候,浏览器 DOM 渲染会暂停
两段 JS 也不能同时执行(都修改 DOM 就冲突了)
webworker 支持多线程,但是不能访问 DOM
  • 解决方案 - 异步
    什么是 callback?异步完成之后要执行的函数
问题一:没按照书写方式执行,可读性查
问题二:callback 中不容易模块化

什么是 event-loop?

  • 文字解释
事件轮询,JS 实现异步的具体解决方案
同步代码,直接执行
异步函数先放在 "异步队列" 中
待同步函数执行完毕,轮询执行 "异步队列" 的函数

如果只用 jquery 如何解决异步?- Deferred

  • 是否用过 jQuery 的 Deferred
jQuery 1.5 的变化
使用 jQuery Deferred
初步引入 Promise 概念
  • jQuery 1.5 的变化 - 1.5 之前
var ajax = $.ajax({
  url: 'data.json',
  success: function () {
    console.log('success1');
    console.log('success1');
    console.log('success1');
  },
  error: function () {
    console.log('error');
  }
})
console.log(ajax); // 返回一个 XHR 对象
  • jQuery 1.5 的变化 - 1.5 之后
var ajax = $.ajax('data.json');
ajax.done(function () {
      console.log('success 1');
    })
    .fail(function () {
      console.log('error');
    })
    .done(function () {
      console.log('success 2');
    })
console.log(ajax); // 返回一个 deferred 对象
// 很像 Promise 的写法
var ajax = $.ajax('data.json');
ajax.then(function () {
        console.log('success 1');
      }, function () {
        console.log('error 1');
      })
      .then(function () {
        console.log('success 2');
      }, function () {
        console.log('error 2');
      })
  • jQuery 1.5 的变化
无法改变 JS 异步和单线程的本质
只能从写法上杜绝 callback 这种形式
它是一种语法糖形式,但是解耦了代码
很好的体现:开放封闭原则 ( 对扩展开发,对修改封闭 )
  • 使用 jQuery Deferred
var wait = function () {
  var task = function () {
     console.log('执行完成');
     console.log('此处新需求......');
     console.log('第一步');
     console.log('第二步');
     console.log('第三步');
  };
  setTimeout(task, 2000);
};
wait();
function waitHandle() {
   var dtd = $.Deferred();
   var wait = function (dtd) {
       var task = function () {
           console.log('执行完成');
           dtd.resolve();
           // dtd.reject()
       }
       setTimeout(task, 2000);
       return dtd.promise(); // return dtd; => return dtd.promise();
   }
   return wait(dtd);
}

var w = waitHandle();
// w.then(function () {  
// => 1.w 接收到的不再是一个 dtd 对象,而是一个 promise 对象
// => 2.只有 .then .done .fail 这种被动监听方法
// => 3.不再支持 .resolve .reject 这种主动方法的调用
$.when(w).then(function () {
    console.log('ok 1');
}, function () {
    console.log('err 1');
});
  • jQuery 里引入 promise
总结,dtd 的 API 可分成两类,用意不同
第一类: dtd.resolve  dtd.reject
第二类: dtd.then  dtd.done  dtd.fail
这两类应该分开,否则后果很严重!
可以在上面代码最后执行 dtd.reject() 试一下后果

Promise 的基本使用和原理?

  • 基本语法回顾
function loadImg(src) {
  const promise = new Promise(function (resolve, reject) {
    var img = document.createElement('img');
    img.onload = function () {
      resolve(img);
    }
    img.onerror = function () {
      reject();
    }
    img.src = src;
  })
  return promise;
};

var src = 'https://www.imooc.com/courseimg/s/cover042_s.jpg';
var result = loadImg(src);

result.then(function (img) {
  console.log(img.width);
}, function () {
  console.log('failed');
});

result.then(function (img) {
  console.log(img.height);
});
  • 异常捕获
// 捕获程序错误异常
// throw new Error('自定义错误');

result.then(function (img) {
  console.log(img.width);
  return img;
}).then(function (img) {
  console.log(img.height);
}).catch(function (ex) {
  // 统一捕获异常
  console.log(ex);
})
// 捕获业务逻辑异常
// reject('图片加载失败');
// var src = 'https://cover042_sXXX.jpg';

result.then(function (img) {
  console.log(img.width);
  return img;
}).then(function (img) {
  console.log(img.height);
}).catch(function (ex) {
  // 统一捕获异常
  console.log(ex);
})
  • 多个串联
//业务需求;先加载一个,再加载另外一个
var src1 = 'https://www.imooc.com/courseimg/s/cover042_s.jpg';
var result1 = loadImg(src1);
var src2 = 'https://coding.imooc.com/static/module/class/content/img/190/section5-img.png';
var result2 = loadImg(src2);

// 链式操作
result1.then(function (img) {
  console.log('第一个图片加载完成', img.width); // 240
  return result2;
}).then(function (img) {
  console.log('第二个图片加载完成', img.width); // 998
}).catch(function (ex) {
  // 统一捕获异常
  console.log(ex);
})
  • Promise.all 和 Promise.race
// 全部完成才执行
Promise.all([result1, result2]).then(function (datas)  {
 console.log(datas[0]);
 console.log(datas[1]);
});
// 只要有一个完成就执行
Promise.race([result1, result2]).then(function (data)  {
 console.log(data);
});
  • Promise 标准
// 关于“标准”的闲谈
任何技术推广使用都需要一套标准来支撑
如 html js css http 等,无规矩不成方圆
任何不符合标准的东西,终将会被用户抛弃
不要挑战标准,不要自造标准
// Promise 标准 - 状态变化
三种状态:pending fulfilled rejected
初始状态是 pending
pending 变为 fulfilled ,或者 pending 变为 rejected
状态变化不可逆
// Promise 标准 - then
Promise 实例必须实现 then 这个方法
then() 必须可以接收两个函数作为参数
then() 返回的必须是一个 Promise 实例

介绍一下 async/await(和 Promise 的区别、联系)?

  • then 只是将 callback 拆分了
var w = waitHandle();
w.then(function () { 
    console.log('ok 1');
}, function () {
    console.log('err 1');
}).then(function () { 
    console.log('ok 2');
}, function () {
    console.log('err 2');
});
  • async/await 是最直接的同步写法
const load = async function () {
  const result1 = await loadImg(src1);
  console.log(result1);
  const result2 = await loadImg(src2);
  console.log(result2);  
}
load();
  • 语法
使用 await ,函数必须用 async 标识
await 后面跟的是一个 Promise 实例
需要 babel-polyfill
  • 坑来了
// webpack 打包
1.首先,npm i babel-polyfill -D
2.运行报错,Uncaught ReferenceError: regeneratorRuntime is not defined
3.在 .babelrc 文件中添加:
    "plugins": [
        [
            "transform-runtime",
            {
                "helpers": false,
                "polyfill": false,
                "regenerator": true,
                "moduleName": "babel-runtime"
            }
        ]
    ]
4.运行报错,ReferenceError: Unknown plugin "transform-runtime" specified
5.npm install babel-plugin-transform-runtime -D
6.运行再次报错,Cannot use import statement outside a module
7.<script type="module"></script>
8.成功
// rollup 打包
1.npm i babel-polyfill -D
之前也报和 webpack 相同的错误,自己就好了,原因未知
  • 小结
promise 是对异步回调的封装
async await 是使用 promise 时的一种扩展
完全是同步的写法,再也没有回调函数
但是:改变不了 JS 单线程、异步的本质

目前 JS 解决异步的方案有哪些?

  • jQuery Deferred
  • Promise
  • Async/Await
  • Generator
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,658评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,482评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,213评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,395评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,487评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,523评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,525评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,300评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,753评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,048评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,223评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,905评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,541评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,168评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,417评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,094评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,088评论 2 352

推荐阅读更多精彩内容

  • 前端开发面试题 面试题目: 根据你的等级和职位的变化,入门级到专家级,广度和深度都会有所增加。 题目类型: 理论知...
    怡宝丶阅读 2,576评论 0 7
  • 《家庭公约》“日念一好”打卡第137天(张利平2019.11.13) 日念家人一好处,念力加持享幸福! 正念、正行...
    张利平专注国学教育139876阅读 171评论 0 0
  • 从惠州回来,到过年从过年的年例,到坐车上来广州,再到从我哥家到学校,再到和你单独在一起,这个过程里面,你我比以前更...
    减肥的女孩阅读 195评论 0 0
  • 小时候过年 大人给小孩买新衣服 是期待的幸福 现在过年 还是大人给小孩买新衣服 只不过 以前的小孩长成了大人 曾经...
    19号船长阅读 213评论 0 0