1.问题
Google Earth有多神,大家都知道,户外必备,独一无二的高清无码卫星地图深得人心。
Google Earth既有手机版也有网页版,还有Windows、Linux的桌面版本,官网都有下载。其中手机版和网页版都得FQ,桌面版一直可以直接打开(本人一直用的Linux版本),直到最近,具体哪天我忘记了,大概就在2020年12月,突然就打不开了,一直卡在主页面,我还以为自己电脑问题,重置修复+重新安装还是不行,直到看到一个新闻才知道也遭黑手,至此所有版本全军覆灭。
Jetbrains家的IDE用过的都知道好,和大部分代码编辑器不一样的是它针对不同语言都有一个单独的定制版本,比如Java开发用idea、PHP开发用的PhpStorm、前端常用的WebStorm、Go开发用的GoLand等等,个人感觉这是我用过的最好的IDE,自带功能强大,还可以安装各种插件扩展功能。
不好的地方就是比较贵,除了社区版之外,很多都是收费的,而且价格不菲,最便宜的是单卖一个是199刀,全家桶打包卖649刀,换算人民币好几千了,说实话,真不便宜,而且还是按年收取,可能有人说程序员工资高,个个年薪30万+,几千块钱算啥。。。
这个就看个人了,如果条件允许,建议还是支持正版。其实有不少好点的公司都会集中采购正版IDE发放给员工使用,但是也有公司为了避免被起诉禁止员工使用破解盗版。。。
废话少说,本文主题是如何免费使用JetBrains家的IDE,这个免费的途径很多,不止一个,待我挨个道来。
相信很多人在开发中过程中都遇到过这个问题: xxx, too many open files
,意思是打开的文件太多,默认情况下,Linux的文件最大描述符个数是1024,这一点可以在终端里面通过 ulimit -n
命令查询。在Linux的设计哲学里面,一切既文件,当你在操作文件、访问网络的时候都会占用文件描述符,文件描述符用尽之后什么操作都做不了,这也就是为什么咱们在编程的时候打开文件之后一定要关闭文件、网络连接用完之后也要及时关闭,可不仅仅是防止内存泄露。
说到随机数不得不提一下真随机和伪随机,一般来说,真随机是指通过物理现象产生的,比如掷骰子、双色球摇奖(前提是机器没问题)、同位素衰变等等,其特征是不可预测、不可重现。而伪随机数一般是通过软件算法产生,看上去是随机的,但是无论是什么算法函数,都会有输入和输出,如果你能得到其输入,自然也可以预测其输出。
实际应用中,伪随机在计算机软件中十分常见,大部分编程语言的函数库里面都有类似 random() 这样的内置函数,可以快速的产生随机数。而真随机数主要应用于安全要求特别高的加密应用中,一般都会有专门的设备用于产生随机数,而本篇文章是给大家介绍一下Golang里面如何生成随机数。
在很多语言里面,函数传参分为值传递和引用传递,在说明这2者区别之前咱先回顾一下函数的一些概念,函数参数有形参和实参之分,所谓形参就是形式参数,它是指定义函数时候的声明的参数,比如在Golang里面 func do(a string, b int),a和b就是形参。而实参则是你在调用这个函数时候所传递的参数,比如在下面代码里面,pa和pb就是实参。
1 | func main() { |
其中,值传递指的是在函数调用的时候,内存会复制一份实参的值给形参,换句话说,形参和实参互不影响!而引用传递则是则形参和实参指向同一块内存区域,换句话,你修改形参也会影响实参的值,修改实参也会影响形参的值!
众所周知,1024在程序员里面有一种特殊的含义,以至于现在每年10月24号都变成了程序员节,这是为什么呢?
稍微了解计算机的人可能知道那是因为在计算机系统里面,1024是不同数据计量单位之间转换的进制,但是作为程序员的你应该知道这件事好像并没有那么简单。
如果你使用过Mac OS,也使用过Windows,你会发现同样一块500G大小的硬盘,在Mac系统就是500G,但是在Windows里面却是465G…这又是为什么呢?
还有,为什么你家里的100M的宽带下载速度最大只有12M左右呢?
说到反射机制,很多语言都有,通常来说,反射可以在运行中获取数据对象信息,它提供了一种在运行过程中动态修改代码自身的能力,也被认为是元编程的一种实现方式。
通过反射我们可以实现一些正常情况下无法实现的功能,甚至简化代码,提高工作效率。虽然反射并不是必须的,但是用的好确实可以事半功倍,下面咱们就看看Go里面反射的一些应用。
在实际编程开发中,无论在任何语言里面,除了数组之外,最常用的数据结构莫非map,map是一种数据结构,在很多语言里面都内置了map类型,map一般被翻译成映射或者地图。从数据结构定义上,map是一组键-值对的集合,例如:
1 | 张三: 18 |
map强调的是一一对应,在具体实现上,不同语言略有差异,比如弱类型语言里面就不会限制key或value的类型,但是在强类型语言比如Go里面,键值的类型是需要声明限定。
但是需要注意的是,map结构的key是唯一的,但是value可以重复。
说到实现原理,大多数语言里面map都是基于hash结构实现,为了解决hash冲突问题,又引入开放地址法和链表结构,Go也不例外,这一点大家简单了解一下即可,并不影响咱们使用,下面咱就结合Go语言来看看map的常见用法。
之前做项目有一个图片裁剪需求,没想到Golang标准库对图片处理的支持还挺强大的,在此记录一下,以备后用。
在Golang里面图片处理主要依赖一个image库,支持常见的png、jpeg、gif等格式,使用这个库我们可以做生成图片、读取图片、裁剪图片等操作。
这篇文章只介绍某几个常用的操作,详细API和使用的技巧大家可以参考Go官方文档和博客,比如:https://blog.golang.org/image-draw
今天谈一下锁,以及Go里面Sync包里面自带的各种锁,说到锁这个概念,在日常生活中,锁是为了保护一些东西,比如门锁、密码箱锁,可以理解对资源的保护。在编程里面,锁也是为了保护资源,比如说对文件加锁,同一时间只也许一个用户修改,这种锁一般叫作文件锁。
实际开发中,锁又可分为互斥锁(排它锁)、读写锁、共享锁、自旋锁,甚至还有悲观锁、乐观锁这种说法。在Mysql数据库里面锁的应用更多,比如行锁、表锁、间隙锁,有点眼花缭乱。抛开这些概念,在编程领域,锁的本质是为了解决并发情况下对数据资源的访问问题,如果我们不加锁,并发读写一块数据必然会产生问题,如果直接加个互斥锁问题是解决了,但是会严重影响读写性能,所以后面又产生了更复杂的锁机制,在数据安全性和性能之间找到最佳平衡点。
众所周知,Golang非常适合用于开发高性能的API,开源的Web框架也很多,比如国产的Beego,以及在目前最流行的Gin,还有Echo、Iris、Revel等框架。
由于博主之前从事过PHP,相比来说,感觉Go的这些框架都比较轻量,很多时候还需要自己花点功夫再打理一下,比如这些框架都没有处理数据库这块,Beego虽然自带了一个ORM,但是可用性极差,需要我们自己手动去集成一些开源的组件。
就拿我用过比较多的Gin框架( https://github.com/gin-gonic/gin )来说,它属于其中最轻量级的框架,主要功能包括路由、请求参数、中间件、模板等,存在一些缺失的东西,比如:
没有推荐项目结构模块划分,很多人不知道代码咋存放
缺少数据库ORM,虽说Go标准库支持数据库,但是缺少封装,用起来麻烦
缺少配置文件加载功能,任何项目都少不了配置文件
日志处理功能不够强大
所以,我基于Gin加上一些开源的组件,封装了一个不算是框架的框架,这里暂且称其为Gen,主要是便于快速开发,解决一些通用性的问题。
今天来说说限速算法,其实这个倒不是什么神秘的事情,本文主要做一个总结,并且从Golang这么语言的角度做一个实践。
假设作为一个完全不懂算法的人,让你去实现一个限速功能(1秒内最多100次),你可能会想到的最简单方式就是记录一个开始时间,然后开始计数,当计数达到100之后限制调用,等待时间间隔达到1秒的时候重置计数器,然后重新计数,如此往复。
这种算法也是日常生活中应用广泛,比如说坐地铁,在北京,很多地铁站在早晚高峰时期都会限流,方法非常简单,地铁站门口有安检员,每过一段时间放几个人进去,虽然安检员也不会掐着表计时,但是基本上是这个规律。
这种方式被称为计数器算法
,有些文章也称之为固定时间窗口计数法
,因为与之对应的还有一个方法叫作滑动时间窗口计数法
。
之前有写一篇文章叫作《谈一谈阿里外包工作》 ,至今3个月已经过去了,今天抽空再写点东西补充一下,希望对有些人有用。
据我了解,很多在年前没有找工作的同事,基本上都空了3-4个月,因为北京这边大概到了4-5月份招聘才多了起来,而且也很奇怪,这时候找工作好像更简单,很多同事都同时拿到了好几个offer,其中也不乏一些大中型互联网公司。
Golang之所以非常适合用于网络编程的原因之一就是其自带网络库可以非常简单快速的建立一个基于http或者tcp的服务应用,以http服务为例,只需几行代码:
1 | package main |
上面这几行代码就启动了一个http服务,运行在8888端口,虽然说非常简陋,也不区分GET或者POST,但是其性能缺十分高效,主要是得益于其底层使用了协程,对每一个请求都会分配一个协程去处理,并发能力强。
相信很多人对Golang里面的数组都不陌生,但实际上99%的场景我们使用的都是slice,原因很简单,Go里面的数组类似C数组长度是固定的,局限太多,而slice则是一个变长的数组,可以自动扩容,类似JS、PHP等弱类型语言里面的数组。
但实际使用slice的过程中,我们一般会遇到2种写法,下面咱们就说说这2种方式的差异和存在的坑:
1 | var s []string |
做技术的人都知道,有时候为了查询一些信息,必须访问一些国外资源,由于这些资源的服务器位于国外,速度较慢,有时候甚至是根本无法访问(你们懂的),这时候拥有一个VPN或者是代理就非常重要了,这也就是国内大部分人使用代理的主要目的,当然代理还有其它很多好处,比如隐藏自己的IP地址和来源。
首先,咱们常见代理有socks代理和http(s)代理之分,比如socks代理默认端口就是在1080。这2者有啥区别呢?http代理属于应用层代理,类似的还有ftp代理,socks代理与应用层代理不同,socks代理只是简单地传递数据包,而不必关心是何种应用协议(比如FTP、HTTP请求)。所以,socks代理比其他应用层代理要快得多,目前用的最多的就是socks5代理。
这次疫情出人意料的持续时间长,口罩瞬间成为一种刚需和战略物资,虽然很多人可能不太愿意戴口罩,但是在中国如果你不戴口罩是没法出门的,这是一种强制措施。我国人多,对口罩的需求更大,在前期口罩基本上买不到,不仅需要抢,而且需要拖关系,甚至由于口罩闹出很多丑事,比如武汉红十字会。而且很多人喜欢囤积,假如你有找到了货源,你可能不会只买1个,你会买未来2个月的用量,那可能就是几百个。
我2月初回北京的时候只戴了一个布口罩,主要是确实没有医用口罩可用,对于我来说,这种口罩完全是形式大于实际意义,但是你如果不戴口罩是没法出门、坐火车,确实很无赖,对于检查人员来说,他们不关心你戴的是什么口罩,只要把脸遮住,哪怕是自己拿布缝的也没问题。
如果现在你说你要去做一款社交软件APP,我大概率会劝你不做,我可能会从市场、资金、成本等多个方面给你分析一通,然后告诉你成功率非常低,你或许认为我总是从最坏的情况考虑,并没有考虑其中的机遇和意外。也许会有人从其它方面分析一通,然后告诉你大有可为,成功率非常高。如果你仔细一想,你会发现两者都有道理,但是只有你真正做了你才能知道哪个是对的,这就像是薛定谔的猫,你只有打开那个盒子才能知道猫是活的还是死的。
如何在Ubuntu自带的文件夹管理器Nautilus里面隐藏文件或文件夹呢?
先说一下背景,之所以想到这个问题是因为我的电脑是 Win10+Ubuntu 双系统,有一块硬盘是共享的NTFS格式,在Windows下面分区会有2个文件夹,了解Windows的人应该知道,这是垃圾回收站和磁盘卷信息。
默认情况下在Windows里面这2个文件夹是隐藏的,但是当我切换到Ubuntu的时候,Ubuntu就会给显示出来了,这倒也正常,但是看起来很碍事,不爽,既然不爽我就要搞它。
说完Go里面的md5的用法,这篇文章咱说说用的比较多的加密方式在Go里面如何实现。首先,科普一下,一般待加密的内容被叫作明文,加密使用的关键元素被称为秘钥,加密的结果被称为密文,当然其中还有一个非常关键的加密算法。
一般加密算法可分为对称加密和非对称加密这两个分类,这两者区别很明显,对称加密是指我们拿到秘钥和密文可以解密出明文,在加密和解密时使用的是同一个秘钥;而非对称加密算法需要两个密钥来进行加密和解密,这两个密钥是公开密钥(public key,简称公钥)和私有密钥(private key,简称私钥)。
用过PHP的童鞋知道在PHP里面md5很简单,是一个内置函数,可以直接调用:
1 | jwang@jun:~$ php -a |
纠正一个错误的说法,很多人一直把md5叫作加密算法,实际上md5并不是加密,它既不是对称加密,也不是非对称加密,它只是一个摘要函数,一般被用于签名或者校验数据完整性。
虽然现在有文章说不推荐使用md5了,因为碰撞几率比较大,实际上,这个几率非常非常非常低,大只是相对于其它摘要函数来说,纯自然的情况下基本不可能碰撞,虽然可以用工具构造出来,但非常复杂。如果实在不放心,可以用sha1或者sha256,或者两者集合起来用,速度会慢一点,但安全性高一点,总之,md5由于速度快,简单易用,现在用的还是蛮多的。
今天想聊一聊学习这个话题,理想情况下,每个人都应该有适合自己的一套学习方法和节奏,主要因为不同人对知识的理解和吸收速度不一样,举个非常简单的例子,在网上看视频或者电影,有些人觉得2倍速播放刚刚好,而有些人甚至还要降速才能看明白,才能Get到点。即便如此,我觉得有些学习的经验和方法是可以共享的,虽然它不一定适合所有人。
人一生都在学习,学习不一定是在课堂上,特别是在互联网时代,我们可以随时随地打开手机观看各种课程,尤其是在编程行业,更需要不断持续的学习才能保持竞争力。我也是自学入行编程,期间也看过很多网上的视频教程,平时学习的时候也经常看一些博客教程,可以说现在也基本上是靠自学成长,颇有感触。
之前写过几篇文章名字叫《一个野生程序员的北漂之路》,这篇文章应该算是后续吧,聊聊我如何进阿里外包,主要是结合我的经历和我所了解的一些事实谈谈我的感受和看法,仅供其他朋友参考。
看过前面文章的人应该知道我上一家公司因为是P2P行业受到打击,目前已经处于立案阶段,整个公司几百员工都失业了,我也不例外。刚开始我对公司还抱有希望,在家休息等待了2周之后我才明白公司是真的没了,自己找工作吧,当时公司为了不仅欠了我们半月工资,而且连社保也没钱缴纳(财务账户被冻结),甚至都无法给员工办理离职(公章被扣押),没人有操心这几百号员工怎么办,但是社保断了对很多人有很大影响,很多人都在问怎么办,最后公司的HR出来告诉我们可以自己找人代缴,但是由考虑到风险,需要员工签一个离职声明,然后公司才可以把社保做减员处理,于是大家争相签离职声明。
每个人对旅行都有自己想法或出于各种目的,对于我当时来说,我并不完全是在旅行,只是把工作和对自由的追求结合在一起。但在这几年的旅行中,我都是独自一人踏遍大江南北,期间也遇到很多和我一样一个人出来旅行的人,我虽不善于交际,但是也在途中结识不少,大多萍水相逢,随后结伴而行度过一段时光,最后各奔东西,相忘于江湖。。。
那是2015年8月,我在拉萨停留几日,期间逛了下大昭寺、布达拉宫门口
等打卡地点,作为一个非宗教人士,我对拉萨的这些宗教文化并无太多感触,也并不觉得灵魂有什么升华。大街上的商店大部分也都是卖着义乌批发制品,他们的售卖对象其实不是游客,而且来自西藏各地的牧民,但我花了100多买了一双山地运动鞋,扔掉了我脚上穿的特步运动鞋,这双运动鞋我在外穿了几个月,虽然也很便宜但是非常轻便,但是过于轻薄,因为我在策划一场没有安排和计划的318之旅,从拉萨坐火车往回走太远,不如走国道再去云南大理转转。
后记,那双鞋质量很差,差的突破预期。。。
如果你看过很多开源库的源码,你会发现大部分项目都有很多详细的测试代码,一般来说测试覆盖率越高说明这个项目的质量越高,所以好的项目测试是少不了的。很多公司对代码测试覆盖率也有要求,不为别的,只为更好的代码质量。
虽然业界有一直开发模式叫做测试驱动开发(TDD),但是了解的人都知道TDD
对开发要求太高了,它要求你先写测试用例然后再写代码,需要你写代码之前思考很多,需要大量时间,我实际开发中并没有采用过这种模式,估计国内都应该很少。
我们可以粗略的把测试用例简单划分为2种类型,一种是单元测试
,它是针对某个模块、函数、方法的测试,另一种是功能测试(集成测试)
,它是针对整个项目功能是否可用的测试。举个例子,你写个了Web服务接口,单元测试可能是针对这个接口里面调用的一个函数测试,而功能测试就是测试这个接口是否可用,因为一个接口可能调用了多个函数。
Golang里面的测试和其它大部分语言的测试不多,只不过表示形式略有不同,比如Go的单元测试通常情况下是和被测试的代码放在一起的,以xxx_test.go
命名并且测试的函数名必须以Test
开头。
自从跨入IT编程行业一直都在使用Linux桌面系统办公(尝试过挺多发行版,最终选择Ubuntu),平时生活也在用,不知不觉已经4年多了,也安利了身边很多人使用Linux,从最早的疯狂折腾到现在追求稳定,其实也颇有感触,闲来无事聊一聊。
我和很多人一样,最早接触的都是Windows
系统的电脑,我也一度是Windows的爱好者,记得当年还对XP、IE情有独钟,装系统、优化系统这些事情当年也没少做,也没少折腾,基本上到了打开任务管理器,对里面每一个进程的作用以及关闭某个进程会导致什么问题都了解的地步。而当时我对Linux的印象也停留在黑框框上面,觉得很神秘,对技术要求很高,只在很多电影里面看见黑客会用到,毕竟那会我对OS需求只是到用的地步,并没有接触编程开发。
此次疫情爆发,有人说现在农村最安全,因为农村一般都是自建房,分布零散,而城市里面都在小区里面,住在火柴盒一样的格子楼里面,进出同一个楼道,同一个电梯,被感染的几率大很多。
我从小在农村长大,自始至今,依然是个农村人(户口还在农村),大学之后,基本上都在城里面上班工作,但是过年还是在老家。有时候早上还在车水马龙、遍布高楼大厦的城里面,晚上就来到了农村蛙声一片的田野边,一个是现代化的城市,另一个是传统的农村,感触十分之深。
今天我就聊聊我一些关于农村和城市的事和想法,可能比较零散,纯属回忆!
上篇文章说到我二家公司由于经营不善,濒临倒闭,拖欠工资,最终我选择自离找工作。
2018年03月,这次找工作非常顺序,我请假面了大概5个公司拿到2个offer,最后选择了一家我觉得还可以的公司,xx网,工资15k。
xx网实际上是某大型教育公司下面一个部门的网站,专门面向程序员,并不是公司名字,很多学习编程的同学应该看过他们网站的课程。
之前也看过他们网站的课程,觉得很不错,这个部门有100多人,其中技术40多人,在这家公司的上班体验总体还不错,除了每天早上无聊的站会以及每周周会,公司属于业务驱动型,大多做的一些业务开发。
直到2018年底春节放假那天,技术老大拉我进屋,悄悄告诉我,经过公司决定,你今年没有年终奖,我当时一脸懵逼,问他为什么?
上篇文章说到我第一家公司因为融资断裂,发不起工资,解散了。这时候我们开发里面一位大佬,这里我称他为Q哥,他也刚进公司不久,如果按职级分,他应该属于高级开发工程师,平时带我们做项目,也会参与开发,毕竟当时公司开发人员不多。
当时他说他有个朋友给他介绍了一个公司,这公司非常缺人,可以直接带我们过去,不用技术面试,他和老板聊好了,我们过去见一下老板就行了。
虽然2020年已经到来,但是真正象征着新的一年的农历新年才刚刚开始,北漂4年多,IT这条路越走越窄,突然萌生出回家的念头,毕竟年龄也不小,算是90后最早一批奔三的人,还未成家,也谈不上立业。
在此回顾一下这些年在北京这几年的职业生涯,作为一种记录,也算是总结吧!
这些年在北京,工作换了很多个,几乎每年面试一次,微信里面同事倒是加了不少,除了聊的好的几个,大部分再也不联系。住的地方也是一年换一次,住过上下铺、地下室、天通苑、自如、一居室。。。
最近想搭建了一个自己的博客网站,经过调研,最终决定使用Hexo+Github的形式搭建,大概花了3个小时的时间,这里简单记录一下过程,备用。
Github提供了一个免费的GIthub Pages功能,简单说就是可以让你存放静态的资源文件,比如css、js、html、image,同时会给你分配一个免费域名,格式:https://xxx.github.io
所以你只需要注册一个Github账号,然后新建一个repository就行了,一毛线都不用花。
由于Github Pages只能托管静态资源,所以像WordPress这类博客肯定是无法运行的,这时候你有2种选择:
Protobuf(Google Protocol Buffer)是 Google公司内部的混合语言数据标准,目前已经开源,支持多种语言(C++、C#、Go、JS、Java、Python、PHP),它是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化。它很适合做数据存储或 RPC 数据交换格式。可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。
说简单点,Protobuf就是类似JSON、XML这样的数据交换格式,当今互联网JSON是最流行的格式了,XML用的也挺多,最初接触到Protobuf是因为gRPC默认使用它作为数据编码,相比于JSON和XML,它更小,更快!
首先,先阐述一个误区,很多人以为gRPC只能go语言使用,以为这个g代表的就是go,其实并不是,这个g应该理解成Google,这个rpc框架是Google出品,不过Go对这个框架的支持确实非常好,看一下官网的介绍:
gRPC is a modern open source high performance RPC framework that can run in any environment. It can efficiently connect services in and across data centers with pluggable support for load balancing, tracing, health checking and authentication. It is also applicable in last mile of distributed computing to connect devices, mobile applications and browsers to backend services.
详细的介绍可以参考官网(grpc.io),简单说,gRPC是一个开源的高性能rpc框架。
说到rpc,很多搞微服务的都喜欢用,特别是Java领域,rpc全称 Remote Procedure Call,翻译过来叫远程过程调用,这个翻译并不是特别好理解。
闲着无事,随便写写,初学Go,望各位大神轻喷!Go自带的几个复合数据类型,基本数据类型咱就不说了,大部分语言常见的几种复合数据类型大概有数组、字典、对象等,不同语言叫法不一样,用法也有差异,比如说PHP里面数组其实严格来说不算数组。
偶尔发现的一个问题,平时主要使用 Ubuntu 操作系统,有时候安装一些软件会用加一些自定义PATH,往往为了方便都会把配置写到 /etc/environment 里面,这样所有用户包括root都有效:
1 | jwang@jwang:~$ cat /etc/environment |
DI - Dependency Injection,即“依赖注入”,是指组件之间依赖关系由容器在运行期决定,与此同时还有一个叫作IOC的词汇,IOC即控制反转。
理论上讲,这2个概念都是基于OOP编程而产生的思想,在OOP编程里面,我们强调对象之间的依赖关系,比如说对象B依赖对象A的某些功能,我们就说B依赖A。
DI毕竟不是Go语言的专利,它是一种编程思想,在很多语言里面都有体现和实现,相信很多具有编程经验的人也有所了解,下面咱们直接开始讲在Go语言里面怎么使用DI。
开头一张图介绍一下我现在日常生活和开发使用的电脑配置:Ubuntu 16.04 + i7-8700k + 1060 + nvme ssd + 32G RAM + 4k显示器,这个配置倒不算很高端,但是开发用体验很高,系统的流畅程度非常高