Skip to main content

10 年大佬的酒后箴言

· 11 min read
Lex
非著名前端

I'm drunk and I'll probably regret this, but here's a drunken rank of things I've learned as an engineer for the past 10 years.


The best way I've advanced my career is by changing companies.

Technology stacks don't really matter because there are like 15 basic patterns of software engineering in my field that apply. I work in data so it's not going to be the same as webdev or embedded. But all fields have about 10-20 core principles and the tech stack is just trying to make those things easier, so don't fret overit.

There's a reason why people recommend job hunting. If I'm unsatisfied at a job, it's probably time to move on.

I've made some good, lifelong friends at companies I've worked with. I don't need to make that a requirement of every place I work. I've been perfectly happy working at places where I didn't form friendships with my coworkers and I've been unhappy at places where I made some great friends.

I've learned to be honest with my manager. Not too honest, but honest enough where I can be authentic at work. What's the worse that can happen? He fire me? I'll just pick up a new job in 2 weeks.

If I'm awaken at 2am from being on-call for more than once per quarter, then something is seriously wrong and I will either fix it or quit. pour another glass

Qualities of a good manager share a lot of qualities of a good engineer.

When I first started, I was enamored with technology and programming and computer science. I'm over it.

Good code is code that can be understood by a junior engineer. Great code can be understood by a first year CS freshman. The best code is no code at all.

The most underrated skill to learn as an engineer is how to document. Fuck, someone please teach me how to write good documentation. Seriously, if there's any recommendations, I'd seriously pay for a course (like probably a lot of money, maybe 1k for a course if it guaranteed that I could write good docs.)

Related to above, writing good proposals for changes is a great skill.

Almost every holy war out there (vim vs emacs, mac vs linux, whatever) doesn't matter... except one. See below.

The older I get, the more I appreciate dynamic languages. Fuck, I said it. Fight me.

If I ever find myself thinking I'm the smartest person in the room, it's time to leave.

I don't know why full stack webdevs are paid so poorly. No really, they should be paid like half a mil a year just base salary. Fuck they have to understand both front end AND back end AND how different browsers work AND networking AND databases AND caching AND differences between web and mobile AND omg what the fuck there's another framework out there that companies want to use? Seriously, why are webdevs paid so little.

We should hire more interns, they're awesome. Those energetic little fucks with their ideas. Even better when they can question or criticize something. I love interns. sip

Don't meet your heroes. I paid 5k to take a course by one of my heroes. He's a brilliant man, but at the end of it I realized that he's making it up as he goes along like the rest of us.

Tech stack matters. OK I just said tech stack doesn't matter, but hear me out. If you hear Python dev vs C++ dev, you think very different things, right? That's because certain tools are really good at certain jobs. If you're not sure what you want to do, just do Java. It's a shitty programming language that's good at almost everything.

The greatest programming language ever is lisp. I should learn lisp.

For beginners, the most lucrative programming language to learn is SQL. Fuck all other languages. If you know SQL and nothing else, you can make bank. Payroll specialtist? Maybe 50k. Payroll specialist who knows SQL? 90k. Average joe with organizational skills at big corp? $40k. Average joe with organization skills AND sql? Call yourself a PM and earn $150k.

Tests are important but TDD is a damn cult.

Cushy government jobs are not what they are cracked up to be, at least for early to mid-career engineers. Sure, $120k + bennies + pension sound great, but you'll be selling your soul to work on esoteric proprietary technology. Much respect to government workers but seriously there's a reason why the median age for engineers at those places is 50+. Advice does not apply to government contractors.

Third party recruiters are leeches. However, if you find a good one, seriously develop a good relationship with them. They can help bootstrap your career. How do you know if you have a good one? If they've been a third party recruiter for more than 3 years, they're probably bad. The good ones typically become recruiters are large companies.

Options are worthless or can make you a millionaire. They're probably worthless unless the headcount of engineering is more than 100. Then maybe they are worth something within this decade.

Work from home is the tits. But lack of whiteboarding sucks.

I've never worked at FAANG so I don't know what I'm missing. But I've hired (and not hired) engineers from FAANGs and they don't know what they're doing either.

My self worth is not a function of or correlated with my total compensation. Capitalism is a poor way to determine self-worth.

Managers have less power than you think. Way less power. If you ever thing, why doesn't Manager XYZ fire somebody, it's because they can't.

Titles mostly don't matter. Principal Distinguished Staff Lead Engineer from Whatever Company, whatever. What did you do and what did you accomplish. That's all people care about.

Speaking of titles: early in your career, title changes up are nice. Junior to Mid. Mid to Senior. Senior to Lead. Later in your career, title changes down are nice. That way, you can get the same compensation but then get an increase when you're promoted. In other words, early in your career (<10 years), title changes UP are good because it lets you grow your skills and responsibilities. Later, title changes down are nice because it lets you grow your salary.

Max out our 401ks.

Be kind to everyone. Not because it'll help your career (it will), but because being kind is rewarding by itself.

If I didn't learn something from the junior engineer or intern this past month, I wasn't paying attention.

Oops I'm out of wine.

Paying for classes, books, conferences is worth it. I've done a few conferences, a few 1.5k courses, many books, and a subscription. Worth it. This way, I can better pretend what I'm doing.

Seriously, why aren't webdevs paid more? They know everything!!!

Carpal tunnel and back problems are no joke. Spend the 1k now on good equipment.

The smartest man I've every worked for was a Math PhD. I've learned so much from that guy. I hope he's doing well.

Once, in high school, there was thing girl who was a great friend of mine. I mean we talked and hung out and shared a lot of personal stuff over a few years. Then there was a rumor that I liked her or that we were going out or whatever. She didn't take that too well so she started to ignore me. That didn't feel too good. I guess this would be the modern equivalent to "ghosting". I don't wish her any ill will though, and I hope she's doing great. I'm sorry I didn't handle that better.

I had a girlfriend in 8th grade that I didn't want to break up with even though I didn't like her anymore so I just started to ignore her. That was so fucked up. I'm sorry, Lena.

You know what the best part of being a software engineer is? You can meet and talk to people who think like you. Not necessarily the same interests like sports and TV shows and stuff. But they think about problems the same way you think of them. That's pretty cool.

There's not enough women in technology. What a fucked up industry. That needs to change. I've been trying to be more encouraging and helpful to the women engineers in our org, but I don't know what else to do.

Same with black engineers. What the hell?

I've never really started hating a language or technology until I started becoming intimately familiar with it. Also, I think a piece of tech is good if I hate it but I simultaneously would recommend it to a client. Fuck Jenkins but man I don't think I would be commuting software malpractice by recommending it to a new client.

That being said, git is awful and I have choice but to use it. Also, GUI git tools can go to hell, give me the command line any day. There's like 7 command lines to memorize, everything else can be googled.

Since I work in data, I'm going to give a data-specific lessons learned. Fuck pandas.

My job is easier because I have semi-technical analysts on my team. Semi-technical because they know programming but not software engineering. This is a blessing because if something doesn't make sense to them, it means that it was probably badly designed. I love the analysts on the team; they've helped me grow so much more than the most brilliant engineers.

Dark mode is great until you're forced to use light mode (webpage or an unsupported app). That's why I use light mode.

I know enough about security to know that I don't know shit about security.

Crap I'm out of wine.

Being a good engineer means knowing best practices. Being a senior engineer means knowing when to break best practices.

If people are trying to assign blame to a bug or outage, it's time to move on.

A lot of progressive companies, especially startups, talk about bringing your "authentic self". Well what if your authentic self is all about watching porn? Yeah, it's healthy to keep a barrier between your work and personal life.

I love drinking with my co-workers during happy hour. I'd rather spend time with kids, family, or friends.

The best demonstration of great leadership is when my leader took the fall for a mistake that was 100% my fault. You better believe I would've walked over fire for her.

On the same token, the best leaders I've been privileged to work under did their best to both advocate for my opinions and also explain to me other opinions 'that conflict with mine. I'm working hard to be like them.

Fuck side projects. If you love doing them, great! Even if I had the time to do side-projects, I'm too damn busy writing drunken posts on reddit

Algorithms and data strictures are important--to a point. I don't see pharmacist interviews test trivia about organic chemistry. There's something fucked with our industry's interview process.

Damn, those devops guys and gals are f'ing smart. At least those mofos get paid though.

It's not important to do what I like. It's more important to do what I don't hate.

The closer I am to the product, the closer I am to driving revnue, the more I feel valued regardless of how technical my work is. This has been true for even the most progressive companies.

Linux is important even when I was working in all Windows. Why? Because I eventually worked in Linux. So happy for those weekend where I screwed around installing Arch.

I've learned to be wary for ambiguous buzz words like big data. WTF is "big" data? I've dealt with 10k rows streaming every 10 minutes in Spark and Kafka and dealt with 1B rows batched up hourly in Python and MySQL. Those labels can go fuck themselves.

Not all great jobs are in Silicon Valley. But a lot are.


Finally, if you really want to hurt me, don't downvote I don't care about that. Just ignore this post. Nothing makes me sadder than when I wrote a long post and then nobody responds. So if you hate this post, just ignore.

Why does the data property on a Vue component must be a function

· One min read
Lex
Front End Engineer @ Baoxiaohe

If you don’t get familiar with the basic rules of a framework (programming language, tool, etc) when starting to use it, things won’t work as expected, since it wasn’t conceived that way.

While using Vue for the first time, I made this by mistake:

data: {  message: "some message";}

then, I got the following warning message:

[Vue warn]: The “data” option should be a function that returns a per-instance value in component definitions.

What you should do instead is:

data: function() {  return {    message:'some message'  }}

So, the reason why Vue forces the data property to be a function is that each instance of a component should have its own data object. If we don’t do that, all instances will be sharing the same object and every time we change something, it will be reflected in all instances.

That's all✒

Vue 的响应式原理

· 3 min read
Lex
Front End Engineer @ Baoxiaohe

解析#

Vue 使用大篇幅介绍了他的响应式原理,So let's look how it work.

首先问两个问题:

  • data 对象中的数据发生改变,Vue 是如何得知的(watch)
  • 好的,假设 Vue 知道哪些数据 change 了,那怎么通知对应的 DOM 发生更新呢

我可真会提问题 🤷‍♂️

So,应该知道的是在 JavaScript 中有监听数据变化的 API Object.defineProperty 和 ES6 的 Proxy 了,

Object.defineProperty

事实上,Vue2 就是通过前者实现的,just like

const data = {  message: "可变数据",  date: "June 27,2021",};
Object.keys(data).forEach((key) => {  let value = data[key];
  Object.defineProperty(data, key, {    set(newValue) {      value = newValue;    },    get() {      return value;    },  });});

好的,第一个问题解决了。接下来要通知谁呢,换言之就是如何收集依赖,这个过程用到了发布/订阅者模式。 为了记录谁订阅了属性的改变,我们定义一个 Dep 类来管理依赖 ✍

// 发布者// Dep类管理依赖class Dep {  constructor() {    this.subscriptions = [];  }
  addSub(watcher) {    this.subscriptions.push(watcher);  }
  notify() {    this.subscriptions.forEach((item) => {      item.update();    });  }}
// 订阅者// 中介类Watcher负责将更新通知到其他地方class Watcher {  constructor(name) {    this.name = name;  }
  update() {    console.log(this.name + "已经update");  }}
// 封装数据监测Object.defineProperty(data, key, {  set(newValue) {    value = newValue;    dep.notify();  },  get() {    return value;  },});

Vue响应式原理的解析过程 这就是 Vue 响应式的大致原理。

实现#

通过 120 行 JavaScript 代码实现 Vue 的双向绑定 🎉🎉

class Vue {  constructor(options) {    this.$options = options;    this.$data = options.data;    this.$el = options.el;
    new Observer(this.$data);    // 代理this.$data的数据    Object.keys(this.$data).forEach((key) => this._proxy(key));    // 处理el挂载 传入Vue实例    new Compiler(this.$el, this);  }
  _proxy(key) {    Object.defineProperty(this, key, {      configurable: true,      enumerable: true,      set(newValue) {        this.$data[key] = newValue;      },      get() {        return this.$data[key];      },    });  }}
class Observer {  constructor(data) {    this.data = data;
    Object.keys(data).forEach((key) =>      this.defineReactive(this.data, key, data[key])    );  }
  defineReactive(data, key, val) {    // 为每个属性key创建一个Dep对象    const dep = new Dep();
    Object.defineProperty(data, key, {      enumerable: true,      configurable: true,      get() {        if (Dep.target) {          dep.addSub(Dep.target);        }        return val;      },      set(newValue) {        if (newValue === val) {          return;        }        val = newValue;        dep.notify();      },    });  }}
class Dep {  constructor() {    this.subs = [];  }
  addSub(sub) {    this.subs.push(sub);  }
  notify() {    this.subs.forEach((sub) => sub.update());  }}
const reg = /\{\{(.+)\}\}/;class Compiler {  constructor(el, vm) {    this.el = document.querySelector(el);    this.vm = vm;
    this.frag = this._createFragment();    this.el.appendChild(this.frag);  }
  _createFragment() {    const frag = document.createDocumentFragment();    let child;    while ((child = this.el.firstChild)) {      this._compile(child);      frag.appendChild(child);    }    return frag;  }
  _compile(node) {    if (node.nodeType === 1) {      const attrs = node.attributes;      if (attrs.hasOwnProperty("v-model")) {        const name = attrs["v-model"].nodeValue;        node.addEventListener("input", (e) => (this.vm[name] = e.target.value));      }    }    if (node.nodeType === 3) {      if (reg.test(node.nodeValue)) {        const name = RegExp.$1.trim();        new Watcher(node, name, this.vm);      }    }  }}
class Watcher {  constructor(node, name, vm) {    this.node = node;    this.name = name;    this.vm = vm;    Dep.target = this;    this.update();    Dep.target = null;  }
  update() {    this.node.nodeValue = this.vm[this.name];  }}

That's all🖼

Git 的使用

· One min read
Lex
Front End Engineer @ Baoxiaohe

branch#

  • link 链接远端仓库
git remote add origin remoteAddress
  • push 到远程分支
git push origin remoteBranchName:localBranchName
  • delete branch locally
git branch -d localBranchName
  • delete branch remotely
git push origin --delete remoteBranchName

fetch#

  • 拉取远程分支到本地
git fetch origin remoteBranchName:localBranchName

Vue 的双向绑定

· One min read
Lex
Front End Engineer @ Baoxiaohe

双向数据绑定#

对技术好奇#

v-for源码

组件化的 CSS

· One min read
Lex
Front End Engineer @ Baoxiaohe

Why#

传统 CSS 的书写方式已然不适合主流前端框架盛行的组件化开发。 组件化下的 CSS 应该符合以下条件👇

  • 可以编写局部CSS:具备独立作用域,不污染其他组件内样式
  • 可以编写动态CSS:可以获取当前组件的一些状态,根据状态变化生成不同的 CSS 样式
  • 支持所有的 CSS 特性:伪类、动画、媒体查询等

当然,符合原生 CSS 编写逻辑也非常重要。

How#

React 里写 CSS 并不像 Vue 那样有统一的标准,所以催生出各种各样的写法和CSS库。

内联样式#

优势

  • 样式之间不会有冲突
  • 可以动态获取当前state中的状态 缺点
  • 要使用驼峰标识
  • 代码混乱
  • 不兼容所有特性(伪类/伪元素)
Live Editor
Result
SyntaxError: Unexpected token (1:8)
1 : return ()
            ^

普通 CSS#

.css作为后缀的文件,然后再引入,很熟悉的方式。 问题就是这样的样式是全局样式,不能生成组件局部样式,权重大的标签会层叠权重小的样式。

CSS Modules#

使用很简单,像使用普通 CSS 一样导入即可。关键在于使用.module.css作为文件名后缀,并在导入时取 name what ever you want,命中className时通过name.className.

import styles from "./index.module.css";
<div className={styles.buttons}>  <Link    className="button button--secondary button--lg"    to="/docs/intro"  >    🌌 Start with Tutorial  </Link></div>

css modules 解决了局部作用域的问题,同时也有一些问题✍

  • 不能使用连接符(item-title),这在JavaScript中不被识别,需要使用驼峰命名
  • 不方便动态修改某些样式,仍然需要使用内联样式

CSS-in-JS#

CSS-in-JS 是一种模式,CSS 由 JavaScript 生成而不是在外部文件中定义。这样,All in JS 就成了🤷‍♀️。 当然,这样的开发模式并不受到所有开发者的追捧: Stop using CSS in JavaScript for web development

styled-components && emotion

That's all👏