源泉

源泉 查看完整档案

武汉编辑武汉软件工程职业学院  |  信息安全 编辑nintyteam  |  端茶倒水 编辑 79px.com 编辑
编辑

喜欢简单的东西。习惯听歌写代码。
没事的时候,喜欢打打dota,下下象棋,写写代码做点小东西。
个人网站:https://79px.com
个人简历:https://eternityspring.github...
个人小程序:黄龙客栈

个人动态

源泉 发布了文章 · 9月6日

无芯设备-应对华为无芯可用

现状

华为的麒麟芯片只能生产到2020.9.15号。

思考与规则

环境压力,断供华为芯片的同时也强行禁止为华为生产自己的芯片。也就一位置如果按照现状,总有一天会有无芯可用的时候。但是所有的规则均没有针对个人以及华为的客户。

吃瓜的异想

既然总有一天会无芯可用,那么在华为生产设备的时候是否可以像卖手机不带电话卡一样,做出那种无芯设备。客户买到设备后自主购买芯片安装即可。当然,这也只是个人的猜想。

查看原文

赞 0 收藏 0 评论 0

源泉 发布了文章 · 6月15日

树莓派烧写Ubuntu20

默认用户名密码:
ubuntu
ubuntu
输入完毕后,按照提示重置ubuntu的密码即可。

ubuntu 切换 root 用户:
先修改 root 用户密码,然后使用 su root切换:

sudo passwd

设置root密码,然后切换:

su root

然后输入上边设置的密码即可。

查看原文

赞 0 收藏 0 评论 0

源泉 发布了文章 · 6月8日

threejs load obj 文件 合并 group中所有mesh

需求

load obj文件得到的是个group 有多个mesh ,现在需要合并,方便做移动操作。

解决方法

创建geometry

let geometry = new THREE.Geometry();

遍历 merge

for(let i = 0;i<arr.length;i++){
            let item = new THREE.Geometry().fromBufferGeometry( arr[i].geometry )
            geometry.merge( item,arr[i].matrix );
        }

注意

尝试过 BufferGeometry 并不好用,所以这里吧 Geometry 转成了 BufferGeometry

查看原文

赞 0 收藏 0 评论 0

源泉 收藏了文章 · 3月10日

大厂面试题分享:如何让(a===1&&a===2&&a===3)的值为true?

unnamed.jpg

当我第一次看到这一题目的时候,我是比较震惊的,分析了下很不合我们编程的常理,并认为不大可能,变量a要在同一情况下要同时等于1,2和3这三个值,这是天方夜谭吧,不亚于哥德巴赫1+1=1的猜想吧,不过一切皆有可能,出于好奇心,想了许久之后我还是决定尝试解决的办法。

我的思路来源于更早前遇到的另外一题相似的面试题:

// 设置一个函数输出一下的值
f(1) = 1;
f(1)(2) = 2;
f(1)(2)(3) = 6;

当时的解决办法是使用toString或者valueOf实现的,那我们先回顾下toStringvalueOf方法,方便我们更深入去了解这类型的问题:

比如我们有一个对象,在不重写toString()方法和valueOf()方法的情况下,在 Node 或者浏览器输出的结果是这样的

class Person {
  constructor() {
    this.name = name;
  }
}

const best = new Person("Kobe");
console.log(best); // log: Person {name: "Kobe"}
console.log(best.toString()); // log: [object Object]
console.log(best.valueOf()); // log: Person {name: "Kobe"}
console.log(best + "GiGi"); // log: [object Object]GiGi
bestPerson
best.toString()[object Object]
best.valueOf()Person
best + 'GiGi'[object Object]GiGi

从上面的输出我们可以观察到一个细节,toString()输出的是[object Object],而valueOf()输出的是Person对象本身,而当运算到best + 'GiGi'的时候竟然是输出了[object Object]GiGi,我们可以初步推断是对象调用的toString()方法得到的字符串进行计算的,难道是运算符+的鬼斧神工吗?

为了验证我们上一步的推断,我们稍微做一点改变,把 valueOf 方法进行一次复写:

class Person {
  constructor(name) {
    this.name = name;
  }
  // 复写 valueOf 方法
  valueOf() {
    return this.name;
  }
}
bestPerson
best.toString()[object Object]
best.valueOf()Person
best + 'GiGi'KobeGiGi

这次跟上面只有一处产生了不一样的结果,那就是最后的best + 'GiGi'前后两次结果在复写了valueOf()方法之后发生了改变,从中我们可以看出来,对象的本质其实没有发生根本的改变,但是当它被用作直接运算的时候,它的值是从复写的valueOf()中获取的,并继续参与后续的运算。

当然不要忘了我们还有个toString()方法,所以我们也复写它,看看结果会不会也受影响:

class Person {
  constructor(name) {
    this.name = name;
  }
  valueOf() {
    return this.name;
  }
  toString() {
    return `Bye ${this.name}`;
  }
}
bestPerson
best.toString()Bye Kobe
best.valueOf()Kobe
best + 'GiGi'KobeGiGi

我们发现 best + 'GiGi'还是没有发生任何改变,还是使用我们上一次复写valueOf()的结果

其实我们重写了valueOf方法,不是一定调用valueOf()的返回值进行计算的。而是valueOf返回的值是基本数据类型时才会按照此值进行计算,如果不是基本数据类型,则将使用toString()方法返回的值进行计算。

class Person {
  constructor(name) {
    this.name = name;
  }
  valueOf() {
    return this.name;
  }
  toString() {
    return `Bye ${this.name}`;
  }
}
const best = new Person({ name: "Kobe" });

console.log(best); // log: Person name: {name: "Kobe"}
console.log(best.toString()); // log: Bye [object Object]
console.log(best.valueOf()); // log: Person {name: "Kobe"}
console.log(best + "GiGi"); // log: [object Object]10
bestPerson
best.toString()Bye [object Object]
best.valueOf(){name: "Kobe"}
best + 'GiGi'Bye [object Object]GiGi

看上面的例子,现在传入的name是一个对象new Person({ name: "Kobe" }),并不是基本数据类型,所以当执行加法运算的时候取toString()方法返回的值进行计算,当然如果没有valueOf()方法,就会去执行toString()方法。

所以铺垫了这么久,我们就要揭开答案,我们正是使用上面这些原理去解答这一题:

class A {
  constructor(value) {
    this.value = value;
  }
  toString() {
    return this.value++;
  }
}
const a = new A(1);
if (a == 1 && a == 2 && a == 3) {
  console.log("Hi Eno!");
}

这里就比较简单,直接改写toString()方法,由于没有valueOf(),当他做运算判断a == 1的时候会执行toString()的结果。

class A {
  constructor(value) {
    this.value = value;
  }
  valueOf() {
    return this.value++;
  }
}
const a = new A(1);
if (a == 1 && a == 2 && a == 3) {
  console.log("Hi Eno!");
}

当然,你也可以不使用toString,换成valueOf也行,效果也是一样的:

class A {
  constructor(value) {
    this.value = value;
  }
  valueOf() {
    return this.value++;
  }
}

const a = new A(1);
console.log(a);
if (a == 1 && a == 2 && a == 3) {
  console.log("Hi Eno!");
}

所以,当一个对象在做运算的时候(比如加减乘除,判断相等)时候,往往会有valueOf()或者toString的调用问题,这个对象的变量背后通常隐藏着一个函数。

当然下面这题原理其实也是一样的,附上解法:

// 设置一个函数输出一下的值
f(1) = 1;
f(1)(2) = 2;
f(1)(2)(3) = 6;

function f() {
  let args = [...arguments];
  let add = function() {
    args.push(...arguments);
    return add;
  };
  add.toString = function() {
    return args.reduce((a, b) => {
      return a + b;
    });
  };
  return add;
}
console.log(f(1)(2)(3)); // 6

当然还没有结束,这里还会有一些特别的解法,其实在使用对象的时候,如果对象是一个数组的话,那么上面的逻辑还是会成立,但此时的toString()会变成隐式调用join()方法,换句话说,对象中如果是数组,当你不重写其它的toString()方法,其默认实现就是调用数组的join()方法返回值作为toString()的返回值,所以这题又多了一个新的解法,就是在不复写toString()的前提下,复写join()方法,把它变成shift()方法,它能让数组的第一个元素从其中删除,并返回第一个元素的值。

class A extends Array {
  join = this.shift;
}
const a = new A(1, 2, 3);
if (a == 1 && a == 2 && a == 3) {
  console.log("Hi Eno!");
}

我们的探寻之路还没结束,细心的同学会发现我们题目是如何让(a===1&&a===2&&a===3)的值为 true,但是上面都是讨论宽松相等==的情况,在严格相等===的情况下,上面的结果会不同吗?

答案是不一样的,你们可以试试把刚才上面的宽松条件改成严格调试再试一次就知道结果了。

class A extends Array {
  join = this.shift;
}
const a = new A(1, 2, 3);
// == 改成 === 后:
if (a === 1 && a === 2 && a === 3) {
  console.log("Hi Eno!"); // Hi Eno!此时再也没出现过了
}

那么此时的情况又要怎么去解决呢?我们可以考虑一下使用Object.defineProperty来解决,这个因为Vue而被众人熟知的方法,也是现在面试中一个老生常谈的知识点了,我们可以使用它来劫持a变量,当我们获取它的值得时候让它自增,那么问题就可以迎刃而解了:

var value = 1;
Object.defineProperty(window, "a", {
  get() {
    return this.value++;
  }
});

if (a === 1 && a === 2 && a === 3) {
  console.log("Hi Eno!");
}

上面我们就是劫持全局window上面的a,当a每一次做判断的时候都会触发get属性获取值,并且每一次获取值都会触发一次函数实行一次自增,判断三次就自增三次,所以最后会让公式成立。

当然这里还有其他方法,这里再举例一个,比如使用隐藏字符去做障眼法瞒过面试官的:

var aᅠ = 1;
var a = 2;
var ᅠa = 3;
if (aᅠ == 1 && a == 2 && ᅠa == 3) {
  console.log("Hi Eno!");
}

上面这种解法的迷惑性很强,如果不细心会以为是三个一样的a,其实本质上是定义三个不一样的a值,a的前后都有隐藏的字符,所以调试的时候,请复制粘贴上面的代码调试,自己在Chrome手打的话可以用特殊手段让 a 后面放一个或者两个红点实现,并在回车的时候,调试工具会把这些痕迹给隐藏,从而瞒天过海,秀到一时半刻还没反应过来的面试官。

最后,祝愿大家在新的一年找到一份如意的工作,上面的代码在实际情况中基本是不会被运用到的,但是用来探索JS的无限可能是具有启发性的,也建议面试官不要使用这类面试题去难为面试者~

交流

如果文章和笔记能带您一丝帮助或者启发,请不要吝啬你的赞和收藏,文章同步持续更新,可以微信搜索「 前端遨游 」关注公众号方便你往后阅读,往期文章也收录在 https://github.com/Wscats/art...
欢迎您的关注和交流,你的肯定是我前进的最大动力😁

截屏2020-03-15上午10.53.06.png

查看原文

源泉 发布了文章 · 3月3日

React native 项目配置 iOS 开发环境遇到的问题

按照官方文档执行配置环境之后,执行 react-native run-ios 命令行会提示让运行:pod install 。 但是,运行改命令后,总是卡在下载https://github.com/CocoaPods/Specs.git
解决办法:
在项目的 ios 目录下,找到 podfile 文件,然后在 target * 上一行添加如下代码:

source 'https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git'

然后再按照正常的流程来配置即可。
墙,和网络问题可太坑。

如果下载被终止,可能是请求缓冲大小不够,可以如下设置:

git config --global http.postBuffer 924288000
查看原文

赞 1 收藏 1 评论 0

源泉 发布了文章 · 2月22日

golang 的 gin 框架开发热重启探索

需求来源

作为一个新萌的假后端,开发接口时候经常需要修改调试重启素质三连。但是频繁修改和频繁的重启会导致非常麻烦。作为一个老前端,自然是厌恶手动重启这种劳心费力的操作的。于是就像找一个在开发环境快速热重启的方案。

工具

经过一番探索,找到以下开源项目:

https://github.com/cosmtrek/air

项目中使用

按照该项目文档说法直接一波操作。
安装

go get -u github.com/cosmtrek/air

创建配置文件
在项目根目录创建一个名为 .air.conf 的配置文件。创建完毕之后,在文件中写入你应用运行的命令如:

go build main.go

运行项目
运行项目只需要在项目根目录执行如下命令:

air -c .air.conf

如果你的配置文件是 .air.conf 那么你只需要运行 air 就可以了。

总结

项目运行后,我们再次编辑项目中的文件,项目的服务会自动重启了。话说,如果是接口测试,如果能够在有个回调,在项目重启后,自动帮我们在浏览器刷新一下测试请求那就更完美了。
就先这么脑洞着。等有时间来折腾一波试试。

查看原文

赞 0 收藏 0 评论 0

源泉 发布了文章 · 2019-09-25

vue 中使用百度脑图 kityminder-core 二次开发

最近项目中要用到 脑图工具。
翻遍个大网站,找到 kityminder-core。

然后发现这货

  • 年代久远,用的技术比较古董
  • 虽然出自大厂,但是文档资料着实让人蛋疼

经过数小时的采坑,已经上岸,记录使用方法如下:

先安装模块:

npm install kity kityminder-core -S

然后引用模块

import kity from 'kity'
import kityminder from 'kityminder-core'

然后创建一个容器标签

<div id="minder-container"></div>

然后创建脑图示例代码如下:

this.km = new window.kityminder.Minder({
  renderTo: '#minder-container'
});
this.km.importJson({
  "root": {
    "data": {
      "text": "test111"
    },
    "children": [
      { "data": { "text": "新闻\nsrc/module/node.j"}},
      { "data": { "text": "网页"} },
      { "data": { "text": "贴吧"} },
      { "data": { "text": "知道"} },
      { "data": { "text": "音乐" } },
      { "data": { "text": "图片"} },
      { "data": { "text": "视频"} },
      { "data": { "text": "地图" } },
      { "data": { "text": "百科","expandState":"collapse"}}
    ]
  },
  "template":"default"
});

使用 new 创建一个实例,挂载在this对象上即可。这里要注意的是,初始化的时候,直接使用 kityminder.Minder 可能会报错。所以需要手动加上 window.kityminder.Minder

这个问题有点奇葩啊,你说直接使用 kityminder 是个空对象,使用 window.kityminder 就是正常的。快上岸吧,兄弟们!

查看原文

赞 0 收藏 0 评论 3

源泉 关注了标签 · 2019-07-16

golang

Go语言是谷歌2009发布的第二款开源编程语言。Go语言专门针对多处理器系统应用程序的编程进行了优化,使用Go编译的程序可以媲美C或C++代码的速度,而且更加安全、支持并行进程。
Go语言是谷歌推出的一种全新的编程语言,可以在不损失应用程序性能的情况下降低代码的复杂性。谷歌首席软件工程师罗布派克(Rob Pike)说:我们之所以开发Go,是因为过去10多年间软件开发的难度令人沮丧。Go是谷歌2009发布的第二款编程语言。

七牛云存储CEO许式伟出版《Go语言编程
go语言翻译项目 http://code.google.com/p/gola...
《go编程导读》 http://code.google.com/p/ac-m...
golang的官方文档 http://golang.org/doc/docs.html
golang windows上安装 http://code.google.com/p/gomi...

关注 25945

源泉 发布了文章 · 2019-07-14

mongodb 和 golang 搭伙采坑

最近在边学边录一些视频教程,放在B站。
https://www.bilibili.com/vide...

背景

起初是打算用 golang + mongodb 来做。网上也查了写资料,说 mongodb 的 model 和 golang 的 struct 是很般配的。然后作为前端出生的我,本来使用过 nodejs 和 mongodb ,所以也就想着用 golang + mongodb 这样自己会更熟悉。

问题

前期的准备什么都没有问题,到后边发现:怎么关联查询啊?
然后网上各种关键词搜索,各种看别人代码社区提问什么的。
最后,耐着性子,找到了官方文档:

clipboard.png

https://docs.mongodb.com/manu...

可以看到,golang 的 driver 并不支持 DBRefs,扎心哦。

结论

看样子,强类型的语言还是适合 mysql 这种关系型数据库。
哎,不说了,换 mysql 继续码了~.~

(个人理解,才疏学浅,有误望指导...

查看原文

赞 0 收藏 0 评论 0

源泉 发布了文章 · 2019-06-25

go 包管理 踩坑

安装或者 运行 go build 时候报错:

go: finding github.com/modern-go/concurrent latest
go: finding gopkg.in/check.v1 latest
go: golang.org/x/net@v0.0.0-20190503192946-f4e77d36d62c: unrecognized import path "golang.org/x/net" (https fetch: Get https://golang.org/x/net?go-get=1: dial tcp 216.239.37.1:443: connectex: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.)

说明你需要proxy了(其实用了proxy有时候也没用),或者是用 module 的 replace 来转一下,这个方法有以下缺点:
1.有些包还是转发失败
2.需要一个个的设置很麻烦

找了许久,另外一种办法设置global go proxy 具体方法如下:
1.先清除 cache ,到特定目录删除文件
2.window下 打开 power shell 然后执行如下命令:

$env:GOPROXY = "https://goproxy.io"

不过这个设置只对当年窗口有效!

3.mac 下在~/.bash_profile 文件下(没有就新建)写入:

export GOPROXY=https://goproxy.io

找到一个一劳永逸的 jetbrain 系列的懒人做法:

clipboard.png

好了,终于可以开始码字了,而不是无脑配环境~.~

查看原文

赞 0 收藏 0 评论 0

认证与成就

  • 获得 77 次点赞
  • 获得 4 枚徽章 获得 0 枚金徽章, 获得 0 枚银徽章, 获得 4 枚铜徽章

擅长技能
编辑

开源项目 & 著作
编辑

  • 79px

    嗯,个人项目。分享知识,传递价值。

  • single-div

    限制你的可选项,会让你重新评估手头上已有的工具。一个div超乎你想象。

  • 开发者resume

    嗯,一个resume模板,拿去用吧-.-

注册于 2014-06-25
个人主页被 1.6k 人浏览