css table 和 html table

在使用antd table组件的时候经常会遇到table的col的宽度的奇怪的表现(自适应等),开始以为是奇怪的display:flex导致的,后来发现是一个table布局的问题,因此研究table相关的表现。

table包括html table和css table,前者是table,tr,th,colgroup等组成的html元素,后者是display为table,table-row,table-header-group,table-column-group的元素。

未完待续。。。:html table的各种表现
相关阅读:

编译

大纲

编译简介

过程:预处理-词法-文法-语意-中间代码-后端

栗子:

词法+文法:基于pegjs

ast的操作:基于babel/recast

前端中的应用

关键词:

  • BNF
  • 文法的处理方法LL,LR,PDA,PEG
  • 表示方法

resource

ppt:https://lqdev.top/static/compile/assets/player/KeynoteDHTMLPlayer.html

Amazon oa以及后续

朋友收到oa,记录一下过程和准备材料。

需要准备智商题。。需要看价值观。。需要刷题库。。感觉和国内(靠一张嘴)还是有区别的。

面经1: https://wdxtub.com/interview/14520850399925.html

oa面经: https://wdxtub.com/interview/14520850399861.html

一亩三分地amazon部分:https://www.1point3acres.com/bbs/tag-136-1.html

quora amazon oa:https://www.quora.com/What-can-I-expect-in-Amazons-SDE-online-assessment-Can-someone-who-has-taken-the-assessment-please-give-me-examples-of-the-types-of-questions-asked

2018秋招-2019春 前端总结

结果:

  1. 第四范式sp(实习转正)
  2. 谷露软件
  3. 声网
  4. 头条实习
  5. 头条sp(真香)
  6. 百度
  7. leetcode cn
  8. 阿里口碑-挂

最后去了头条sp(头条这么累我是不会去的,真香。。)头条一共面了4次(2过2挂),总面试论述估计有15面。。。。

面试总结:

全靠一张嘴吹逼

  • html、css、js基础,js基础 & 代码能力很重要,每一个地方要求深入了解,日常问事件循环,宏任务微任务,手写防抖,手写事件总线,发布订阅啥的。css弱鸡也就写个flex,基本的盒模型要知道,css3都有问但是没有那么关键。dom编程了解一些。日常无限滚动吹逼。
  • 算法:头条的一次挂就是手写个快排,写不出来,挂;最难的可能是一个非递归的二叉树遍历;写过扫雷;图啥的,老老实实刷题
  • 设计模式、计网、操作系统等。。百度一下很多
  • 自己做的东西,主要表现的是解决问题的能力和业务能力,在什么情况下遇到了什么问题,用什么解决。这个准备一个然后吃遍天。
  • 框架。老生常谈的框架生命周期,原理,看没看过源码啊,准备一下就没什么问题了。

头条的面试总结:面了15轮还是有一定发言权利的。一二面日常算法(必有),也就是中等难度,解不出来也要说出来自己的思路。三面一般是leader面,综合考察个人能力(也包括视野,而且自己要发现自己的亮点),一般都是根据之前的东西问一下解决的过程,或者提出一个问题来让你解决。四面要么是给sp要么是前三面分歧太大,需要另一个大佬来定夺。

总体看就是基础没问题,智商没问题,努力没问题,offer就没问题了。

React 的setState

doc

  • react setState的设计原理:https://github.com/facebook/react/issues/11527#issuecomment-360199710 性能需求,react本身的想要实现的行为模式的要求(需要进一步的研究)
  • setState源码解析
    • https://www.cnblogs.com/jasonlzy/p/8046118.html
    • https://www.cnblogs.com/jasonlzy/p/8046256.html
    • https://www.cnblogs.com/jasonlzy/p/8046273.html

key points

  • setState的原理
  • 为什么setState是异步的(怎么实现的)
  • 异步渲染的出发点和实现

 

 

roadhog build dll时的一个bug(can’t resolve ‘fs’)的解决过程

过程:

  • 问题出现:引入npm install @svgr/webpack 插件后无法build dll,报错can’t resolve ‘fs’
  • 问题分析:webpack build的时候肯定是build不正确的pkg,这个pkg是node环境下使用的
  • 搜索:baidu之,一看就不靠谱,换google,发现其他包(出了roadhog)也有这个问题,解决放在是在webpack配置中加入node:{fs:’empty’},意义是解析到fs时给个空对象
  • 使用上述方法解决生产时问题

  • 继续分析问题的根源:不正确的包引入了,调试对应的webpack config,发现@svgr/webpack在build dll的entry中,大概率是这个不对
  • 在webpack config中filter掉这个entry,bug消失,问题成功定位
  • 接下来看这个entry如何生成,查看roadhog源码,buildDll.js,发现其配置中的entry是读取package.json的dependencies然后处理include和exclude之后内容,所以最终的解决方式是把package.json的dependencies中的@svgr/webpack移到devDependencies中
  • 启示:
    • npn install –save 和 npm install –save-dev的时候需要规范
    • roadhog这个属于坑,需要完善文档

react 16.3-16.4 getDerivedStateFromProps等新的生命周期

doc:

  1. bug fix https://reactjs.org/blog/2018/05/23/react-v-16-4.html#bugfix-for-getderivedstatefromprops
  2. 官方文档 https://reactjs.org/docs/react-component.html#static-getderivedstatefromprops
  3. 某中文教程 https://blog.csdn.net/nnxxyy1111/article/details/80832525
  4. react 16.3-16.4生命周期 http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/
  5. 一个非常好的解读 https://zhuanlan.zhihu.com/p/37169569
  6. memoization https://segmentfault.com/a/1190000015301672
  7. 一些新生命周期下的事件(官网译):https://www.zcfy.cc/article/update-on-async-rendering

这个生命周期某种程度上用来替代UNSAFE_componentWillReceiveProps。另外是为了异步渲染(?)。

推荐阅读顺序:5&4,2/6,3,1

特性:

  • 基本功能
    • 通过props往state里面塞东西
  • 每次接受新的props,setState会调用
  • 可能需要在state里面塞入之前的状态来进行对比(官方栗子)

在新的生命周期情况下,一些新的pattern:

  • 在更新props的时候执行一些side effect(拿数据什么的):放在componentDidUpdate里面
  • 在更新props的时候执行重新计算一些数据(some data,指的不是state),使用pureComponent和memoization优化 https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#what-about-memoization(译文:https://blog.csdn.net/nnxxyy1111/article/details/80832525#%E4%BB%80%E4%B9%88%E6%98%AFmemoization)
  • 在更新props的时候reset/重置一些数据,暴力的重新渲染组件就好了(通过更改key),官网说性能差不了多少(谁知道呢)

tips:

  • 期待在constructor,componentWillMount(即将废弃),shouldComponentUpdate,render是pure的,在did*中进行异步操作。实践中在will*进行有effect的操作通常会出发二次渲染,所以直接就放在did里面了。
  • getsnapshotBeforeUpdate目前的应用就是在官网的demo中用于处理dom的scrollTop,更多的使用有待探索

一段的es6 js代码

通过babel了解一下es6的class,let,const和箭头函数

class的实现方式:原型链继承的语法糖,但是es6中未提供静态变量

箭头函数如何处理this:在上文生成一个变量,和arguments:使用上文的arguments,当然箭头函数的写法也是其很重要的一部分。

let:

作用域问题:通过创建不同的变量和调用关系/通过作为函数执行时的参数实现

 

//测试class 和箭头函数
class A {
  static name = () => "liuqi";
  constructor() {
    this.hello = "coool";
    const a = () => {
      console.log("hello", this, arguments);
    };
    const b = function() {
      console.log("hello", this, arguments);
    };
  }
}
class B extends A {
  a = function() {};
}
 
const b = val => {
  console.log(val);
};
 
const a = x => {
  return () => {
    console.log(x);
  };
};
 
// 测试let的上下文
for (let i = 0; i < 5; i++) {
  setTimeout(function() {
    console.log(i);
  }, i * 1000);
}
 
for (var i = 0; i < 5; i++) {
  setTimeout(function() {
    console.log(i);
  }, i * 1000);
}
 
for (var i = 0; i < 5; i++) { setTimeout(() => {
    console.log(i, this);
  }, i * 1000);
}
 
for (let i = 0; i < 5; i++) { setTimeout(() => {
    console.log(i);
  }, 1000);
}
 
if (true) {
  let a;
  if (false) {
    let a;
    let b;
    a = 1;
  }
  a = 2;
}
"use strict";
 
"use strict";
 
// constructor 返回值
function _possibleConstructorReturn(self, call) {
  if (!self) {
    throw new ReferenceError(
      "this hasn't been initialised - super() hasn't been called"
    );
  }
  return call && (typeof call === "object" || typeof call === "function")
    ? call
    : self;
}
 
// 通过原型链进行继承
function _inherits(subClass, superClass) {
  if (typeof superClass !== "function" && superClass !== null) {
    throw new TypeError(
      "Super expression must either be null or a function, not " +
        typeof superClass
    );
  }
  subClass.prototype = Object.create(superClass && superClass.prototype, {
    constructor: {
      value: subClass,
      enumerable: false,
      writable: true,
      configurable: true
    }
  });
  if (superClass)
    Object.setPrototypeOf
      ? Object.setPrototypeOf(subClass, superClass)
      : (subClass.__proto__ = superClass);
}
 
// 类型检查
function _classCallCheck(instance, Constructor) {
  if (!(instance instanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function");
  }
}
 
// 声明一个class/function
var A = function A() {
  var _this = this,
    _arguments = arguments;
 
  _classCallCheck(this, A);
 
  this.hello = "coool";
  var a = function a() {
    console.log("hello", _this, _arguments);
  };
  var b = function b() {
    console.log("hello", this, arguments);
  };
};
 
// 类的静态方法
A.name = function() {
  return "liuqi";
};
 
// 类的继承
var B = (function(_A) {
  _inherits(B, _A);
 
  function B() {
    var _ref;
 
    var _temp, _this2, _ret;
 
    _classCallCheck(this, B);
 
    for (
      var _len = arguments.length, args = Array(_len), _key = 0;
      _key < _len;
      _key++
    ) {
      args[_key] = arguments[_key];
    }
 
    return (
      (_ret = ((_temp = ((_this2 = _possibleConstructorReturn(
        this,
        (_ref = B.__proto__ || Object.getPrototypeOf(B)).call.apply(
          _ref,
          [this].concat(args)
        )
      )),
      _this2)),
      (_this2.a = function() {}),
      _temp)),
      _possibleConstructorReturn(_this2, _ret)
    );
  }
 
  return B;
})(A);
 
var b = function b(val) {
  console.log(val);
};
 
var a = function a(x) {
  return function() {
    console.log(x);
  };
};
 
// let的作用域
var _loop = function _loop(_i) {
  setTimeout(function() {
    console.log(_i);
  }, _i * 1000);
};
 
for (var _i = 0; _i < 5; _i++) {
  _loop(_i);
}
 
for (var i = 0; i < 5; i++) {
  setTimeout(function() {
    console.log(i);
  }, i * 1000);
}
 
for (var i = 0; i < 5; i++) {
  setTimeout(function() {
    console.log(i, undefined);
  }, i * 1000);
}
 
var _loop2 = function _loop2(_i2) {
  setTimeout(function() {
    console.log(_i2);
  }, 1000);
};
 
for (var _i2 = 0; _i2 < 5; _i2++) {
  _loop2(_i2);
}
 
// let的作用域
if (true) {
  var _a = void 0;
  if (false) {
    var _a2 = void 0;
    var _b = void 0;
    _a2 = 1;
  }
  _a = 2;
}

let a = 1;
console.log("1:", a);
new Promise((resolve, reject) => {
  console.log("2:", a);
  resolve(1);
  console.log("3:", a);
  reject(2);
  console.log("4:", a);
})
  .then(val => {
    a = 2;
    console.log("5:", a);
  })
  .catch(val => {
    a = 3;
    console.log("6:", a);
  });
console.log("7:", a);
 
a = 4;
console.log("8:", a);

输出:

1: 1
2: 1
3: 1
4: 1
7: 1
8: 4
5: 2

分析:promise的then是异步的,promise resolve之后的状态就确定了,不能再改变了