月度归档:2019年01月

向世界交付产品,而不是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'
        })
      })
    })

在地图中去调用 stores. marker

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

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

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

      data.map(item => {
        item.id = item._id
      });

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

如何平衡深度和广度

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

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

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

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

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

做事先做人

如何做好一件事?

做事要先做人。

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

低欲望年轻人

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

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

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

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

腾讯之行总结

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

 

实现密码生成器的思路

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

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;
}

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

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

密码生成器各函数关系图

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

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;
}

其代码逻辑图如下

密码生成器的代码逻辑图

我如何学习编程?

虽然不是什么大?,但是打算分享一下自己的学习方法,说不定能找到一些同好,共同进步。

由于我不是计算机科班出身的,所以一直以来也都没有以科班的方式来学习编程。更多的是 “Learn By Doing”。

我的 Learn By Doing 一般都会强迫自己去做点什么,比如,昨天上线的 tomarkdown.com 就是我做的一个工具,用来做 HTML 转 Markdown。

和我以往使用的 PHP 的 Laravel 、Ruby 的 Rails 不同,ToMarkdown 使用的是 阿里出品的 Egg.js,运行在 Node.js 环境下。而且,这个项目的服务器并没有使用自己的部署的服务器,而是采用的 Heroku (主要还是懒得再搞 Node.js 的运行环境了,现有的服务器要么是 PHP 要么是 Rails。)。Heroku 的自定义域名不支持 SSL ,就又加入了 CloudFlare 的强制 SSL。

你可以看到,我为了做一个新的项目,去学了新的框架,新的 Platform。对于我来说,只要这些项目还有人用,还没死绝,那么这个项目对于我来说,都是需要维护的,也会变相的让我持续的对这个框架、技术关注,让自己长期掌握这样的技能。

因此,每次做一个新的 Side Project 时,我都会在同类型的多种语言中,选择自己没有用过的、不熟悉的,踩坑、持续维护!