向世界交付产品,而不是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 时,我都会在同类型的多种语言中,选择自己没有用过的、不熟悉的,踩坑、持续维护!

生活太苦,连咖啡都甜了

正文

我们对于苦味的感知是源自基因的。在原始人的时代,苦味意味着毒物,如果吃了有苦味,大概率会导致中毒等症状,也得益于此,我们进化出了避开有毒之物的能力,让自己活下来。

我们的基因里是爱甜味的,严格来说,是喜欢糖,因为糖可以让我们的身体充满了能量。刚出生的小朋友,给个糖就能笑呵呵的,给点苦的,就会娃娃大哭,这就基因带给我们的本能,享受甜品,排斥苦味的产物。

严格来说,是自然选择,将那些无法识别苦味的原始人选择没了,使得最终能够识别苦味的个体活了下来。

随着工业革命的出现,近 200 年间,人们开始富足,我们有足够多的食物可以吃,人们终于能吃饱了,人们也从田间地头,走入了高楼大厦,开始了自己的白领工作。

进入了楼宇之中,我们开始了工作,但是似乎我们也并没有因此得到快乐。

的确,我们有了更多的金钱,可以去做更多的事情,可是,我们也失去了自由。

为了更好的工作,我们喝起了咖啡,为了提神,我们从速溶喝到了星巴克,从星巴克喝到了独立小众咖啡馆,从小众咖啡馆喝到了自己做的手冲。

我们对于咖啡的苦味容忍程度变得越来越高,曾经苦涩无比的咖啡,如今喝起觉得淡如白水

是我们进化了么?不是的,生活太苦,连咖啡都甜了

在过去的半年里,经济萧条、实体经济的萎缩、互联网寒冬、HC 紧缩一个个刺激着我们的神经,让我们不禁拉了拉自己的衣服,好让这股寒风吹不到自己。

后记

朋友圈内容

本文源自我在朋友圈看到同学发的一个朋友圈,具体内容如下:

无知也是幸福的

两件事

关于军方

我所在的创业团队中,和军方有合作。Boss 和军方有个单独的群。昨天和 Boss 吃饭,Boss 说“现在不让大家加入这个群,是对大家有好处,因为加入这个群,大家可能就不能出国了。我加入这个群是没办法,大家暂时还是不要进这个群,如果真是一定到了要进去的时候,我在单独聊。”

作为一个平民,可以有足够的时间、空间去做自己的事情,挺幸福的。

关于内容

我在做公众号推荐的时候,突然想起了一个问题,的确,从内容质量上来看,英文世界的内容的确有更多的优质内容。但是任何事务都有两面性,英文世界有更多的优质内容,同样也有更多的劣质内容。在国内可能我们看的很明白的垃圾内容,简单包装一下,英文内容下可能就成为我们追捧的内容。比如“效率”?

第三方服务前端数据安全校验

白名单 or Master Key

坐在腾大写博客,听到了身边的人在讨论前端数据安全校验的方案。

他们需要提供 H5 的SDK ,既然运行在前端,那么应用的 Secret 和 Key 就有可能暴露在浏览器里,如何确保 Secret 和 Key 的安全呢?

一个比较主流的方案就是使用白名单限制。每一个应用绑定特定的几个域名,只有白名单里的域名可以请求服务。

我还想到了另外一个案例。我自己比较喜欢使用 Algolia 提供的搜索服务,在 Algolia 中,区分 Master Key 和 Search Only Key。Search Only Key 只能用于数据查询,而 Master Key 可以用来添加数据。

如果是这样的话,或许可以比较好的处理。