估计用过windows和linux双系统切换的人都遇到过这个问题,2个系统之间一切换时间就不对劲了,虽然说可以手动同步,但是每次这么搞有点费劲,不如一劳永逸,彻底解决这个问题!
根本原因:linux系统与win系统对于时间的管理方式不同。
linux认为硬件时间为GMT+0时间,是世界标准时间,而中国上海是东八区时间,显示时间为GMT+8。
windows系统认为硬件时间就是本地时间,而这个时间已经被linux设置为GMT+0时间,因此win系统下时间比正常时间慢8个小时。
估计用过windows和linux双系统切换的人都遇到过这个问题,2个系统之间一切换时间就不对劲了,虽然说可以手动同步,但是每次这么搞有点费劲,不如一劳永逸,彻底解决这个问题!
根本原因:linux系统与win系统对于时间的管理方式不同。
linux认为硬件时间为GMT+0时间,是世界标准时间,而中国上海是东八区时间,显示时间为GMT+8。
windows系统认为硬件时间就是本地时间,而这个时间已经被linux设置为GMT+0时间,因此win系统下时间比正常时间慢8个小时。
之前写过几篇关于在阿里外包的文章,转眼间,我在阿里已经干了3年多的外包了,虽然说疫情已经结束了,但随之而来的经济萧条导致就业更加困难,特别是IT行业,这几年铁拳监管之手各种敲打,大公司的日子都不好过,中小公司也难,创业公司基本上没了。
综合考虑各种因素,我目前还没换工作,主要考虑我的现状(非科班、非重点学历、非大厂北京、年龄大)即使出去也缺乏竞争力,那些大公司也进不去,小公司不稳定,很难更好的工作,就算找到工资可能还不如我们目前的水平,另外我也不打算在北京再干多久了,可能要回到老乡的省会找个工作,所以目前也是走一步看一步。
很多人对我的工资比较感兴趣,这里只能简单透露一下,我刚开始进阿里外包的时候就是以比较高的级别进去的,这几年也稍微涨了那么一丁点,目前加上公积金的钱,年包大约不到30个W,虽然说和阿里正式工的水平没法比,据我了解阿里p6的年包大概也在50个W,但在外包里面算是中等偏上。
其实阿里也一直在裁员,去年就裁了一批外包,今年发完年终奖又裁了一批正式员工,虽然说阿里实行某位淘汰制,那些拿了低绩效的(3.25)大概是要被优化的,但是这次不一样,和绩效关系不大,光速走人,我所在部门就走了几个,按照比例看确实和网传差不多。
裁了再招也罢,但现在阿里裁了人之后几乎不招人了,这才是最大的问题,除了大环境原因之外,阿里本身问题也很多,在国内的竞争中开始掉队了,公司内部的压力也大。
从事Web开发的童鞋对RESTful API很多人都不陌生,不同项目的接口形式千奇百怪,有些声称使用RESTful,但是实际上并不完全符合规范,不禁让我思考,到底要不要使用RESTful API的风格?
举个例子,相信大家见过不少下面风格的API:
用途 | 请求方法 | 命名 |
---|---|---|
获取用户列表 | GET | /getUserList |
获取单个用户信息 | GET | /getUserInfo?id=1 |
新增用户 | POST | /createUser |
更新用户 | POST | /updateUser |
删除用户 | POST | /deleteUser |
这是一个最简单的CURD接口,说实话,我并不反对这种形式的API,虽然说看上去俗了点,但是至少见名知意,除了获取数据使用GET,其它一律POST,简单粗暴,没什么大问题。
在国内搞计算机网络开发基本上必备梯子,不仅仅是为了使用Google,其实很多海外网站,不是打开慢就是偶尔彻底打不开,还有类似最近大火的ChatGPT,有梯子还不一定能用上。
为了解决这个问题,必须需要一个VPN,也就是俗称的梯子,梯子哪里来呢?
作为一个资深互联网爱好者,早在Google退出中国之前就注册了账号,一直延用至今,这些年也没少折腾,从shadowsocks到v2ray,各式各样的梯子技术都尝试过,也算是稍微有点经验,今天就来分享一个永久免费的方案,一分钱不花享受高速梯子服务。
说到代码安全,虽然很多时候大家都不当回事,只要实现业务功能就行了,但是一旦出现安全问题都不是小事,突然想起来之前项目有很多类似的写法:
1 | sql := "select * from xxx where 1=1" |
为什么要这么写?主要是为了实现一些复杂的列表查询,默认情况下查询所有,但是有很多可选的参数,所以图省事选择了拼Sql,虽然功能上没有什么问题。
但是经过我的测试,上面这种写法存在SQL注入风险,非常危险!!!
作为一名在北京工作了5年多,几乎1年1换房子的人也算是经验丰富了,特此总结一下北京租房的几个途径和一些坑。
如果简单的划分,可以认为租房有2种主要方式,一种是和直接和房东签合同,另一种不是直接和房东签,俗称二房东。
下面,我就主要从租房途径这个层面来讲一讲,以北京为例和个人经历为主:
中介的水很深,中介靠不靠谱也得看情况,好在这几年房屋中介相关的管理监管加强了,幺蛾子没那么多了,但是也不能掉以轻心。
在北京,大家经常都在街上看见他们的店铺的中介就那几家,就不用我说了,但是那些不知名的小中介、区域性中介就太多了,据统计北京大概有上百家房屋中介,有人说存在即合理,在我看来,是存在既有利润。
这些大中介的中介费大多是1个月,最多给你打9折,也就是0.9个月,很多小中介比较便宜,可以谈到0.5个月,从成本的角度来说,这些小中介在广告投入上比较少,费用低一些是可以理解的,但不是说大中介贵就一定不会翻车,小中介便宜一定有问题。
Git的rebase命令是一个非常强大的命令,关于这个命令的介绍文章网上很多,但是大多理论性比较强,所以我这篇文章结合几个非常典型的应用场景来谈一下rebase命令的使用。
说实话,rebase这个操作极少用到,大部分时候老老实实merge就行了。说到rebase这个单词,有些文章翻译成“变基”,实在有些生硬,但是从字面意思上看base有着基础的含义,比如说我们每次修改代码的时候是基于上一次的基础,这是一个线性的过程,而rebase则是打破这个线性过程,改变变更的基础,达到一些特殊的目的。
作为一名在阿里干了2年多外包的人应该具有一定的发言权,之前有写过几篇关于阿里外包的文章,感兴趣的童鞋可以往前翻一下。如今差不多2年过去了,突然想起来继续更新一下近况,首先告诉大家的是,我还在外包,没错,我还在干外包。
不过这篇文章我想谈一个话题,那就是“阿里外包是否能转正?” 因为转正这个事情发生在我身上过,但是却又没有成功。
不过在此之前,我先简单说一下这2年发生的一些事情,算是一些铺垫
在这2年多内,我换过多个阿里主管,最早那个阿里主管跑路了,然后我就换了另一位主管了,但是没多久这个主管又转岗了,于是我又转移到另外一个主管下面。
在阿里这2年内,我认识的正式工里面离职的人1只手数不下来,后来得知在阿里一般3年多可以升到p7,再往上面升p8就非常困难了,而这个时候基本上股票该拿的也拿完了,所以想涨工资大多只能通过跳槽。
最近愈发觉得我用了差不多2年的手机红米k20 Pro打开应用速度反应很慢,偶尔还会有卡顿,这款手机搭载了高通骁龙855plus,8核CPU,最高主频2.96GHz,即使放在今天性能也不是很差,我平时很少拿来玩游戏,只是日常使用。
虽说手机用久了都会变卡,毕竟电子元器件存在性能衰减,不过问题其实也不是这么简单。MIUI系统很早就有省电模式、均衡模式、性能模式,熟悉Linux系统的人都知道这和Linux的CPU调度策略非常类似,当然这是废话,因为安卓内核就是Linux。。。
手机系统为了平衡功耗以及温度,会有很多种CPU调度策略,MIUI在平时使用的时候会根据运行软件的不同去执行不同的调度策略,比如一些日常软件的话主频会限制到2GHz,但打游戏的时候往往火力全开,但是火力全开手机温度就会上升,达到一定程度就会触发温控策略导致CPU降频,从而引起卡顿。
我这个机型的系统版本还取消了性能模式,默认以均衡模式运行,再加上小米保守的温控策略,根本没法发挥全部实力,作为一个技术宅已经忍了很久了,既然没钱换新手机那就动手解除封印,释放全部潜能再战1年!所以接下来,我会把这台手机root、之后再安装Scene4解锁来CPU限制,火力全开,最后再删除温控策略,尽可能的释放手机性能,提高流畅度。
理论上,手机CPU和GPU也能超频,不过这个玩法就太高端了,而且恐怕散热真的撑不住。。。
本人在折腾过程中也查看了不少教程,但是都比较零散细碎,所以这里总结了一下,以下教程适用于MIUI 12,虽然我的机型可能和大家不一样,但是大同小异,仅供参考。
众所周知,Ubuntu的发行版默认的Linux内核版本都不是最新的,但是通常比较稳定,是和发行版契合的,一般情况下我不建议升级,除非说你有明确的需求。
比如说 Ubuntu16.04 目前的内核版本还是4.15,确实比较老,像我个人比较喜欢unity桌面,所以也一直没有去升级到20.04的发行版(新发行版使用5.0以上版本),但是我们可以单独升级内核。
本人升级内核主要是折腾、尝鲜,个人感觉升级版本之后感觉确实流畅了一点,其它没有什么变化。
先说结论:目前 Ubuntu16.04桌面版本,可以完美支持的Linux内核版本是5.4,更新一点的版本在安装的时候会有一些headers依赖错误,虽然不致命,但是总感觉有问题,这些底层依赖库自己想要去升级版本的话是非常麻烦的,必须从源码编译,而且可能会有导致系统崩溃的风险。
说到并发和并行,很多人容易混淆,虽然在大部分时候他们俩的意思都差不多,但实际上还是有很大区别。如果非得说明白,我觉得先从并行和串行这个2个单词说起更加容易理解,因为这2个单词很多人都熟悉,在编程里面所谓串行就是一个一个去执行,而并行则是指同时去执行。
举个例子:如果你需要调5个接口获取数据,每个接口耗时1s,那么串行总共需要5s来执行,但是并行顾名思义同时去执行,则可以同时去调用,那么总共只需要1s时间。所以相对于串行来说,并行可以节省很大时间,提高效率。
但是并发的概念和并行有所不同,并发更强调的是“同时”发生,它可以是并行的,也可以是“假”并行。
举个例子:早期CPU只有单核,单核意味着CPU同时一时间只能执行一段代码,那电脑是怎么做到在上网的同时还可以听歌呢?这是因为操作系统是支持并发的,它会把CPU执行时间分为很多小的时间片分给不同的应用程序,然后交替执行代码,所以看上去好像是在同时进行。如今,电脑CPU都是多核的,操作系统可以把一个或者多个核单独分配给一个应用去使用,对于这种情况我们可以认为他是并行。
从理论上说并行只是并发的一种实现方式,并发是更高维度的概念,说白了,并发只要你能实现“同时”执行的效果,至于物理层面是否是同时并不重要。所以我们网上看到大部分文章都会说并发编程,很少有人会说并行编程。
其实在如今,很多语言依然不支持并发编程,比如PHP;还有很多语言通过多进程、多线程的方式来实现,比如C++、Java;而Go则是通过协程的方式实现了并发编程。
说起面向对象(OOP),很多人都听说过封装、继承、多态这些特性,从本质上说面向对象只是一种软件编程思想。但由此衍生出面向对象语言这个概念,其中Java是最典型的代表,是一种完全面向对象的语言,表现在语言层面就有类和对象的设计。
严格来说Go不是一门完全面向对象的语言,但是在某种层面上实现了面向对象的部分特性,毕竟任何软件工程的主要目标都是为了实现重用性、灵活性和扩展性,Go也不例外。
举个例子:假设你需要把一个大象放到冰箱里面,需要几步?
第一步:打开冰箱
第二步:把大象放进冰箱
第三步:关上冰箱
这3个步骤用面向过程的方式去实现可能就是3个函数,比如openFridge、placeElephant、closeFridge,我们只需要依次调用即可。
但是从面向对象的思维来看,冰箱作为一个对象,它应该有2个函数:open、close,而大象作为一个对象应该有一个函数:walk,我们只需要组合这2个对象的函数就完成这些步骤。
简单说一下Linux设置开机自启的几种方式,以前用Windows很多软件巴不得开机启动,导致开机巨慢,所以每次安装完系统都要各自优化,禁用启动项。
但是Linux下大部分软件都比较守规矩,没有设置自启,对于一些后台进程类应用,还需要自己手动添加开机自启,下面我就针对Ubuntu桌面演示一下。
举个例子,Ubuntu桌面下的鼠标移动速度太快,很灵敏,即使在鼠标设置里面把移动速度拉到最低还是很快,这时候只能祭出神器: xinput。
假设最终解决方式是需要使用命令行设置属性,如下:
1 | xinput set-prop 10 "Device Accel Velocity Scaling" 1.2 |
不过这个命令的效果不是永久的,每次电脑重启就失效了。如果你不嫌麻烦你就每次开机的时候执行一下,但是这显的很蠢。
在Ubuntu下实现这种开机自启、自动执行的效果有很多种方式,下面咱就一一介绍。
这篇文章是承接上面那篇文章:ubuntu unity桌面设置攻略 的后续,主要内容是讲一下我个人在使用Ubuntu桌面系统的时候常用的软件和设置。
这里记录一下也是方便以后自己查阅,或者他人参考之用,仅此而已。
不过在开始看文章之前,我先说一个大的前提,很多人都知道Linux下安装软件,大部分时候只需要使用命令行即可,比如:“sudo apt install git”。
使用命令行没问题,但是由于Ubuntu16.04的版本比较老,其源里面的很多软件版本已经比较旧了,我比较喜欢最新的版本,很多老牌的知名开源软件都有官网,上面会有最新的下载地址,有些还会提供一个PPA源,只要添加到系统里面,以后还可以收到更新。
所以我一般遵循以下步骤:
难道只有我一个人觉得Ubuntu的unity桌面非常好用吗?
最近把台式机上面的Ubuntu 16.04格式化了,装了黑苹果用了一周,不得不说,MacOS确实很精美,软件生态比Linux丰富很多,比Windows简单安全很多,但是我最终还是不想用了,原因很多,究其原因,我觉得是因为Mac是一个为触摸操作优化的系统,没有触摸板就像是断条腿。
所以,我决定重回Linux,继续用Ubuntu,期间尝试了最新的Ubuntu 20.04版本,发现Gnome桌面模仿Mac系统的痕迹太明显了,扁平化的UI设计真的欣赏不来,最要命的是我总感觉一卡一卡,没有unity桌面流畅,真的不是我的错觉,我之前也尝试过18.04版本,那会感觉也是很卡。
最后想了想,还是回到unity桌面吧,不再折腾了,奈何unity已经被抛弃,只能死守16.04这个版本,虽然看起来有点老了,但是用起来完全没有任何问题。装个系统对于我来说是非常轻松的事情,但最麻烦的是我个人的一些特殊设定、常用软件的安装配置比较耗时,所以这篇文章的主要目的就在于记录整个过程,结合我之前写的一些文章,作为一个记录,也可以供需要的参考一下,如果你喜欢unity桌面的话。
以下文章的内容仅针对Ubuntu的unity桌面,准确的说是16.04版本,因为之后的版本都是Gnome桌面,基本上不适用了,Only For Ubuntu16.04。
最近项目里面有需要实现插件机制,所谓插件就是指可以在不用发布新的版本情况下实现对程序功能的扩展,这种插件机制应用特别广泛,常见的比如咱们浏览器的扩展、Nginx扩展、PHP扩展等等。
在Go语言里面,官方自带了一个插件扩展机制,这个我之前有文章介绍过,详情可以点击 Go Plugin实现插件化编程
但是Go官方自带这个插件机制很不成熟,更像是一个半成品,存在很多问题,比如插件无法卸载、各自版本依赖必须完全一致,其中对版本依赖必须一致这个要求非常致命,因为在一个大型的项目里面,很难限制插件开发者使用的依赖库版本,很难做到统一。
今天咱们就介绍一个基于RPC实现的插件机制,而且这种方式是经过大规模实践验证的,可用性非常高,值得尝试一下。
其实到今天,黑苹果的技术已经非常成熟了,甚至形成了一条产业链,有专门做黑苹果安装的某宝店和一些电脑店。其实之前我也装过几次黑苹果,就是没坚持用下去就格了,最近又装了个黑苹果,感觉挺好用的,今天咱们就总结一下目前最简单的方式。
黑苹果并不是黑色的苹果,说到黑有些人觉得是不是有问题,比如黑客通常都被认为是干坏事的。其实黑苹果这个说法还是真和黑客有关系,因为黑客的英文叫Hacker,而黑苹果英文叫Hackintosh,Mac的全称是Macintosh。
苹果的OS从来都是只自用,搭配Mac电脑出售,不对外单独出售,如果你想用Mac系统就得买苹果电脑,但是呢?苹果的电脑卖又那么贵,确实贵。。。所以一群黑客破解了MacOS,可以装在普通电脑上面,所以叫黑苹果,简单说就是盗版了的MacOS,与之相对的白苹果就是指正经安装在Mac电脑上。
在使用Golang做业务的时候经常遇到各个类型之间的转换,今天就稍微总结一下常见类型之间的转换方式,主要是int、string、float64、[]byte这几个类型。
这个用的还是比较多的,特别是在Web开发的时候,前端传值一般都是string居多,转换主要使用一个库strconv
来操作:
1 | // StringToInt string => int |
作为一名以Web开发为主的程序员,上一次写PHP已经是2年前的时候了,不出意外今后应该都不会再去写PHP代码了,原因很简单:Go太好用了。
这个话题看上去像是语言之争,听起来没有意义,因为大家都说真正牛逼的人什么语言都能写,语言只是工具,最重要的是编程思想。话说的没错,但是从实际开发来说,不同语言的生态环境还是有点区别的,比如很多库包装和调用的形式不一样,来回切换成本很高。
举个例子,常用的http库,如果你写PHP你立马会想到Guzzle这个强大的库,如果是Go呢,标准库自带的功能就已经足够了,如果是Python,应该是用requests这个库,但是Java呢,我还真不清楚。。。
从实际工作的角度来说,一个公司的技术栈往往都是以某些语言为主,比如字节都是Go为主、百度偏向PHP、阿里京东基本上都是Java。原因有很多,但是大多都是规范、维护、内部学习等,毕竟你招聘的时候岗位上面都会说明主要语言。
说到插件这个东西,很多人都不陌生,一般来说,插件化有几个好处,一个是增加程序扩展性,丰富功能。另外,还可以实现热更新,有些大型应用,动辄几个GB的安装程序,如果一个小小的更新就需要重新下载整个程序,这时候我们就可以把经常更新的模块插件化,这样更新的时候只需要下载一个小更新文件。比如说平时咱们Chrome浏览器都会装一些插件,可以扩展浏览器实现更多的功能,还能灵活的安装卸载。
Golang在1.8版本之后提供了一个 Plugin 的机制,可以动态的加载so文件,实现插件化,虽然并不是非常成熟,但是在特定的情况下还是非常好用。
Currently plugins are only supported on Linux, FreeBSD, and macOS.
本人工作多年,干倒不少公司,待过十几个人的团队,也进过上百人的团队,也算是项目开发经验丰富。今天我就来说说互联网公司项目开发的常见流程,主要来自于本人经验总结,结合了我这么多年来不同公司的实践所得。对于平时个人开发或者参与多人项目开发,大家可以参考一下,不一定适合所有公司,采取其中部分流程也是可行。
个人觉得从整体来说,项目开发流程大体分为3个大的部分,第一个部分就是需求,这个需求来源可能是BOSS、可能是用户反馈、可能是产品人员拍脑袋。第二部分是编程开发,程序员干活的地方。第三部分是测试验收,主要是测试人员干活的地方。
之前有写好几篇文章是关于阿里外包的,比如《谈一谈阿里外包工作》 等等,感兴趣的可以翻一下我之前写的。
不知不觉,在阿里干外包已经干了1年半了,不长也不短,渐渐的感觉自己已经非常适应这样的生活,不太愿意去尝试新的工作,一直也没静下心来思考这些问题,今天刚好决定静下心来写点东西,分享一下这1年多的经历。
Linux下的显示画面撕裂(Tearing)问题由来已久,如果你观察比较仔细,肯定会发现使用Ubuntu播放视频的时候画面明显有撕裂的现象,这倒不是什么大问题,但是却一直以来存在。
因为我是使用Ubuntu当主力机,每天不仅拿来编程,也拿来娱乐,看视频电影,浏览网页,对这个现象比较注意,其实这种问题有时候也不单单是Linux存在的问题,很多玩游戏的朋友应该知道很多游戏都有一个垂直同步的选项,这也是为了解决画面撕裂问题。
这种画面撕裂问题本质上是显卡输出和显示器刷新频率不同步导致的问题,这里记录一下我的解决方式,一个是自己备用,另外分享给需要的朋友。
买卖股票的最佳时机II,简单难度,leetcode地址:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii
给定一个数组 prices ,它的第i个元素 prices[i] 表示一支给定股票第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
示例 1:
1 | 输入: prices = [7,1,5,3,6,4] |
买卖股票的最佳时机,简单难度,leetcode地址:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock
给定一个数组 prices ,它的第i个元素 prices[i] 表示一支给定股票第 i 天的价格。
你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。
返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。
示例 1:
1 | 输入:[7,1,5,3,6,4] |
整数反转,简单难度,leetcode地址:https://leetcode-cn.com/problems/reverse-integer
给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围,就返回 0。
示例 1:
1 | 输入:x = 123 |
Z字形变换,中等难度,leetcode地址:https://leetcode-cn.com/problems/zigzag-conversion
将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 “PAYPALISHIRING” 行数为 3 时,排列如下:
1 | P A H N |
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:”PAHNAPLSIIGYIR”。
示例 1:
1 | 输入:s = "PAYPALISHIRING", numRows = 3 |
现在很多人都使用高分屏,比如2k、4k的显示器,在Ubuntu上面一般都需要设置缩放比率,之前我写过一篇文章介绍过 Ubuntu 4K显示器缩放设置
但是我最近发现存在一个问题,当你电脑休眠之后再恢复,这个屏幕缩放比例就还原了,变成1了,比如我的4k显示器一般设置是1.88刚好合适,瞬间变回1那个界面UI真的酸爽。。。
多次实验发现,这个不是休眠的问题,实际上只要你用显示器上面的按钮关闭显示器或者拔掉显示器电源再插上,这个缩放比例都会被重置。
关于这个问题的解决方案我找了很久,用中文搜索一直没找到,最后用英文搜索在ask ubuntu
上面发现有人提过这个问题:17.04 Display scaling reverting to 1 after resume from suspend?
最近在学习开源项目Grafana
的代码,发现作者实现了一个事件总线的机制,在项目里面大量应用,效果也非常好,代码也比较简单,介绍给大家看看。
源码文件地址:https://github.com/grafana/grafana/blob/main/pkg/bus/bus.go
最长回文子串,中等难度,leetcode地址:https://leetcode-cn.com/problems/longest-palindromic-substring
给你一个字符串 s,找到 s 中最长的回文子串。
示例 1:
1 | 输入:s = "babad" |
无重复字符的最长子串,中等难度,leetcode地址:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters
给定一个字符串,请你找出其中不含有重复字符的最长子串
的长度。
示例 1:
1 | 输入: s = "abcabcbb" |
两数相加,中等难度,leetcode地址:https://leetcode-cn.com/problems/add-two-numbers
给你两个非空的链表
,表示两个非负的整数。它们每位数字都是按照逆序
的方式存储的,并且每个节点只能存储一位数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例 1:
1 | 输入:l1 = [2,4,3], l2 = [5,6,4] |
两数之和,简单难度,leetcode地址:https://leetcode-cn.com/problems/two-sum
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出和为目标值 target 的那两个整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。 你可以按任意顺序返回答案。
示例 1:
1 | 输入:nums = [2,7,11,15], target = 9 |
之前写过一篇 文章 简单介绍过Go里面的依赖注入,其中提到了Facebook开源的一个依赖注入项目,地址:https://github.com/facebookgo/inject 刚好最近看一个开源项目用到这个项目,于是带着一些疑问仔细研究了一下。
这可能不是一个普遍的问题,但是我遇到很多次,不知道经常使用Windows、Linux双系统的人有没有感觉到,那就是同样一个鼠标,DPI一样的情况下,在Linux上面比较“飘”,我主要是用Ubuntu,这个问题从14.04到18.04版本一直存在,鼠标手感比Windows差太多,也不是鼠标的问题,我期间换过好几个鼠标都一样。
具体的说,有2个方面,一个是鼠标移动加速度,通常情况下Linux下面鼠标移动非常快,就是感觉不准;另一个则是滚轮的滚动速度,在浏览网页的情况下翻页滚动非常慢。
说实话,Linux系统在这方面调教还是差了点,本文说说如何自己动手解决这些小问题,可以留作备用,以备不时之需。
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,主要是便于快速开发,解决一些通用性的问题。