2019 年 1 月 月度总结

2019 年 1 月没有太大的变化,仅仅是敲定了 2019 年上半年的工作问题。

工作相关

正式入职青宁信安,职责从后端转为前端。负责青宁信安的所有前端相关的事宜。后续如果工作时间有充裕的,再考虑接手 Scala 的后台开发事宜。

情感相关

本月情感有较大的突破。但是也要考虑到存在一些不稳定因素,仍需努力。

身体健康相关

本月停止锻炼,下月需要恢复锻炼。

其他

本月 Side Project 有较大突破


年度任务对标

  • 年读书 52 本,1月应读书籍: 4 本。 1月实读书籍: 3 本,落后进度 1 本
    • 《高效前端:Web 高效编程与优化实践》
    • 《程序员的思维训练》
    • 《深阅读》
  • 每年国内旅游 5 次, 1月旅游1次,为广州,游览了广州长隆野生动物园、广州塔。
  • 得到课程学习: 1门 ,戴愫的《怎样成为人脉管理的高手》

向世界交付产品,而不是Demo

作为开发者,最常见的问题是,做项目的适合,所做的产品完全无法交付给第三方使用。你所做的东西只能用于自己使用,无法交付给第三方使用时,实际上你并没有交付出去价值。

当你交付出去了价值的时候,世界才能为你定价。所以,做东西尽可能做成可以交付的产品,交付出去产品,让世界为你估价。

以上心得是我在做美食地图时得到的。

在做美食地图时,我需要做以下事情来保证交付:

  1. 一个安装文档
  2. 一个配置说明
  3. 一个FAQ
  4. 一个升级说明(当你有 breaking changes 时,就需要写清楚升级说明,来辅助你的用户完成版本升级)

小程序的 marker 无法触发 bindmarkertap 事件应该如何处理

TL;DR

如果想要 marker 可以响应 bindmarkertap 事件,需要设定 markerID,这一点文档中并没有标注。

具体情况

在开发美食地图时,出现了一个问题,marker 的点击总是不会触发 bindmarkertap 事件。

我的代码是这样写的

    store.get().then(res => {
      this.setData({
        stores: res.data,
        windowHeight: app.globalData.windowHeight,
      }, () => {
        wx.hideLoading();
        wx.showToast({
          title: '双指缩放可以调整地图可视区域,查看更多美食',
          icon: 'none'
        })
      })
    })
Code language: JavaScript (javascript)

在地图中去调用 stores. marker

在地图上的确可以出现图标,但是无法点击 maker 并触发事件。

通过复制官方的 marker 的数据进行调试后发现,当 maker 有 id 时,marker 就可以触发事件,因此,怀疑是 ID 的问题。

在美食地图小程序中,我使用的是腾讯云提供的小程序·云开发,其使用的是 MongoDB 作为后台的 Database ,默认的主键为 _id,所以,我自己写了代码来转换 _id

      data.map(item => {
        item.id = item._id
      });
Code language: JavaScript (javascript)

对应的 commit :https://github.com/CloudKits/miniprogram-foodmap/commit/5abcad1f756e03a388bb33dd1c699d3cae9ea0c4#diff-f5ea41cdd371d7b65bfdf8d32188e37d

如何平衡深度和广度

我很崇尚广度,在有一个深度以后,去追求更多的广度,并试图将广度发展成深度。

不过,这两天在群里看到了另外一种分类的方法:

  1. 如果你是做基础架构的,广度更重要;看得越多,知道的模式越多,基础架构越牢靠。
  2. 如果你是做业务的,深度更重要;深度越深,业务越稳固。

从另外一个角度来看,也解释了为什么大公司需要的是深度型的人才。

大公司往往业务模型已经确立,他们需要的是人能够把业务更好更快的运转,螺丝钉更适合;而小公司由于没有确定业务模型,需要花时间去做好基础架构,这个时刻广度就非常重要了。

做事先做人

如何做好一件事?

做事要先做人。

一个人要能够把事做完,靠谱,让所有人对你产生靠谱的印象,那你就差不多了。如果你没有办法让别人对你产生靠谱、可以信赖的印象,很难做长久。

低欲望年轻人

由于要留在深圳工作了,就要考虑到租房的问题了。

整理了一下自己的住房需求,发现自己真是一个低欲望的年轻人。

  • 单人床:更大也可,但是至少应该是一张单人床
  • 空调:即使是今天,我依然穿着短袖+5分裤,可以推断夏天我一定会觉得非常热,那么一个空调就有必要了。
  • 能洗澡:作为一个北方来的糙汉子,公用卫生间也OK。而且我的作息和大部分互联网人不一样。12点睡 5 点起,可以避开高峰期。
  • 安静:安静的房子可以让自己有更多的精力去处理自己的事情。
  • 有洗衣机:虽然在大学里都是自己手洗的衣服,但是工作了以后,我可能没有太多的精力去洗衣服了。不过好消息是,按照目前的情况来看,大概率我一年四季穿 T Shirt。

暂时打算去自如看看,先租半年自如的房子。

腾讯之行总结

TL;DR
受限于学历,可能没有办法通过校招补录的申请,因此没有办法在当前这个时间进入腾讯。
详情
我的朋友基本集中在阿里巴巴和腾讯。在经历了 gap year 后,我希望能够再次进入到大企业镀个金,所以联系了两家的朋友。
阿里的朋友反馈由于应届非校招,无法直接进入,认为我必须以运营的方式进入。
而腾讯这边的朋友由于进入了新的项目中,没有锁 HC,还在招人,因此就希望把我搞进去。
元旦过后,我和腾讯的人面试了几轮,都是直接对接业务方面的人,进行沟通。和业务方面的人沟通的很愉快,也体现出了我适合的几个方面:
技术、产品、布道师
他们也愿意接收。不过,最后因为学历的问题,还是没办法进去。
1jgi7
 

实现密码生成器的思路

在项目中有这样一个需求:需要生成一组随机密码,确保安全性。因此,我去翻了一个项目的代码。这里是具体的代码

function GeneratePassword() {
    if (parseInt(navigator.appVersion) <= 3) {
        alert("Sorry this only works in 4.0+ browsers");
        return true;
    }
    var length=8;
    var sPassword = "";
    length = document.aForm.charLen.options[document.aForm.charLen.selectedIndex].value;
    var noPunction = (document.aForm.punc.checked);
    var randomLength = (document.aForm.rLen.checked);
    if (randomLength) {
        length = Math.random();
        length = parseInt(length * 100);
        length = (length % 7) + 6
    }
    for (i=0; i < length; i++) {
        numI = getRandomNum();
        if (noPunction) { while (checkPunc(numI)) { numI = getRandomNum(); } }
        sPassword = sPassword + String.fromCharCode(numI);
    }
    document.aForm.passField.value = sPassword
    return true;
}
function getRandomNum() {
    // between 0 - 1
    var rndNum = Math.random()
    // rndNum from 0 - 1000
    rndNum = parseInt(rndNum * 1000);
    // rndNum from 33 - 127
    rndNum = (rndNum % 94) + 33;
    return rndNum;
}
function checkPunc(num) {
    if ((num >=33) && (num <=47)) { return true; }
    if ((num >=58) && (num <=64)) { return true; }
    if ((num >=91) && (num <=96)) { return true; }
    if ((num >=123) && (num <=126)) { return true; }
    return false;
}

Code language: JavaScript (javascript)

上完代码,接下来来分析一下这段代码

首先,这段代码中有三个函数,其关系如下图所示

image
密码生成器各函数关系图

其中 getRandomNum 生成了一个范围在 33 – 127 的数字。这里是由于在后续生成随机字符串时,用的是 String.fromCharCode,当数字在 33~127 之间时,能够确保生成的数字在输入时比较简单。

image 1
String.fromCharCode 的测试结果

checkPunc 则是检测输出的文字是否可以直接发音,这涉及到记忆的难度的问题,在一个长的字符串中,记忆 ABCD 肯定比记忆逗号、破折号、句号等符号要简单一些,毕竟字母肯定要好记忆点,可以自编语句来实现。

接下来我们来看最核心的 GeneratorPassword 函数:如果将其中的 Dom 操作都忽略掉,并设置一个值。并进行配置后,代码如下:

function GeneratePassword() {
    // 检测浏览器支持
    if (parseInt(navigator.appVersion) <= 3) {
        alert("Sorry this only works in 4.0+ browsers");
        return true;
    }
    var length=8;
    var sPassword = "";
    length = 10 // 此处代码原为使用 dom 函数获取表单数据的代码,来实现自定义长度的功能。
    var noPunction = false// 此处代码原为获取表单数据的代码,控制是否检测密码的可读性
    var randomLength = false // 此处代码原为获取表单数据的代码,控制是否使用随机长度。
    // 如果使用随机长度的密码,则进入循环
    if (randomLength) {
        length = Math.random();
        length = parseInt(length * 100); // 生成 0 ~ 100 之间的数字
        length = (length % 7) + 6 // 对生成的长度取余,则最短为6,最长为12
    }
    // 根据长度进行循环
    for (i=0; i < length; i++) {
        numI = getRandomNum();  // 获取一个随机数
        if (noPunction) { while (checkPunc(numI)) { numI = getRandomNum(); } } // 如果需要判断发音,进行发音判断,判断失败就重新生成,直到成功。
        sPassword = sPassword + String.fromCharCode(numI); // 将生成的字符串加入到原有的字符串最后
    }
    // 设置代码到 Dom 元素中
    return true;
}
Code language: JavaScript (javascript)

其代码逻辑图如下

未命名表单 1
密码生成器的代码逻辑图