这个问题是一个读者面试时遇到的一个问题,准备过面试的人应该都记得,非对称加密与对称加密的区别之一就是非对称加密的速度慢,但是我们做业务开发的时候通常都是直接调用算法,对其原因并没有过多深究,因此如果有面试官问到了这个问题,的确会让人措手不及。正好借着这篇文章来说一说。
对称加密与非对称加密 首先我们先来说一下到底什么是对称加密,什么是非对称加密,这一节主要是用一些例子来介绍一下对称加密和非对称加密是什么,如果你已经了解了,可以跳过本节。
对称加密 高中生小明和小红是一对“地下情侣”,可偏偏他们一个坐在教室前,一个坐在教室后,所以晚自习的时候也只能通过纸条传情。这时一个很尴尬的事情就出现了,由于无法直接将纸条交给对方,因此纸条必须要经过多个人的传递,可总有一两个八卦的人喜欢看纸条里写的什么。为了避免被班主任抓包以及被同学们窥视,他们两约定,用现代汉语词典当作“密码本”,以后传纸条时,纸条上的内容是要写的字在词典里的页码及顺序,这样即使纸条被别人看了,不知道密码本是什么的人也就不会得知纸条里的真正内容了。 在上述的例子中,纸条是承载信息的载体,纸条里的内容是信息,汉语词典是密钥,将文字映射到汉语词典的页码和顺序是加密方式(算法)。 类似于上面这种,在加密和解密时使用相同的密钥,或是使用两个可以简单地相互推算的密钥的加密方式就是对称密钥加密(Symmetric-key algorithm),简称对称加密。常见的对称加密算法有:AES、DES、3DES 所以你可以将对称加密简单理解为:一方通过密钥将信息加密后,把密文传给另一方,另一方通过这个相同的密钥将密文解密,转换成可以理解的明文。他们之间的关系如下图所示(这里借用一下@寒食君的图):
弊端 这种加密方式虽然简单,但是其弊端也是非常明显的。在上面的例子中,如果传递纸条的人知道了他们这种加密方式,那就同样可以通过查阅汉语词典解析出他们的纸条内容。如下图所示。这样为什么众多抗战片中会出现疯狂抢夺密码本这一情节也就很好理解了。
非对称加密 再举一个生活中非常常见的例子。小区里的小伙伴们经常可以在自家的邮箱里收到信件,比如你的录取通知书,当然更多可能是广告。不过,虽然说所有人都可以往里面扔邮件,但是只有你可以打开这个邮箱查看这个邮件。 上面这个过程就是一个很形象的非对称加密。
非对称加密不同于对称加密,它有一对秘钥,一个称为公钥(publicKey) ,另一个称为私钥(privateKey),并且***只知道公钥是无法推算出私钥**。*就和上面的例子中只知道邮箱位置却并不能打开邮箱是一个道理。常见的非对称加密算法有:RSA、DSA、ECC 另外,这种算法还有一个特别神奇的功能,那就是通过公钥加密的内容,只有私钥才可以解开,而通过私钥加密的内容,只有公钥才可以解开。
公钥/私钥的用法 第一种用法:公钥加密,私钥解密。—用于加解密 第二种用法:私钥签名,公钥验签。—用于签名 其实很容易理解: 既然是加密,那肯定是不希望别人知道我的消息,所以只有我才能解密,所以可得出公钥负责加密,私钥负责解密; 既然是签名,那肯定是不希望有人冒充我发消息,只有我才能发布这个签名,所以可得出私钥负责签名,公钥负责验证。
这里提一点:签名 ≠ 加密,通俗点说加密就是你哪怕看到了不该看到的东西,也理解不了。而签名就是你做了任何事,都抵赖不了。
为什么非对称加密比对称加密慢? 介绍了这两种加密方式后,我们终于可以回到本篇文章的开头了,为什么非对称加密会比对称加密慢? 这是因为对称加密主要的运算是位运算,速度非常快,如果使用硬件计算,速度会更快。以 AES 算法为例,如下图所示,其运算本质上来说就是位移和替换。 但是非对称加密计算一般都比较复杂,比如 RSA,它里面涉及到大数乘法、大数模等等运算。其加解密可以用下面的公式来表示:
我们知道,幂运算的本质是乘法,乘法的基础单位是加法,也就是我们最常见的整数加。学过数字逻辑电路的同学想必都知道,在电路上实现“加法”比异或(XOR)要麻烦的多,况且后面还有一个模运算。因此非对称加密的速度自然而然是比不过对称加密的。 当然,我想另外还有一个原因是,AES 中的许多中间计算过程是可以事先计算好的。加密数据时许多中间过程可以直接查表,而不需要实时地计算。
通常情况下,非对称加密(如 RSA)的解密速度会比加密速度更慢,详情可参考Why is RSA decryption slow?
时空性 这里另外提一点,我们在学习算法的时候,一定听过时间复杂度和空间复杂度这两个名词。鱼和熊掌不可兼得,通常情况下,一个算法如果运行比较快,那么空间消耗相对来说就会高一些,反之亦然。因此才会有拿空间换时间的说法。 从上一节我们可以知道,非对称加密运行起来通常比对称加密慢,那么这时就有一个问题了,对于密钥的存储情况也是这样吗?非对称加密对于密钥的存储会比对称加密的密钥存储少吗? 答案是的确如此,在对称加密中,当信息量大的时候,要求密钥量也要足够大,需要每两个人之间都有一个密钥,也就是对于 n 个人来说,一共需要 个密钥才能确保两两之间对话不被其他人知道。 而在非对称加密中,每个人都有公钥和私钥,对于 n 个人来说,一共要 个密钥,就能保证两两之间对话不被其他人知道。
什么?你问我这个公式怎么来的?数学归纳法了解一下?
这么看,非对称加密虽然效率低下,但是存储成本低且相对安全,这也就解释了为什么非对称加密应用如此广泛了。
HTTPS 既然无法做到既安全又快速的加解密,那我们在实际使用时只能尽量达到一个动态的平衡。 因此我们在项目中通常会采用如下这种将两种加密算法结合在一起的使用方式:
...
前言 世界上根本没有 LSP,又或者,人人都是 LSP。
说起种子,你会想到什么?
是农民伯伯春天播下,秋天就会收获果实的东西?还是以.torrent结尾的文件?
如果是前者,那你一定是一个热爱大自然的人。如果是后者,你一定是一个“热爱生活”的人。
不过今天我们要聊的不是大自然的那个种子,而是 LSP 们喜闻乐见的这个种子。
P2P 与 BitTorrent 协议 所谓“种子”(或者叫种子文件),其实就是以.torrent结尾的文件,而他之所以叫种子,是因为这个文件里包含了你需要获取的文件的相关信息。就和自然界中的种子一样,包含了日后形成一颗果实所需要的最基本的成分。
而这个.torrent后缀其实指的是支持 BitTorrent 协议的文件。BitTorrent 简称 BT,俗称比特流。看到这,想必你已经有些印象了吧,我们常说的 BT 种子和种子其实是一种东西。
那么这个 BitTorrent 协议是什么?
不急,在介绍 BitTorrent 之前,先让我们梦回高中课堂,回想一下以前抄作业的时光。
抄作业的例子 如上图所示,学霸在写完作业后,要把作业借给同学抄,但是一次只能借给一个人,且其他人只能抄学霸的作业,那么如果想要让学霸在内的 7 个人都写完作业,取决与学霸写作业的速度和每个同学抄作业的速度。我们知道,这样的效率一定是很低下的,所以聪明的学霸想出了第二个办法。如下图所示:
学霸的办法就是,把作业分成几块,让每个人抄不同的部分,比如 A 抄单选题、B 抄多选题、C 抄填空题……然后每个人再把自己抄到的作业和其他人抄到的作业互换,这样,所有人都可以在规定时间内把所有的作业都抄完了,以此实现效率的提升。
P2P 与文件下载 之所以要先提抄作业这个事情,是因为这两种方案和下载文件颇为相似。
传统的文件下载就和上面的第一种方案类似,如上图所示,客户端向服务器发送“我要下文件”,服务器便将文件再发给客户端,这是一个很常见的场景,在这个场景中,客户端下载文件的速率取决于两个因素:服务器的上传带宽和客户端的下载带宽。带宽是指在单位时间(一般指的是 1 秒钟)内能传输的数据量。
而一旦需要下载的文件数量是多个时,下载的总时间便受到下载数量 N 的限制,即越多的人下载某一个文件时,理论上所需要的下载时间就越长,如下图所示:
这种用户体验显然是很糟糕的,那么有没有什么好的方法解决这个问题呢?这就要请出我们本期的“天降猛男”——P2P**(peer-to-peer)**。
这里的 P2P,和点对点(point-to-point)的协议程序不同,它是用户群对用户群(peer-to-peer),当然也不是我们前几年经常听见的暴雷的 P2P(互联网金融点对点借贷平台)。
本文所说的 P2P 是一种架构模式,就和我们之前说过的 C/S(客户端/服务端)架构类似。
在 P2P 模式中,服务和资源分布化,资源不集中存储在某些设备上,而是分散存储在运行 P2P 程序的设备上,每一个对等方都可以为其他对等方提供服务。
还是拿抄作业这个例子来说,学霸的第二个方案就是一个很典型的 P2P 模式。他将自己的作业分成填空、选择、单选、多选等部分,然后分别送给 6 个人,这样当每个人都有自己的一部分副本后,就可以不用再找学霸本人要作业了,直接找其他拥有和自己副本不同的人索取然后互换资源即可。
...
软件的复杂性带来的问题 工作一年多了,在涉及到跨部门合作的时候往往就是最痛苦的时候,其实道理很简单,刚开始,我们的组织和产品如左图,一切都比较简单,为了业务的发展,通过人工快速吃到技术和产品的红利,很多事情人工能掌控,有事吼一声,开个会就解决了,也运转得很好。
但随着慢慢发展,组织和产品就如右图,彼此连接依赖越来越复杂,为了整体的高速运转,对每个部件的稳定性越来越高,越来越精密,发展到一定程度,人力已经无法掌控,任何一个组件出异常都有可能牵一发而动全身,影响全局。每个部件的稳定性和精密程度决定了整体的工程质量,也决定了整体的发展速度。
那么,为了解决这样的问题,我们可以采取什么样的手段?
从汽车的发展到软件系统的建设 他山之石可以攻玉,软件系统虽然日益复杂,但和汽车建造无本质区别。软件编写完成后是要交付出去的,这就跟一辆车建造好后是要卖给别人一样,闭门造车无疑是自嗨。那么车主在买车的时候会考虑什么?
把时钟拨回到100多年前,贵族们在买车时,车能跑起来就万事大吉了;后来出“车祸”的人越来越多,开车变成了一件危险的事情,于是车企就开始了各种测试(例如碰撞测试);再后来,为了方便车主关心自己车子的状况,越来越多的车撞上了「仪表盘」;到了现在,没有仪表盘的汽车没有几个人敢开,因为你对车的健康、速度等状态一无所知,和闭着眼睛走路没什么区别。
如今,你再去买车,你会关心百里加速耗时多少,油耗多少,制动距离等等**「指标」,因为这些「指标」**让我们对最终交付给我们的车辆能提供的服务有一个明确的认识和期望,开车的时候心里更踏实。
软件系统的交付(代码->安装包->镜像) 回到软件系统,软件工程的本质就是为了解决软件系统的复杂性,而其中一个part就是就是交付过程的复杂性。
代码交付 一开始,我们会选择把代码+配置文档交给业务方,然后由业务方自己去打包、配置运行环境并进行部署和运行。这种交付手段可想而知:流程复杂且不可控,加之开发环境与生产环境的差异,上线前往往需要烧香拜佛,更多的不是技术问题而是玄学问题。
安装包交付 于是在代码的基础上更进一步,交付二进制的安装包或者将配置部署过程脚本化,实现了部署和运行的规范化。这种方式解决了流程复杂和重复的问题,但是仍然不能解决环境不一致的问题,因为宿主环境是你无法预先确定的。
镜像交付 再后来,开发者直接将代码及其依赖的环境(OS、三方库、配置等)完整地打包进虚拟机镜像,实现了一键部署和运行。这种方式既解决了流程问题,也解决了环境问题,主要问题在于虚拟机是一种比较重的技术,比较耗费资源和部署时间。而容器的出现,才真正改变了软件交付的形式,镜像将代码和环境全部打包,容器了确定镜像、部署流程与配置,实现一键部署和运行。 这种方式实现了 “一处编译,处处运行” 的美好愿景(同样愿景的Java还必须依赖JVM,而容器直接与OS交互,是真真的实现了这个愿景),并且比虚拟机更轻量高效,是目前软件交付的事实标准。
我们需要交付的究竟是什么? 类比上文说的汽车的交付,软件系统交付的究竟是什么?是代码吗?功能代码是模棱两可的,谁也不知道到底正确与否,交付质量全凭价值观保证。
客户需要的,其实是你交付的系统能做到什么,不能做到什么,你的系统是否达到我的期许,如果没达到我的期许,又该怎么解决问题。这就是系统开发者与客户之间的「约定」,在软件系统中称为服务等级协议,即SLA(Service Level Agreement)。
那么回到一开始的那个问题,为什么在涉及到跨部门合作的时候往往就是最痛苦的时候,本质上在于双方的SLA不对等,我认为你这个服务的提供方应该要给我提供这些能力,但是服务方却觉得这根本不是我的职责,我为什么要帮你解决问题。
升华一下,亲密关系也是如此,事先没有约定好你想要的和对方能给予的,吵架便也是家常便饭了。
SLA(Service Level Agreement) 前面铺垫了这么多,总算是来到本文的主角了。
SLA,是服务供应商与客户之间的服务等级协议,它定义了服务供应商应保证的服务质量,以及在服务不达标情况下的服务赔偿。SLA在定义上又细分为SLI、SLO与SLA。
SLI,服务质量指标,服务的某项质量的一个具体的量化指标。 SLO,服务质量目标,服务的某项SLI的具体目标值,或者目标范围。 SLA,服务质量协议,描述在服务不达SLO情况下的后果。 现在大家对于SLA的讨论更多是围绕着云服务厂商展开的,其实很好理解,云原生时代,云服务厂商就是最大的服务提供方,而用来确保服务双方达成一致的SLA,自然会更加重视。
云计算的最终愿景是**“让计算资源和公共基础设施一样,按照使用者的规模提供随用量变化的弹性经济模式!”**
虽然SLA常见于公司与外部供应商之间,但事实上SLA也可以用于公司内部两个部门,两个产品之间。公司内部可能不会涉及到服务赔偿,因此内部SLA更关注于SLO的达标情况。
一个实例快速了解SLI、SLO 给你承诺的男人不一定可靠,但连承诺都不给的男人一定不可靠。
男孩对女孩说:以后你发消息,我一定秒回,间隔时间超过xx分钟,我就给你送礼物
SLA中的对服务类型、质量时间条款的条文规定
可是女孩每次发消息的时候,男孩不是在洗澡就是在打游戏,每次都超过约定的时间
可用性低于条文中所规定的值
于是为了哄女孩开心,男孩只能道歉+送礼物
服务商所需提供的赔偿
久而久之,女孩终于忍受不了男孩的行为,选择删除好友。
客户更换服务商
在上面这个SLA的例子中,SLO(指标)就是男孩给出的秒回承诺,秒回(≈0ms)就是SLI(指标),「超过规定时间就送礼物」是未达标的后果,因此SLA又可以抽象成👇
SLA = SLO + 后果
如何描述服务质量? 对于大多数服务而言,表述服务可用性最直接的方式可能就是服务可用时间。
在这种体系下,常说的99.9%,99.99%,99.999%的可用性都是时间维度的统计,可以理解为:在规定的条件和规定的时间内,完成规定任务的概率。基于时间的可用性有如下表述形式👇
可用性 = 系统正常运行时间 / 统计周期内的总时间
...
前言 在初学 Java 时,相信大家下载安装完 JDK 后的第一件事就是 「配置环境变量」,几乎所有的教程都会告诉你当你在命令行工具中输入了 java 命令和 javac 命令后看到类似如下的结果就说明你的 Java 环境配置好了 👇
不知道你有没有思考过这个「环境变量」究竟是什么?为什么配置了之后就会显示这样的内容,为什么不配置,就会提示你一个错误:'javac' 不是内部命令或外部命令,也不是可运行的程序或批处理文件。
如果你也有这样的疑问,不要着急,我们今天就来一探究竟。
文内相关的演示,均在 Windows10 操作系统下执行
从打开软件的两种方式说起 我们平时打开一个应用程序,一般是双击桌面图标或在开始菜单链接,无论是桌面的快捷图标还是菜单链接都包含了应用程序的安装位置信息,打开它们的时候系统会按照这些位置信息找到安装目录然后启动程序,这里以 QQ 这个软件为例:
上面是我们最常用的打开软件的方式,当然了,既然知道了一个应用程序的安装目录位置,我们也可以通过命令行工具进入启动程序所在的文件,通过命令打开,如笔者 QQ 的位置为:
"C:\Program Files (x86)\Tencent\QQ\Bin\QQScLauncher.exe" QQ 的启动程序名为 QQScLauncher,那么我们打开终端工具,使用 cd 命令进入该目录,再输入.\QQScLauncher.exe,即可通过命令启动 QQ。
做一点改进 如果想要炫技,每次都先进入安装目录再打开文件显然有些麻烦,那有没有什么简单的方式,直接在命令行工具中输入 QQScLauncher 甚至直接输入 QQ 就能打开软件呢?
当然是可以的,我们只需要在用户变量名Path中添加安装路径的字符,我们在命令行工具无需进入软件的安装路径即可打开软件了。
我们来试下直接在命令行工具中输入 QQScLauncher,果然可以直接打开软件了。
原因 为什么配置环境变量前,直接输入 QQScLauncher 无法打开软件呢?
这是因为操作系统并不知道你的 QQScLauncher.exe 这个文件在哪里,所以无法执行对应的文件。
你在命令行里输入的那几个符号,其实就是一些可执行程序的名字(标签、别名),是可以直接被当前系统直接执行的程序。如果是在 Windows 系统中,则这些被输入的符号就是可以直接被 windows 系统执行、后缀为’.exe’的程序(文件)。
那么为了能够让操作系统找到这个可执行文件,我们就需要把 QQScLauncher.exe 这个 可执行文件所在的目录作为 PATH 环境变量的一部分设置起来,这样当你在命令行输入一个命令的时候,操作系统就会自动搜索 PATH 变量中所指定的所有目录 了。
...
对大多数人来说,在即将到达大学终点的时候通常会出现两条路,一条是步入社会就业,另一条是踏入高校读研深造。
往年,研究生复试和春招基本是同时进行的,这也就导致考研结束后很多人觉得自己没考好就直接放弃了复试。今年由于疫情的原因很多学校的复试都推迟到了 4 月底 5 月初,这就让很多 2、3 月开始工作的人,又多了一次选择的机会。
其实每年的这个时候都会有很多人讨论究竟是读研好还是工作好,不过毕竟没有人可以同时涉足两条道路,所以选择就变得格外重要。毕业之后我选择读研这条路,我的朋友寒食君也曾和我交流过并写了一篇文章《保研之路:从双非到南大》,现在很难确定这个决定对我来说是否正确,对其他人也同样如此。我们需要全方面的考量自己,从性格、抗压能力、未来期望、家庭条件等多个方面去考虑。
今天写这篇文章,不是为了告诉大家如何去选,而是想介绍一个我在读研期间认识的一个人,他的经历让我有些惊讶,完全可以拿去当考研成功的案例,这里给大家做选择时提供一些参考。他是我的舍友,本科来自于烟台大学材料科学工程中韩合作。高考时遭遇滑铁卢无奈去了这个三本,后来跨考考研时逆袭到南京大学读软件工程专业,读研时开始自学 Java,在这次的春招实习中斩获了网易、腾讯和微软的 Offer,最后选择了微软。从三本到 985 读研,再到斩获数个大厂 Offer ,这样的人,实在是少有。
最近一直有更新面经系列,本来也想记录下他的面试过程的,但是一想到他这励志的经历,便想请他谈谈自己这几年的心路历程,留下一点文字,给正在看文章的人一些指引和参考。下面我将会采用 Q&A 形式记录一些重要的内容。
为什么选择考研? 因为我本科是中韩合办的材料专业,所以专业课是由韩国语教授的。又因为我韩语不行,所以专业课都听不懂,说实话对我来说毕业都挺困难的。最简单的原因就是找不到工作,得想办法混个饭吃。放在面前的选择有三个,一是去韩企。我不会韩语,所以去不了。二是考公务员,我不知道你们了解山东不,在山东公务员首先很难考,其次像我这种不会喝酒的感觉也没啥前途。三就是考研了,也算是个没有办法的办法?
为什么考研选择了南京大学,而且还是跨考软件工程? 我高考考了两年,最后压本科线上的这个专业。本科挂了一万个科,在本科其实有想过修软件工程的双专业,也不是没报名,可惜第一天上课就和高数补考撞了。所以我就放弃了双专业(其实是因为懒得去了),去了补考(也没补过,最后重修了)。考研考了两年,第一年考南航差一分上线(吃鸡太好玩了,而且上线也不一定能录取),看到现在你肯定觉得我在装逼。其实我说这些是想表达,你想学习其实不一定来不及。第一年考研结束后,切实感受到了生活压力(同学大四回家生孩子了,导致没顺利毕业,爸妈帮他看孩子他也不好意思要钱,只能在我租的房子里睡沙发)。也好好想了想自己想要什么,所以决定好好冲个猛的,猛的冲不动就回家打工混吃等死。我认为我唯一比别人猛的方面,就是用搜索工具。我要散播第一个消费主义观点:**扔了百度,快想想办法用谷歌吧。**然后说几个关于考研择校的观点,不一定对,抛砖引玉:
招人越多的越好,这样如果你初试分足够高,复试就会特别稳。不用担心会因为奇奇怪怪的事情把你黑掉。而且招人足够多,分数线的波动就不会特别大。招三个人,有两个猛男一个关系户你考第三不也无能为力嘛。 如果你想考好学校,出身又很垃圾,那就直接冲猛的,在你能力范围内越猛的越好。这样可以一定意义上避免学历歧视,因为在好学校看来你们学历都挺垃圾的。(这是我的个人看法) 现在每个学校基本都能搞得到历年真题,尽量选变化不大的。学校出题变化大,对于猛男来说没啥,但是我们小弱鸡不能拿二十几岁的一年时光来赌这个。 想要完成以上的筛选工作困难并不大,特别是在你搜索工具用的得心应手的情况下。南大软院在我考研那年来看性价比是特别高的。你可以试着问问你的亲戚朋友,如果不在江苏省内的,可能很多人都不知道南大是个什么级别的学校,说不定你说南大很多人都以为是南开大学。但是这又是个极好的学校,所以很适合捡漏。又因为考英二数二(对高考英语 80 分且四级没过的我比较友好),会导致调剂困难(大部分学校都是考英一数一的),有一部分人就会因此不敢报名。而我的打算就是考不上就回家打工嘛,我也没想调剂,所以比较适合我。确定南大之后就是计算机院和软院之间的选择了,南大计算机院有国重,用屁股想想就知道对科研要求高,我啥也不会还跨考,本科也不好也没啥科研能力,别人咋也不可能要我。经过一通排除,我就选择南大的软工(当时在考研群里看了几个考人工智能院的大佬,第一届参考书都整不明白就敢冲,瑞思拜)。
然后是我考研的一点小心得。我太讨厌我家乡的生活了,导致我有无穷的动力来压迫我自己好好学习。考研第二年,真的是拼了命在学,不然像我这种啥也不会的不努力想考上南大肯定是不可能的。我要在这里散播我的第二个消费主义观点,**能花钱省时间的,价格不是太离谱就别犹豫。**跨考相较于不跨考的人来说,你的时间肯定是更宝贵的。保证时间,一是需要延长学习时间,二就是要在单位时间内学多一点。我完成这两点的方式如下:
建立起学习的工作流。 通过番茄钟来保证单位时间的效率,也可以有效统计每天的学习时间。 使用 anki 和思维导图来进行知识的复习,保证你学完的东西不会白学。 花钱让自己学习的效率更高。(别人售卖的,声誉良好的课和资料一定是有原因的,他至少花费了课程数倍的时间来沉淀知识,这也是我觉得为啥听话的孩子普遍吃亏少发展好的原因) 但是我认为学了两年是最重要的一点,说到底就是磨出来的。当然我也吃了一些亏,我经常会纠结哪个课最好,然后对比很久。方法总是第二步,开始学习才是最重要的第一步。找到一个差不多的尽快开始,会比花时间在比较上好很多。
你本科是材料专业的,考研时才接触的软件工程,现在研一也快结束了,有什么收获吗? 从一个啥也不会的小菜鸡到能写出来点能动弹的东西,还是挺有成就感的。
一个好的环境很重要,我能有这些大公司的面试机会就是吃了南京大学的红利。而我研一能有这些进步,主要在于身边有太多优秀的人。说实话第一次上课我是挺震惊的,虽然没有很多人在听课,但是所有人都在学自己的东西。这个公众号的主人也给了我很大帮助,我刚上学真是一头雾水啥也不懂。没他指路现在估计我还在慌着面试呢。披头士几个人都猛,但他们肯定不能都是天才吧。持续训练,刻意练习,才是我们这些笨逼的归宿。虽然现在我在他们之间还是最菜的,但是比较来看,说刚开学的时候我和他的编程能力差一百个我是不过分的,但现在估计也就差几个我了。
这次春招,你面试了哪些公司?最终选择了哪家呢? 面了一万个公司。你能想到的说的出名字的说不出名字的基本都面了,阿里、腾讯、头条、美团、网易、微软等等等等等等等。拿到 offer 的就只有微软、腾讯和网易,没拿到的就是都挂了。这其实还是一个笨逼多锻炼的故事,多试试总有运气好的时候吧。而且面试官的问题都是类似的,有一次我上午面网易,下午面腾讯,问的问题几乎一模一样。只要你在面试之间多总结,总能磨进去。最后还是选择了巨硬,第一是因为从小就想去巨硬,第二是因为比尔盖茨是我的爱豆,第三就是因为身体不太好,想养老发自内心。
可以简单说下,面试这些公司的过程吗? 大伙开始投阿里提前批的时候,我很慌,不敢投。导致错过了很多锻炼面试的机会,因为最开始是不进系统的。你一个部门挂了其实就只是那一个部门有你的记录,建议大伙还是阿里提前批多锻炼。小公司练手是个美好的想法,但是不切实际。为啥小公司是小公司,他们效率真的不太高,像有的同学阿里、腾讯或者头条都拿到 offer 了小公司还没有开始面试。
最开始面试肯定是慌得一逼,话都说不顺溜。面多了感觉其实还是在于多吹,你吹得面试官和你都开心,这次面试基本就没啥问题。下面说一些我的经验,不一定对,毕竟还是挂了很多面试。
别人问你一个问题你最好把你知道的都说出来。如果我当时遇到了这个问题,我就会把我是咋解决的过程说出来。 代码题需要疯狂判断边界条件。写之前就要和面试官沟通时间复杂度和空间复杂度,说不定面试官心情好会给你点提示。会写英文注释就用英文注释装逼。 最后问问面试官对你的建议,过来人说话还是好使的。 把面试官对你项目的质疑,提炼出来,下次在详细介绍项目的时候把它变成你对你的项目的思考。 为什么会选择微软,你觉得微软相较于其他几家公司,更吸引你的地方在哪呢? 前面回复啦~
为了去这家公司,你做了哪些准备呢? 刷 leetcode,我刷的题目说实话挺少的,但是一直比较在意代码的简洁程度。代码题其实都不会很难,难得一逼你实在不会,考官可能会暗示你,还有可能给你换题。不用慌。外国公司大部分就是考察你做算法题的能力,你买个会员把这个公司的题库都刷完必能过(公司肯定也想要你这样的,不管是聪明的一逼算法题随便秒的,还是对着公司题库全刷一遍的,都是公司想要拥有的人,我从网上看的)。 项目肯定还是要整明白的,在多次面试之后就算你整不明白你的项目,面试官也会把你问明白的。 基础知识需要过一遍,JVM、操作系统、计算机网络等等。争取要比别人写的资料深一点点。这些问题千篇一律,你回答的多一点,就显得你猛一点。 可以晒一下你的 offer 吗? ...
七夕佳节, 送你们一份来自直男的代码情书
代码情书——谁说程序员不懂爱 曾经有一份真挚的爱情摆在我眼前, 我没有珍惜, 等我失去的时候我才后悔莫及, 如果上天能给我一个再来一次的机会, 我会对那个女孩子说三个字我爱你, 如果非要在这份爱上加一个期限, 我希望是一万年。 来源: 电影《大话西游之大圣娶亲》
public class Love { public static void main(String[] args) { boolean love = true; while (love) { love = false; } me.regret(); if (god.getChance()) { me.sayToHer("我爱你"); if (me.getLoveTime() < 10000) { me.setLoveTime(10000); } } } } 你的一句明天见, 偷走了我整个夜晚的睡眠。 来源: https://www.zhihu.com/question/28314613
public class Love { public static void main(String[] args) { while (you.say("see you tomorrow")) { i.sleep = 0; } } } 我愿化身石桥, 受五百年风吹, 五百年日晒, 五百年雨打, 但求此少女从桥上走过。 来源: 电影《剑雨》
...
没有一个树莓派能逃离吃灰的命运。
去年我写了一篇《树莓派家用指北》,介绍了树莓派是如何作为家庭服务器改善我的生活的,指路链接 👇
https://mp.weixin.qq.com/s/JZR2gFnIFoYDG7Z9HwsS3A
今天我们的主角依旧是我的那个树莓派,只是以另一种形式在我的家里发光发热——电视盒子。
看到这可能有人会好奇,这个树莓派用作电视盒子后,原先的家庭服务器怎么办?事实上我之所以把这个树莓派做成电视盒子,第一个原因是我搬家了,需要重新升级规划下家里的软件系统,第二是我用 NAS 替代了原先的树莓派用作家庭服务器(有机会的话以后讲一下)。
所以为了不让这个“理财产品”就这么吃灰下去,我一直积极探索可能的用处,终于,我发现了一个最适合他的场景——Android TV。
为什么会想到 Android TV? 搬家之后,新屋子里有一个电视 + 办宽带送的中国移动的电视盒子,第一次打开它的时候,卡顿的系统、上古的 UI、繁杂的广告让我不禁感叹,这真的是 2022 年的东西吗?
心想那要不买一个 Apple TV 吧?可再看看价格,不免囊中羞涩,算了算了,还是留点老婆本吧。况且 Apple TV 这么好的盒子用在一个只有 1080P 的电视里属实是有些浪费了。
既然用不了苹果的电视服务,用安卓的总可以吧。
于是我又去搜索了一些国内的电视盒子,什么小米的、当贝的、荣耀的,横向比较了一下,不是性能孱弱(通常都是 2GB+32GB)就是广告遍地,而且还不能看海外电视。当然了,最关键的是还要多花一笔钱,想了想还是放弃了。
既然国内的安卓盒子不行,为什么不试试原生的 Android TV 呢?2022 年了,原生的 Android TV 应该有不少的发展了吧。
抱着试一试的心态,我打开了 Android 开发者的官网,发现 2022 年的 Android TV 无论是 UI 还是体验,都比以前有了长足进步,现在就差一个载体,而我刚好有这个最好的载体——树莓派。
行动起来 本文不是一个教学贴,因此不会手把手的记录整个流程,简单介绍一些我在自制这一过程中的关键点以及可能出现的问题。参考的帖子:https://konstakang.com/devices/rpi4/LineageOS18-ATV/
准备工作 你需要准备的东西有:
一个树莓派 3B/4B,至少有 2GB RAM,建议 32GB+ 的 SD 卡(我的是 8GB RAM + 256GB ROM) 一根 mini HDMI 转 HDMI/DP/VGA 数据线(根据你家的电视接口定) 树莓派风扇(如果有最好,毕竟是 24 小时不关机的,散热还是有必要的) 我选择的是 konstakang 提供的 LineageOS 18.1 Android TV (Android 11),没有选择上 Android 12 的原因是当时还没有出 12 的 GApps(谷歌提供的一些套件),再加上一个电视盒子也没必要追求那么新的操作系统(国内还有不少手机停在 Android 10 万年不更新)
...
2018 年 6 月 21 日,我在掘金发布了我的第一篇博客 👇 到今天这第 100 篇的时候,已经过去 2 年多了。这 2 年发生了好多好多事,毕业、保研、暴瘦、恋爱、分手、实习。如果说有什么事是没变的,那应该就是我一直在做技术分享。我知道我的阅历尚浅,所写文章的深度有限,我的文笔也不是很好,也写不出富有文藻的文章。所以我非常感谢这些关注我的,读我文章,给我点赞的好人们。如今我也算是半只脚迈入社会的人了,感触良多。正好借着这次掘金年中总结的征文好好总结下这半年来的所学所思所想(估计活动都要结束了吧)。 上图是我这两年在掘金的成绩,2 年时间才这么点东西我心里也是很惭愧的,今年上半年总共发过 20 篇文章(部分没有在掘金更新),平均一个月 3 篇左右。其中很大一部分还是收集的身边好友的实习经历,外加一些翻译的文章,这么一看真实产出就更少了。其实我的计划列表里堆积了很多要写的文章,但每每准备写点什么的时候又停下了手里的键盘,原因我自己心里也很清楚,这半年我的状态很差(好像从去年开始我的状态就不怎么好),经常性的失眠,新年伊始和女朋友分手,随即迎来新冠疫情,学校不开学了,还要忙着找实习。因为疫情的原因,各行各业都有所缩水,互联网行业也不例外,所幸我的运气还算可以,拿到了淘宝和字节的实习 offer。我找实习的经历之前有写过 👉搏一搏,单车变摩托,记录一下我的淘宝实习面试 之所以最后选择了来淘宝实习,一方面是因为阿里巴巴是我一直很想去的公司,另外一方面就是字节跳动的加班太严重了(虽然在国内 996 已成常态了)。 其实在找实习前,我是很迷茫的,我也不清楚自己应该要找什么样的岗位,当时的我做过深度学习的项目,会写一些网页,也会用 Python 的 Flask 和 Java 的 SpringBoot 做些后端项目,顺便也会写写 App 什么的。总的来说,我的技术栈是很混乱的,不过也可以理解,毕竟是学生,乱七八糟的什么都学了一些。所以这两家公司里,字节投的是客户端,淘宝投的是服务端。当时的想法也很简单,谁要我我就去哪搬砖。对于我们计算机专业的同学找实习,我之前写过一篇指北文章,有兴趣的朋友可以阅读参考下 👉计算机相关专业实习指北
选择合适的路 之前有人问过我,都读研了为什么还要做开发,这样一来,和本科生有什么区别? 真的是,我要是能从那些大佬手里抢过算法岗的 offer,我也去抢啊。 年年都说算法岗爆炸,今年更甚,有些大厂的算法岗投录比甚至已经 40:1 了,和你竞争的不光是优秀的硕士,更会有一些博士对你降维打击,人家拿出一两篇 A 类论文,怎么打? 再加上,我对自己的能力也很清楚,天赋不够,也不想用努力去凑,读博什么的对我来说可能更多是赌博,与其这样,不如早点找个开发的工作,拿个像样的薪资苟一波。 算法岗,相对普通开发来说,薪资高,加班少,给人的感觉就是每天看看论文,跑跑数据,掉的头发也不比普通程序员多,再加上某些“鄙视链”的存在,自然会更吸引人。可好的并不一定是适合你的,就像你喜欢的菇凉,不管再怎么优秀,三观不合,也是不合适的。所以选择一条适合自己职业发展的方向才是最重要的。
谈谈实习感受 2020 的开局非常魔幻,庆幸我的上半年还算平稳。前半部分在找实习、后半部分在实习。怎么找实习之前谈过了,这里就简单聊聊自己实习期间的感受。
对自己的代码负责 来阿里也已经 2 个多月了,需求没做几个,倒是体重增了几斤。实习前,听的最多的一句话就是“面试造航母,工作拧螺丝”,这话并不假,大多数人进来后都不可能让你从 0 开始做一个项目,更多的还是在已有项目的基础上加些功能,但并不能因为是拧螺丝的工作就可以掉以轻心。因为一颗马蹄钉输掉一场战争的例子比比皆是,入职培训的第一天就看到的非常非常多资损的例子,其实都是因为一些小失误导致的。更何况,拧螺丝也是一个积累的过程,如果连一颗小小的螺丝都拧不好,等真的有造航母的机会你也参与不了。 不想造航母的工程师不是好码农,不管是在哪工作,不求把代码写的像诗一样,但求不要把代码写的像 💩 一样。心中要牢记,对自己的代码负责。
持续学习的观念 活到老,学到老。考上了一个好大学,找到了一份好的工作,并不是结束,而是开始。 大家都知道,好的公司都更愿意收一些名校的学生,不单单是因为名校的学生能力更强一些,更多的是因为公司对于展示出高水平**“学习力”的员工有着巨大的需求,“学习力"是指快速成长和调整自身技能的渴望和能力,以保持在工作生涯中的称职状态。这是一种抽象的能力,所以如果想要快速的筛选出拥有这种抽象能力的人,最方便的就是看出身。这话说的很残忍,但也很现实。 那怎么样才能保持持续学习的状态呢?我的建议是持续接触新的事物**,只有当你不断接触新鲜事物,真正觉得自己无知的时候,才会永远保持一颗学习的心。这也是我为什么一直坚持做分享的原因。
工作与生活的协调 上面提到的持续学习的观点并不只是适用于工作中,生活中同样如此。除去技术,这个世界上有趣的东西还有很多。我们同样需要去学习、去探索。 只是,我们处在这个行业,有太多太多不得已,996 的口号喊了没多久,007 就已经开始流行。一天就 24 小时,工作的时间是有限的,压榨你的欲望是无限的。之前我写过一篇吐槽,算是小小的抗争吧 👉我不想加班,您看我还有机会吗? 阿里的加班是出了名的,哪怕实习生也不例外,所以为了避免在通勤上花费我太多时间,我租的房子离公司只有 10 分钟路程。幸运的是,公司给实习生提供了租房补贴。但即使是这样,等回到家收拾好也已经差不多快 11 点了。如果中途想跑跑步、看看书可能就更晚了。 其实我自己也没办法完全做好工作与生活的协调,毕竟下班都已经很晚了。周五不加班,周末双休已经是我最后的倔强。空闲时间我会出去吃点好吃的,健健身,发工资的那个周末还会出去旅旅游、拍拍照片。我觉得工作不只是为了工作,而是为了更好的生活,如果本末倒置是得不偿失的。当然,可能很多人会觉得我的这番言论还太过幼稚,我也知道很多人到中年会有不得已的“中年危机”,可对于我来说,这些到底还是太过遥远。我还不想未雨绸缪到让自己在本该快乐的年纪疲惫不堪。
...
该图片由Free-Photos在Pixabay上发布
我从今年年初正式运营我的公众号到现在也有小半年了,说来也惭愧,一个运营了将近半年的公众号到现在连1000人也没有,虽然我在去年年底给自己定的目标就是今年公众号人数达到1000人,但是这个数字和其他的公众号对比多少还是显得寒碜,期间我也考虑过怎么吸引读者,但是实在也没想出什么有效的方法。近期也发了一些不温不火的文章,但总是没办法保持持续更新,现在更是能做到一周一更就很不错了。一方面是因为自己最近这段时间毕业季确实太忙了,另一方面也是因为自己技术确实不强,很多时候也不知道可以写什么。我之前想过写系列文章,也做了尝试👉《AI 绘画系列》,虽然阅读量没有多少,但毕竟是自己写的,觉得只要自己努力去做了,收获多少会有一些的。
于是我又心血来潮,想开(挖)一个新的系列(坑)了。我决定在公众号上发布Leetcode的题解(虽然我知道有很多人的博客里面都有)。我在今年年初立了一个flag,就是在Leetcode上刷满400题,前段时间因为要做毕业设计和写毕业论文耽搁了一阵,前天重新登录网站发现自己才做了200多道。
做题期间我也整理了一些题解,想着这些题解既然搁着也是搁着,倒不如拿出来放进公众号里,当然我更希望大家也可以把你们题解分享出来,说不定哪天有兴趣了,或者业务代码写的太累了,花个十来分钟做做算法题也未尝不可。
不知道是不是因为我的公众号没有文章留言功能,总觉得和读者之间的互动性几乎为0,越来越觉得自己的公众号变成了"自嗨号"。我起初做这个公众号的目的就是希望和大家一起交流进步,然而现在却事与愿违,所以在这篇文章末尾我会发起一个关于是否建读者群的投票,希望大家可以多多支持🙏
该图片由Coffee Bean在Pixabay上发布
受到公众号「曾少贤」的启发,自己也整理了一些我在生活中经常使用到的在线网站,涉及的领域有图片、设计、文档、编程、学习等方面,这里分享出来,希望可以对大家所有帮助。话不多说,我们开始吧 😄
免费图片库 Pixabay 地址: https://pixabay.com/zh/
首当其冲的自然是 Pixabay 了,我几乎每篇文章的题图都是在这个网站发现的。这是一个免费的图片网站,图片质量高,数量多,种类繁杂,最最关键的是它免费。
在线抠图/换背景 地址: https://www.gaoding.com/koutu
有时候我们需要将图片的设置成透明的,虽然使用 PS 等工具可以实现,但是操作起来总是有些难度,无意中发现这个网站,只需画几笔,3 秒就能稿定透明背景。
在线图片压缩网站 地址: https://zhitu.isux.us/
很多人都会推荐 TinyPNG,但是 TinyPNG 的限制太多了,使用起来很 XX,直到我发现了「智图」,可以选择图片格式和压缩品质。
在线文件转换网站 地址: https://www.aconvert.com/cn/
我们经常会碰到转换文件的需求,很多人会在电脑上下载一个格式工厂之类的软件,然而一个网站就可以了。Aconvert.com 可以在线转换各类PDF,文档,电子书,图像,图标,视频,音频和压缩文件,非常方便。
微信公众号格式化工具 地址: http://blog.didispace.com/tools/online-markdown/
公众号排版是一个很头疼的事情,尤其对我这样一个直男来说,排一次版的时间可能跟写一篇文章的时间差不多,好在我发现了这个工具,可以轻松的将 Markdown 文件转换成微信公众号可用的 HTML 格式。对于比较懒的公众号主来说是不可或缺的神器。
绿豆堂中文字体免费下载 地址: http://www.lvdoutang.com/zh/0/0/1/1.html
在开发过程中,我们可能会使用到多种字体,仅靠系统自带的一些字体无法满足我们的需求,这时候就需要寻找一些字体了,这个网站有很多好看的免费字体,足够日常使用了。
草料二维码 地址: https://cli.im/url
这个就不多说了,生成二维码用的。
二维码梦工厂 地址: http://qrdream.com/
单说二维码肯定是不够的,现在的年轻人都追求二维码的美观,仅靠草料二维码内置的美化器是不够的,这里推荐一个「二维码梦工厂」,里面有很多非常好看的二维码模版可供选择。
在线 Logo 制作器 地址: https://www.designevo.com/
对于没有学过设计的程序员来说,如何给自己的个人网站(博客)上添加一个好看的 Logo 是一件很困难的事情,然而有了这个网站后我们就可以自己作出一个好看的 Logo 了。我相信很多人都用过那些所谓的”免费“Logo 生成器,在花了很长时间制作好 Logo 准备下载的时候网站却提示你要付费,让你顿时有一种受到欺骗的感觉。好在这个网站在做好 Logo 后会给你几个选择,如果你想要高质量的 Logo,需要付费购买。如果你对 Logo 的质量要求不高,这个网站还是个很不错的选择。
...