plainify

为了预测股票,我用TensorFlow深度学习了股市数据

完整源码可在微信公众号:「01 二进制」后台回复:「股市分析」获取 阅读此文前建议先阅读《找对象的过程中,我竟然理解了什么是机器学习!》 前言 相信大家这几天或多或少的都开始关注到股市了,虽然我还不是很懂里面的一些套路,但是从最近各个公众号的推送里面,我也看到最近的股市确实是形势大好。对很多人来说,股票就和房价一样,他的升与降牵动着众多人的心。这几天很多 qq 群、微信群都开始讨论起股票了,各位坊间大神也纷纷开始预测各种股票走势了。 股票价格是典型的时间序列数据(简称时序数据),会受到经济环境、政府政策、人为操作多种复杂因素的影响,所以说股票价格预测是一件非常唬人的事情。但是基于历史数据,以股票价格为例,介绍如何对时序数据进行预测,仍然值得一做。 不过今天我们不聊股市,因为我也不是很懂,今天我们来聊聊我们知道的东西。如今深度学习在金融市场的应用越来越广泛,我们能否利用已有的历史数据通过深度学习的方式来进行预测呢? 准备工作 答案自然是可以的,虽然我们无法非常准确的进行预测,但是作为一个深度学习入手的项目是完完全全可以的。 实验环境 老样子,以免出现因环境导致的问题,先将实验环境列出: MacOS 10.14.3 Python 3.6.8(Anaconda) Jupyter Notebook 使用的包有: TensorFlow Keras matplotlib pandas 数据 此次实验,我们采用STATWORX的S&P 500股价数据,该数据集爬取自 Google Finance API,已经进行过缺失值处理。他们的官方网站是:https://www.statworx.com/。 数据集可在微信公众号:「01 二进制」后台回复:「股市数据集」获取 数据预览 在这里我们还是使用 pandas,主要用于数据清洗和整理 import pandas as pd data=pd.read_csv('data/data_stocks.csv') data.info() 执行data.info()可以查看特征的概要: <class 'pandas.core.frame.DataFrame'> RangeIndex: 41266 entries, 0 to 41265 Columns: 502 entries, DATE to NYSE.ZTS dtypes: float64(501), int64(1) memory usage: 158....

plainify

为什么不在 for 循环里捕获异常?

在回答标题这个问题之前,我们先试想一下,在没有 try…catch 的情况下,如果想要对函数的异常结果进行判断,我们应该怎么做? 异常 第一个想法肯定就是 if…else 了,一般情况下,相关的代码段我们都是放在一起的,如果此时你的程序中有大量的代码段要做这做判断,这就意味着后面执行的逻辑会依赖你前面语句的执行情况,也就意味着你每调用一个可能会出现错误的函数的时候,都要先判断是否成功,然后再继续执行后面的语句。这就会导致你的代码中会充斥着大量的 if…else。 Java 是一门工程性的语言,而工程也是一种艺术,因此采用这样的做法显然是很不优雅的。《Thinking in Java》中提到“badly formed code will not be run.”,意思是结构不优雅的代码不应该被执行,于是一个适用于 Java 的异常处理机制便应运而生了。 Java 的异常处理其目的在于通过使用少于目前数量的代码来简化大型程序,举个简单的例子 🌰 不用 try…catch FileReader fr = new FileReader("path"); if (fr == null) { System.err.println("Open File Error"); } else { BufferedReader br = new BufferedReader(fr); while (br.ready()) { String line = br.readLine(); if (line == null) { System.err.println("Read Line Error"); } else { System.out.println(line); } } } 用了 try…catch...

plainify

为什么我们需要批量操作?

背景 实习的时候被问过一个问题,为什么 redis 会有 pipline,mysql 会有 batch,这些东西都具有批量操作的共性,是什么原因让我们在处理数据时需要批量操作? 这么说可能有些抽象,举一个和 API 调用有关的例子 🌰: 现有三个服务 service A、service B 和 service C。因业务需要,我们需要在 service A 中调用 service B 获取一组 id,然后根据 id 从 service C 中读取最终内容。然后组织成结果返回前端。由于 service C 只提供了单个 id 查询内容的 API,所以如果我们想要获取批量的信息,最先想到的办法是通过 for 循环多次调用 service C。但是这样的办法是极其不优雅的,接下来我们从以下两个方面来分析。 网络通信 鉴于现在的分布式架构,每个 service 都分布在不同的服务、不同的机器中,所以我们每次调用都要通过 RPC 来实现,这就要求我们不得不构造同等数量的请求来获取数据。这样就会导致了一些效率问题。如下图所示: 所以我们通常会通过在 service C 中提供一个批量查询的接口来解决多次通信的问题。如下图所示 👇 我们知道,并不是每一次网络传输都非常稳定,中途可能会遇到丢包等一系列问题,而用批量查询代替 for 循环单个查询,这样做的好处是,我们可以减少网络通信的次数,一定程度上可以增加整个系统的健壮性。 数据查询 解释完多次 rpc 调用可能造成的网络延迟的问题后,我们再往深一点的地方看。 一般情况下,数据都是存放在数据库中的,所以无论是单个查询还是批量查询,我们最终都是要访问到数据库的。 现假设,我们需要从数据库中查询一个 id 为 123 的用户信息,我们可以用类似下面这样的代码。 long id = 123; Person p = serviceA....

plainify

为什么我建议你去写博客?

每次有学弟学妹问我如何学编程的时候,我都会在最后告诉他们最好写篇博客记录下。现在是 2020 年的 11 月,我自己写博客也已经有 3 年多了,零零散散也写了有 200 多篇了,虽然不如一些大佬写的多且快,但自己佛系更新倒也开心。刚开始写的时候,也没想着能坚持到现在,现在写了几年,渐渐也成了一种习惯,今后应该还会继续写下去。 维基百科对于博客的解释是: 博客(英语:Blog)是一种在线日记型式的个人网站,借由张帖子章、图片或影片来记录生活、抒发情感或分享信息。博客上的文章通常根据张贴时间,以倒序方式由新到旧排列。 说白了就是记录自己的一些想法、学习心得、总结之类的,主要还是看自己想写什么。 我是一个文笔很差的人,高考语文也是勉强及格,所以如果一开始你告诉我,我的文字将会对我产生很大的影响,我肯定是不相信的。直到后来本科学了软件工程之后,想着要整理一些自己的学习笔记,但是代码也不方便用纸记下来,这便开始有了用电脑做笔记的想法。当时的做法也很土,就是新建一个 word 文档记笔记,然后用一个文件夹收录,后来经学长提点,索性就把笔记整理到 csdn 上,这样就不用每次记笔记还要新建一个 word 文档了。 再之后,看到了阮一峰、池建强的博客网站,也学到了很多有用的知识,也萌生出弄一个自己的博客的想法。期间也尝试了很多,有在掘金、简书等第三方平台上发布博客,也自己玩了玩 wordpress、hexo 这样的自建博客,现在也算是确定了写作的位置,最终选择了自建博客(hexo)+掘金/简书/公众号的搭配。掘金和简书主要是发布一些技术性的文章,例如实战教程这些,公众号吹水的比较多,科普一些我学到的技术、聊一聊我的想法之类的,然后所有的这些都存放到我的自建博客中去。 之所以会选择 hexo 这种自建博客,一方面是因为他的颜值比较高(虽然 wordpress 也可以安装各种主题),只要下载别人的主题简单的配置下就可以弄出一个好看的博客了。另一个原因就是部署、同步相较于 wordpress 更加方便,hexo 是用 markdown 的形式进行写作,这样的好处就是我可以无缝迁移到简书、掘金、公众号等平台,而且和 wordpress 这种需要自己购买服务器的自建博客相比,hexo 可以依赖 GitHubPages 免费使用,这对于我这种白嫖党来说无疑是最好的选择。 其实写博客的这几年也有人问过我,你又不接广告,也没什么人打赏,还要花那么多时间来写博客,不觉得累吗?为什么还坚持写了几年? 说实话,写博客确实是很花时间的,但是我认为和单纯的学习笔记相比,博客是对笔记的又一种成体系的整理,一方面可以加深记忆,另一方面也方便日后的查找翻阅。 不仅如此,如果你的博客内容质量很高,在一定程度上是可以提高自己的影响力。在如今这个浮躁的社会,很多人的文章都是东拼西凑,如果你的内容有足够的深度,那么物以稀为贵,你会更加容易、持久的建立起自己的影响力。 而且就算你的文笔不够好,也可以在写博客的过程中锻炼自己的思维能力、知识储备能力,以及思维的严谨程度。我相信,在写作过程中得到的锻炼,对于你在其他领域的工作,依然会有所帮助。 功利点说,如果你的内容质量非常高,也是可以通过写作赚钱的。我们正处在一个“知识付费”的年代,写达人课、写书、写推广文、写公众号,这些赚钱方式不一而足。而且不同于工作,你在写作上所花费时间可以被多次售卖,你可以通过你的写作,构建出属于自己的**「睡后收入」**。 当然了,博客也不单单可以用来整理学习笔记,我时常会通过博客来帮助我探索、梳理和记录生活。写一篇博客所花费的时间,比整理笔记要多得多,但另一方面,我们又会浪费很多时间。坚持抽一些时间写一篇博客,一定程度上可以让自己学会管理时间,毕竟谁不希望可以成为一个“时间管理大师”呢? 以上就是我对于写博客这件事的一些简单想法,就个人而言,写博客的这几年,我的知识储备得到了提升,也获得了一些收入,还通过博客认识到了一些有趣的人。当然,如果你觉得你想说的东西不适宜让他人知道,其实也可以在自己的电脑里写,不用放到网上。但我还是强烈建议,每一个朋友(尤其是计算机专业),都应该有一个属于自己的 Blog,尝试将自己的生活和想法记录下来,留下一些印记,说不定未来的某一天你的博客就让你的人生有了一些变化,毕竟,我女朋友就是写博客认识的(逃)。

plainify

为什么非对称加密比对称加密慢?

这个问题是一个读者面试时遇到的一个问题,准备过面试的人应该都记得,非对称加密与对称加密的区别之一就是非对称加密的速度慢,但是我们做业务开发的时候通常都是直接调用算法,对其原因并没有过多深究,因此如果有面试官问到了这个问题,的确会让人措手不及。正好借着这篇文章来说一说。 对称加密与非对称加密 首先我们先来说一下到底什么是对称加密,什么是非对称加密,这一节主要是用一些例子来介绍一下对称加密和非对称加密是什么,如果你已经了解了,可以跳过本节。 对称加密 高中生小明和小红是一对“地下情侣”,可偏偏他们一个坐在教室前,一个坐在教室后,所以晚自习的时候也只能通过纸条传情。这时一个很尴尬的事情就出现了,由于无法直接将纸条交给对方,因此纸条必须要经过多个人的传递,可总有一两个八卦的人喜欢看纸条里写的什么。为了避免被班主任抓包以及被同学们窥视,他们两约定,用现代汉语词典当作“密码本”,以后传纸条时,纸条上的内容是要写的字在词典里的页码及顺序,这样即使纸条被别人看了,不知道密码本是什么的人也就不会得知纸条里的真正内容了。 在上述的例子中,纸条是承载信息的载体,纸条里的内容是信息,汉语词典是密钥,将文字映射到汉语词典的页码和顺序是加密方式(算法)。 类似于上面这种,在加密和解密时使用相同的密钥,或是使用两个可以简单地相互推算的密钥的加密方式就是对称密钥加密(Symmetric-key algorithm),简称对称加密。常见的对称加密算法有:AES、DES、3DES 所以你可以将对称加密简单理解为:一方通过密钥将信息加密后,把密文传给另一方,另一方通过这个相同的密钥将密文解密,转换成可以理解的明文。他们之间的关系如下图所示(这里借用一下@寒食君的图): 弊端 这种加密方式虽然简单,但是其弊端也是非常明显的。在上面的例子中,如果传递纸条的人知道了他们这种加密方式,那就同样可以通过查阅汉语词典解析出他们的纸条内容。如下图所示。这样为什么众多抗战片中会出现疯狂抢夺密码本这一情节也就很好理解了。 非对称加密 再举一个生活中非常常见的例子。小区里的小伙伴们经常可以在自家的邮箱里收到信件,比如你的录取通知书,当然更多可能是广告。不过,虽然说所有人都可以往里面扔邮件,但是只有你可以打开这个邮箱查看这个邮件。 上面这个过程就是一个很形象的非对称加密。 非对称加密不同于对称加密,它有一对秘钥,一个称为公钥(publicKey) ,另一个称为私钥(privateKey),并且***只知道公钥是无法推算出私钥**。*就和上面的例子中只知道邮箱位置却并不能打开邮箱是一个道理。常见的非对称加密算法有:RSA、DSA、ECC 另外,这种算法还有一个特别神奇的功能,那就是通过公钥加密的内容,只有私钥才可以解开,而通过私钥加密的内容,只有公钥才可以解开。 公钥/私钥的用法 第一种用法:公钥加密,私钥解密。—用于加解密 第二种用法:私钥签名,公钥验签。—用于签名 其实很容易理解: 既然是加密,那肯定是不希望别人知道我的消息,所以只有我才能解密,所以可得出公钥负责加密,私钥负责解密; 既然是签名,那肯定是不希望有人冒充我发消息,只有我才能发布这个签名,所以可得出私钥负责签名,公钥负责验证。 这里提一点:签名 ≠ 加密,通俗点说加密就是你哪怕看到了不该看到的东西,也理解不了。而签名就是你做了任何事,都抵赖不了。 为什么非对称加密比对称加密慢? 介绍了这两种加密方式后,我们终于可以回到本篇文章的开头了,为什么非对称加密会比对称加密慢? 这是因为对称加密主要的运算是位运算,速度非常快,如果使用硬件计算,速度会更快。以 AES 算法为例,如下图所示,其运算本质上来说就是位移和替换。 但是非对称加密计算一般都比较复杂,比如 RSA,它里面涉及到大数乘法、大数模等等运算。其加解密可以用下面的公式来表示: 我们知道,幂运算的本质是乘法,乘法的基础单位是加法,也就是我们最常见的整数加。学过数字逻辑电路的同学想必都知道,在电路上实现“加法”比异或(XOR)要麻烦的多,况且后面还有一个模运算。因此非对称加密的速度自然而然是比不过对称加密的。 当然,我想另外还有一个原因是,AES 中的许多中间计算过程是可以事先计算好的。加密数据时许多中间过程可以直接查表,而不需要实时地计算。 通常情况下,非对称加密(如 RSA)的解密速度会比加密速度更慢,详情可参考Why is RSA decryption slow? 时空性 这里另外提一点,我们在学习算法的时候,一定听过时间复杂度和空间复杂度这两个名词。鱼和熊掌不可兼得,通常情况下,一个算法如果运行比较快,那么空间消耗相对来说就会高一些,反之亦然。因此才会有拿空间换时间的说法。 从上一节我们可以知道,非对称加密运行起来通常比对称加密慢,那么这时就有一个问题了,对于密钥的存储情况也是这样吗?非对称加密对于密钥的存储会比对称加密的密钥存储少吗? 答案是的确如此,在对称加密中,当信息量大的时候,要求密钥量也要足够大,需要每两个人之间都有一个密钥,也就是对于 n 个人来说,一共需要 个密钥才能确保两两之间对话不被其他人知道。 而在非对称加密中,每个人都有公钥和私钥,对于 n 个人来说,一共要 个密钥,就能保证两两之间对话不被其他人知道。 什么?你问我这个公式怎么来的?数学归纳法了解一下? 这么看,非对称加密虽然效率低下,但是存储成本低且相对安全,这也就解释了为什么非对称加密应用如此广泛了。 HTTPS 既然无法做到既安全又快速的加解密,那我们在实际使用时只能尽量达到一个动态的平衡。 因此我们在项目中通常会采用如下这种将两种加密算法结合在一起的使用方式:...

plainify

人人都是 LSP?—— 种子与文件下载的相爱相杀

前言 世界上根本没有 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 个人,这样当每个人都有自己的一部分副本后,就可以不用再找学霸本人要作业了,直接找其他拥有和自己副本不同的人索取然后互换资源即可。...

plainify

什么是SLA

软件的复杂性带来的问题 工作一年多了,在涉及到跨部门合作的时候往往就是最痛苦的时候,其实道理很简单,刚开始,我们的组织和产品如左图,一切都比较简单,为了业务的发展,通过人工快速吃到技术和产品的红利,很多事情人工能掌控,有事吼一声,开个会就解决了,也运转得很好。 但随着慢慢发展,组织和产品就如右图,彼此连接依赖越来越复杂,为了整体的高速运转,对每个部件的稳定性越来越高,越来越精密,发展到一定程度,人力已经无法掌控,任何一个组件出异常都有可能牵一发而动全身,影响全局。每个部件的稳定性和精密程度决定了整体的工程质量,也决定了整体的发展速度。 那么,为了解决这样的问题,我们可以采取什么样的手段? 从汽车的发展到软件系统的建设 他山之石可以攻玉,软件系统虽然日益复杂,但和汽车建造无本质区别。软件编写完成后是要交付出去的,这就跟一辆车建造好后是要卖给别人一样,闭门造车无疑是自嗨。那么车主在买车的时候会考虑什么? 把时钟拨回到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 + 后果...

plainify

什么是环境变量?

前言 在初学 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 变量中所指定的所有目录 了。...

plainify

从三本到985再到微软,他做了这些

对大多数人来说,在即将到达大学终点的时候通常会出现两条路,一条是步入社会就业,另一条是踏入高校读研深造。 往年,研究生复试和春招基本是同时进行的,这也就导致考研结束后很多人觉得自己没考好就直接放弃了复试。今年由于疫情的原因很多学校的复试都推迟到了 4 月底 5 月初,这就让很多 2、3 月开始工作的人,又多了一次选择的机会。 其实每年的这个时候都会有很多人讨论究竟是读研好还是工作好,不过毕竟没有人可以同时涉足两条道路,所以选择就变得格外重要。毕业之后我选择读研这条路,我的朋友寒食君也曾和我交流过并写了一篇文章《保研之路:从双非到南大》,现在很难确定这个决定对我来说是否正确,对其他人也同样如此。我们需要全方面的考量自己,从性格、抗压能力、未来期望、家庭条件等多个方面去考虑。 今天写这篇文章,不是为了告诉大家如何去选,而是想介绍一个我在读研期间认识的一个人,他的经历让我有些惊讶,完全可以拿去当考研成功的案例,这里给大家做选择时提供一些参考。他是我的舍友,本科来自于烟台大学材料科学工程中韩合作。高考时遭遇滑铁卢无奈去了这个三本,后来跨考考研时逆袭到南京大学读软件工程专业,读研时开始自学 Java,在这次的春招实习中斩获了网易、腾讯和微软的 Offer,最后选择了微软。从三本到 985 读研,再到斩获数个大厂 Offer ,这样的人,实在是少有。 最近一直有更新面经系列,本来也想记录下他的面试过程的,但是一想到他这励志的经历,便想请他谈谈自己这几年的心路历程,留下一点文字,给正在看文章的人一些指引和参考。下面我将会采用 Q&A 形式记录一些重要的内容。 为什么选择考研? 因为我本科是中韩合办的材料专业,所以专业课是由韩国语教授的。又因为我韩语不行,所以专业课都听不懂,说实话对我来说毕业都挺困难的。最简单的原因就是找不到工作,得想办法混个饭吃。放在面前的选择有三个,一是去韩企。我不会韩语,所以去不了。二是考公务员,我不知道你们了解山东不,在山东公务员首先很难考,其次像我这种不会喝酒的感觉也没啥前途。三就是考研了,也算是个没有办法的办法? 为什么考研选择了南京大学,而且还是跨考软件工程? 我高考考了两年,最后压本科线上的这个专业。本科挂了一万个科,在本科其实有想过修软件工程的双专业,也不是没报名,可惜第一天上课就和高数补考撞了。所以我就放弃了双专业(其实是因为懒得去了),去了补考(也没补过,最后重修了)。考研考了两年,第一年考南航差一分上线(吃鸡太好玩了,而且上线也不一定能录取),看到现在你肯定觉得我在装逼。其实我说这些是想表达,你想学习其实不一定来不及。第一年考研结束后,切实感受到了生活压力(同学大四回家生孩子了,导致没顺利毕业,爸妈帮他看孩子他也不好意思要钱,只能在我租的房子里睡沙发)。也好好想了想自己想要什么,所以决定好好冲个猛的,猛的冲不动就回家打工混吃等死。我认为我唯一比别人猛的方面,就是用搜索工具。我要散播第一个消费主义观点:**扔了百度,快想想办法用谷歌吧。**然后说几个关于考研择校的观点,不一定对,抛砖引玉: 招人越多的越好,这样如果你初试分足够高,复试就会特别稳。不用担心会因为奇奇怪怪的事情把你黑掉。而且招人足够多,分数线的波动就不会特别大。招三个人,有两个猛男一个关系户你考第三不也无能为力嘛。 如果你想考好学校,出身又很垃圾,那就直接冲猛的,在你能力范围内越猛的越好。这样可以一定意义上避免学历歧视,因为在好学校看来你们学历都挺垃圾的。(这是我的个人看法) 现在每个学校基本都能搞得到历年真题,尽量选变化不大的。学校出题变化大,对于猛男来说没啥,但是我们小弱鸡不能拿二十几岁的一年时光来赌这个。 想要完成以上的筛选工作困难并不大,特别是在你搜索工具用的得心应手的情况下。南大软院在我考研那年来看性价比是特别高的。你可以试着问问你的亲戚朋友,如果不在江苏省内的,可能很多人都不知道南大是个什么级别的学校,说不定你说南大很多人都以为是南开大学。但是这又是个极好的学校,所以很适合捡漏。又因为考英二数二(对高考英语 80 分且四级没过的我比较友好),会导致调剂困难(大部分学校都是考英一数一的),有一部分人就会因此不敢报名。而我的打算就是考不上就回家打工嘛,我也没想调剂,所以比较适合我。确定南大之后就是计算机院和软院之间的选择了,南大计算机院有国重,用屁股想想就知道对科研要求高,我啥也不会还跨考,本科也不好也没啥科研能力,别人咋也不可能要我。经过一通排除,我就选择南大的软工(当时在考研群里看了几个考人工智能院的大佬,第一届参考书都整不明白就敢冲,瑞思拜)。 然后是我考研的一点小心得。我太讨厌我家乡的生活了,导致我有无穷的动力来压迫我自己好好学习。考研第二年,真的是拼了命在学,不然像我这种啥也不会的不努力想考上南大肯定是不可能的。我要在这里散播我的第二个消费主义观点,**能花钱省时间的,价格不是太离谱就别犹豫。**跨考相较于不跨考的人来说,你的时间肯定是更宝贵的。保证时间,一是需要延长学习时间,二就是要在单位时间内学多一点。我完成这两点的方式如下: 建立起学习的工作流。 通过番茄钟来保证单位时间的效率,也可以有效统计每天的学习时间。 使用 anki 和思维导图来进行知识的复习,保证你学完的东西不会白学。 花钱让自己学习的效率更高。(别人售卖的,声誉良好的课和资料一定是有原因的,他至少花费了课程数倍的时间来沉淀知识,这也是我觉得为啥听话的孩子普遍吃亏少发展好的原因) 但是我认为学了两年是最重要的一点,说到底就是磨出来的。当然我也吃了一些亏,我经常会纠结哪个课最好,然后对比很久。方法总是第二步,开始学习才是最重要的第一步。找到一个差不多的尽快开始,会比花时间在比较上好很多。 你本科是材料专业的,考研时才接触的软件工程,现在研一也快结束了,有什么收获吗? 从一个啥也不会的小菜鸡到能写出来点能动弹的东西,还是挺有成就感的。 一个好的环境很重要,我能有这些大公司的面试机会就是吃了南京大学的红利。而我研一能有这些进步,主要在于身边有太多优秀的人。说实话第一次上课我是挺震惊的,虽然没有很多人在听课,但是所有人都在学自己的东西。这个公众号的主人也给了我很大帮助,我刚上学真是一头雾水啥也不懂。没他指路现在估计我还在慌着面试呢。披头士几个人都猛,但他们肯定不能都是天才吧。持续训练,刻意练习,才是我们这些笨逼的归宿。虽然现在我在他们之间还是最菜的,但是比较来看,说刚开学的时候我和他的编程能力差一百个我是不过分的,但现在估计也就差几个我了。 这次春招,你面试了哪些公司?最终选择了哪家呢? 面了一万个公司。你能想到的说的出名字的说不出名字的基本都面了,阿里、腾讯、头条、美团、网易、微软等等等等等等等。拿到 offer 的就只有微软、腾讯和网易,没拿到的就是都挂了。这其实还是一个笨逼多锻炼的故事,多试试总有运气好的时候吧。而且面试官的问题都是类似的,有一次我上午面网易,下午面腾讯,问的问题几乎一模一样。只要你在面试之间多总结,总能磨进去。最后还是选择了巨硬,第一是因为从小就想去巨硬,第二是因为比尔盖茨是我的爱豆,第三就是因为身体不太好,想养老发自内心。 可以简单说下,面试这些公司的过程吗? 大伙开始投阿里提前批的时候,我很慌,不敢投。导致错过了很多锻炼面试的机会,因为最开始是不进系统的。你一个部门挂了其实就只是那一个部门有你的记录,建议大伙还是阿里提前批多锻炼。小公司练手是个美好的想法,但是不切实际。为啥小公司是小公司,他们效率真的不太高,像有的同学阿里、腾讯或者头条都拿到 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....