《后端技术面试 38 讲》学习笔记 Day 01

《后端技术面试 38 讲》学习笔记 Day 01

学习目标

在2022年春节将至(半个月),适合在这个冬天里,温故知新。通过学习一门覆盖面较广的课程,来夯实基础,完善自己的知识体系,是一个很棒的选择。

总结性的学习,不求快,而求稳。这门课程的学习,我将跟随专栏的章节所讲,结合工作内容进行思考,记录并分享。欢迎大家对我的思考发起质疑,共同探讨。

开篇词 | 掌握软件开发技术的第一性原理

原文摘抄

  1. 建立起技术思维体系,掌握技术体系背后的原理,那么当你接触一个新技术的时候,就可以快速把握住这个新技术的本质特征和思路方法。

  2. “让我自由地从物理规则出发去思考问题,而不是迎合那些所谓的世俗智慧。”

  3. 如果你掌握了软件开发技术的第一性原理,那么当你为了解决某个新问题,去学习和研究一个新技术的时候,就算遇到了知识的盲点,也可以快速定位到自己技术体系的具体位置,进一步阅读相关的书籍资料

  4. 第一性原理是一种思维方式,一种学习方式,一种围绕事物核心推动事物正确前进的做事方式

心得体会

  1. 掌握技术的原理,才能更好理解技术的应用,巧妙的进行设计。
  2. 建立技术体系,才能让这幢“大楼”更为稳固,才能让上手更加的熨帖,才能巨人肩膀上再踏出一步。

01丨程序运行原理:程序是如何运行又是如何崩溃的?

原文摘抄

  1. 程序是静态的,安静地呆在磁盘上,什么也干不了
  2. 程序运行起来以后,被称作进程。
  3. 程序运行时如果需要创建数组等数据结构,操作系统就会在进程的堆空间申请一块相应的内存空间,并把这块内存的首地址信息记录在进程的栈中。
  1. 进程在生命周期中,主要有三种状态,运行、就绪、阻塞。
  2. CPU 以线程为单位进行分时共享执行
  3. 每个线程有自己的线程栈,所有的线程栈都是完全隔离的
  4. 多个线程访问共享资源的这段代码被称为临界区,解决线程安全问题的主要方法是使用锁
  5. 锁会引起线程阻塞,如果有很多线程同时在运行,那么就会出现线程排队等待锁的情况,线程无法并行执行,系统响应速度就会变慢。此外 I/O 操作也会引起阻塞,对数据库连接的获取也可能会引起阻塞。
  6. 如果阻塞的线程数超过了某个系统资源的极限,就会导致系统宕机,应用崩溃

心得体会

  1. 程序是一个文件,一个可以被操作系统理解,运行的文件。
  2. 程序运行的单位是一个进程,操作系统为进程在内存中分配堆空间、栈空间;分配CPU时间片执行代码指令。
  3. 程序变慢主要是锁、IO阻塞等竞争性的资源有限,过多的竞争导致“排队”阻塞。
  4. 程序奔溃是变慢的一个无穷大的体现。资源已经完全不足,操作系统、甚至硬件为了自保的壁虎断尾操作。

02丨数据结构原理:Hash表的时间复杂度为什么是O(1)?

原文摘抄

数据结构

  1. 数组是最常用的数据结构,创建数组必须要内存中一块连续的空间,并且数组中必须存放相同的数据类型。
  2. 不同于数组必须要连续的内存空间,链表可以使用零散的内存空间存储数据。
  3. Hash 表的物理存储其实是一个数组,如果我们能够根据 Key 计算出数组下标,那么就可以快速在数组中查找到需要的 Key 和 Value。一旦发生 Hash 冲突,只需要将相同下标,不同 Key 的数据元素添加到这个链表就可以了
  4. 数组和链表都被称为线性表,因为里面的数据是按照线性组织存放的.
  5. 栈就是在线性表的基础上加了这样的操作限制条件:后面添加的数据,在删除的时候必须先删除,即通常所说的“后进先出”。
  6. 队列也是一种操作受限的线性表,栈是后进先出,而队列是先进先出。
  7. 树则是非线性表

心得体会

  1. 为什么我们会关心O(1)、O(N)、O(nlogn)等算法复杂度,究其原因,是访问一次内存大约需要200-300个时钟周期(即比CPU慢这么多倍)。我们组织不同的数据结构,不同算法,根本原因还是要通过减少遍历来减少内存的访问。

  2. 我认为数据结构从内存的连续性可以分为两类,一类就是申请连续内存空间的数组演变的数据结构;一类是以类似链表,申请不连续的空间,通过记录下一个或上一个等关联元素内存地址来进行寻址的数据结构,例如树。

    对于不同的数据结构有不同的算法进行查找、插入、删除,其所需操作内存的复杂度(时间、空间)会有不同的体现。例如连续内存空间的数据结构,如果有逻辑可以计算内存偏移,那么访问就是O(1),但是插入或删除,都会因为连续性导致其后的元素需要进行移动,就适合读多写少的场景。

    我们要理解内存的访问,再去组织它的数据结构,来自己“定制”最合适的数据结构。

工作体验

  1. 正如这节课老师提到的:“事实上,我很难相信,如果这些基本数据结构没有掌握好,如何能开发好一个稍微复杂一点的程序”。我想起大三的时候与同学参与比赛时共同开发“贪吃蛇大作战”这样的手机游戏,看起来应该是个easy的程序,也就链表记录蛇的位置,长度。而我们遇到了游戏运行时间久了之后,游戏卡顿的问题,最终发现是遍历蛇、每条蛇吃食物等等操作,在这个数据大了之后遍历就很慢。最后针对这样的情况分析修改,来做性能优化。

    而在我的工作中,微服务体系的注册中心、配置中心、网关等中间件,其维护着整个公司以万为单位的微服务节点,其如何保持较低的延迟来响应都是基于精心设计的数据结构、网络模型的。

  2. 可能很多同学和我一样,也参与过很多业务系统的开发,觉得对于数组的应用也就是简单的ArrayList,那不知道有没有想过这里会不会用LinkedList更为合理呢?这些问题往往在开发环境会因为数据量不大而无差异,在生产上面对千万、上亿级的数据量,很有可能会形成一个耗时的慢接口,或者明显占用的内存过高导致OOM。

    其实,在我参与开发一个无码BI平台时,就遇到类似数据结构稍作优化,就能大有改善的场景:

    • 原本一张报表中用到的底表、列信息,使用两个不同的List(tableList、columnList)进行存储,当需要获取该表a中所有的列信息时,先从tableList中遍历获取tableA需要对columnList进行变量,进行判等操作,过滤出所有与tableA对应的列。然而,改为Map,则能以O(1)的时间复杂度进行读取。

03丨Java虚拟机原理:JVM为什么被称为机器(machine)?

原文摘抄

  1. Java 编译的字节码文件不是直接在底层的系统平台上运行的,而是在 Java 虚拟机 JVM 上运行,JVM 屏蔽了底层系统的不同,为 Java 字节码文件构造了一个统一的运行环境。

  2. 通过 Java 命令启动 JVM,JVM 的类加载器根据 Java 命令的参数到指定的路径加载.class 类文件,类文件被加载到内存后,存放在专门的方法区。然后 JVM 创建一个主线程执行这个类文件的 main 方法,main 方法的输入参数和方法内定义的变量被压入 Java 栈。

  3. 程序计数寄存器一开始存放的是 main 方法的第一行代码位置,JVM 的执行引擎根据这个位置去方法区的对应位置加载这行代码指令,将其解释为自身所在平台的 CPU 指令后交给 CPU 执行。

  4. 我们再回过头看 JVM,它封装了一组自定义的字节码指令集,有自己的程序计数器和执行引擎,像 CPU 一样,可以执行运算指令。它还像操作系统一样有自己的程序装载与运行机制,内存管理机制,线程及栈管理机制,看起来就像是一台完整的计算机,这就是 JVM 被称作 machine(机器)的原因。

  5. JVM垃圾回收:(标记)清理、压缩(整理)、复制

  6. 不同垃圾回收器的执行流程:

    《后端技术面试 38 讲》学习笔记 Day 01_第1张图片

  7. JVM 有很多配置参数,Java 开发过程中也可能会遇到各种问题,了解了 JVM 的基本构造,就可以帮助我们从原理上去解决问题。

  8. 执行引擎在执行字节码指令的时候,是解释执行的,也就是每个字节码指令都会被解释成一个底层的 CPU 指令,但是这样的解释执行效率比较差,JVM 对此进行了优化,将频繁执行的代码编译为底层 CPU 指令存储起来,后面再执行的时候,直接执行编译好的指令,不再解释执行,这就是 JVM 的即时编译 JIT。

心得体会

  1. JVM有自己的解释执行,作为中间层来屏蔽底层操作系统的接口不一致性,使得JAVA具有很高的可移植性。
  2. JVM有自己的内存规划、内存整理。帮助JAVA程序员从自己的内存管理中解脱出来。但是太烂的代码(内存泄露)可能也会导致虚拟机无法正常工作,自己还是要对内存管理有认知,才能写出安全的代码。
  3. 垃圾回收器的演变,也是时代的进步,从单核CPU到多核CPU,出现的并发垃圾回收器。G1回收器使用“分治”的思想,把内存划分成一块一块进行并发回收,应对大内存的垃圾回收,也是服务器内存逐渐“富裕”的表现。
  4. JVM作为java应用程序运行的基石,是java开发人员绕不过去的门坎。学习JVM能够让地基更夯实,运行更稳健。

工作体验

  1. JVM参数有许多,有一些的JVM规范中的,有一些是不同JVM发行版提供的正式特性,有一些是发行版提供的预览特性。常用参数的了解,使用,如何观察并分析,最终调节到合适的数值,是需要学习+实践来学会的。往往配合性能测试来进行参数的调整。
  2. 生产运行中,记得要让JVM输出GC日志,指定OOM的DUMP文件路径,如果条件允许,开启JMX也未尝不可。
  3. 生产的JVM故障排查分两种,一种是宕机,一种是运行时。
    1. 宕机的先看看有没有OOM日志,再看看日志文件最后的输出,有些还要看看是不是被系统kill掉,使用dmesg来查看。如果没有各种监控系统留痕的话,使用各种命令先备份一下当前机器运行的状态,例如netstat、top、iostat等等。如果节点数少,甚至只有一个节点,导致服务不可用的,抓紧时间重启。
    2. 运行时的话,看GC日志,是不是有FullGC,用jstack看看是不是有线程死锁。有条件的连上JMX看看一些关键的MXBean。运行时的故障种类可能比较多,还是要仔细分析的。一些线上的分析技巧、工具可能都需要了解。例如skywalking等系统查看Error的Trace;Arthas用来看具体一个类的反编译代码,模拟某个方法的请求等等。
    3. 故障需要改代码或者调参重启的,还是先分析清楚,在本地测试通过,再打个报告后去操作生产。例如重新hashcode,equals来解决内存泄露的,调整元空间最大值的,修改GC回收器的。生产无小事,快、准、稳很重要。

04丨网络编程原理:一个字符的互联网之旅

原文摘抄

了解网络通信原理,了解互联网应用如何跨越庞大的网络构建起来,对我们开发一个互联网应用系统很有帮助

  1. DNS、CDN、HTTP、TCP、LB(负载均衡)等等都是报文会经过的

  2. OSI 7层协议合并为5层模型: 物理层、数据链路层、网络层、传输层、应用层(会话层、表示层、应用层)

    《后端技术面试 38 讲》学习笔记 Day 01_第2张图片

    报文:

    《后端技术面试 38 讲》学习笔记 Day 01_第3张图片

  3. TCP三次握手

    App 和服务器之间发送三次报文才会建立一个 TCP 连接,报文中的 SYN 表示请求建立连接,ACK 表示确认。App 先发送 SYN=1,Seq=X 的报文,表示请求建立连接,X 是一个随机数;淘宝服务器收到这个报文后,应答 SYN=1,ACK=X+1,Seq=Y 的报文,表示同意建立连接;App 收到这个报文后,检查 ACK 的值为自己发送的 Seq 值 +1,确认建立连接,并发送 ACK=Y+1 的报文给服务器;服务器收到这个报文后检查 ACK 值为自己发送的 Seq 值 +1,确认建立连接。至此,App 和服务器建立起 TCP 连接,就可以进行数据传输了。

    《后端技术面试 38 讲》学习笔记 Day 01_第4张图片

心得体会

  1. 网络是互联网的基石,但是又是被层层封装,不会去细细触碰的。它标准,严格,是软硬件合作来完成工作的。
  2. 网络的一次请求,就像一次旅行,有许多不固定因素。需要拨打电话预定(建立连接),需要坐长途汽车(传输),还需要转站(路由),需要过安检(防火墙),兑换外币(加解密),实名认证(签名验证),累的很,还好都有旅行公司做好了一切安排。
  3. 应用层的协议还有许多,类似邮件的收发,都有不同的协议。了解当前应用系统使用的网络协议,对外的网络模型,中间经过的链路,也是排查问题很重要的依据。

工作体验

  1. 从这章节的报文层层添加协议头,而报文仅几个字节的示意图可以看出,添加的报文头长度基本可知,长度比较稳定,如果我们应用层的报文太小,着实浪费流量,携带的信息太少。所以我们在系统优化时,可以做一些聚合查询的接口,在一次报文中,将相关性比较大的信息一次性返回,减少报文请求的次数。
  2. 报文太小不好,那太大自然也不好,传输的时间过长,会导致用户页面一直在等待响应、传输,一直在“转圈圈“。要考虑用户的网络情况,是5G、4G还是WIFI,有没有可能网络情况不好是3G甚至更不稳定的网络。假设1MB的报文,在限速400KB的网络中,光传输都需要2.5秒了。综合实践建议,报文的大小控制在200KB以下为佳。
    • 有个生产大报文导致故障的经历,使用spring cloud gateway作为微服务请求的网关是背景。故障情况是网关频繁发生FullGC,导致许多RT要求较低的系统表现不正常。原因就是本部门的公共服务中心系统在与其他业务微服务同步用户、机构、权限等信息的接口时,聚合了全量不同信息在一个报文中,报文大小在20M,在定时同步的时候,多个微服务同时请求,导致这样的集中式的网关集群进入了FullGC的状态。这种情况就需要拆分接口,避免网关压力过大。
    • 报文太大最直接的性能问题除了传输,也遇到过被强制走网关的加解密。数兆大小的报文,经过这层网关,会多用1秒多的情况也会出现。
  3. 网络的传输过程其实对我们应用系统来说,并不透明。除了章节中提到的DNS、CDN等等,生产环境为了安全,还有层层网关,甚至网关会进行加解密、鉴权。不夸张的说,在银行这样的公司,外部互联网进入的请求,网关过个4-5层是很正常的。甚至内部系统间的请求,会分成web区、应用区、主机区等等,中间会有防火墙隔离。微服务之间的调用存在着鉴权。敏感数据会有加解密。种种原因,可能会导致我们内部请求一个接口仅几十毫秒,而用户则300毫秒起步了。
  4. 也遇到过业务应用系统FullGC时间过长,导致没有响应心跳包导致的告警。通过网络平台把当时的网络包下载下来,通过wireshark分析,确定准确时间段,对比系统日志、GC日志,才准确定位原因。
  5. 掌握nslook,tracert,ping,telnet,netstat等网络相关的命令是比较有效的。
  6. 顺便一提,ssh也是一个很有意思的命令。当服务器未安装telnet命令,难以去验证防火墙规则设置是否打开时,通过ssh命令,指定端口来发起请求,也是可以判断网络是否通的,因为都是通过TCP协议进行发起请求的。

05丨文件系统原理:如何用1分钟遍历一个100TB的文件?

原文摘抄

  1. 硬盘的形式主要两种,一种是机械式硬盘,一种是固态硬盘。

  2. 机械式硬盘的结构,主要包含盘片、主轴、磁头臂,主轴带动盘片高速旋转,当需要读写盘上的数据的时候,磁头臂会移动磁头到盘片所在的磁道上,磁头读取磁道上的数据。读写数据需要移动磁头,这样一个机械的动作,至少需要花费数毫秒的时间,这是机械式硬盘访问延迟的主要原因。

  3. 如果一个文件的数据在硬盘上不是连续存储的,比如数据库的 B+ 树文件,那么要读取这个文件,磁头臂就必须来回移动,花费的时间必然很长。如果文件数据是连续存储的,比如日志文件,那么磁头臂就可以较少移动,相比离散存储的同样大小的文件,连续存储的文件的读写速度要快得多。

  4. 固态硬盘则没有这种磁性特质的存储介质,也没有电机驱动的机械式结构。其中主控芯片处理端口输入的指令和数据,然后控制闪存颗粒进行数据读写。由于固态硬盘没有了机械式硬盘的电机驱动磁头臂进行机械式物理移动的环节,而是完全的电子操作,因此固态硬盘的访问速度远快于机械式硬盘。

  5. inode 中记录着文件权限、所有者、修改时间和文件大小等文件属性信息,以及文件数据块硬盘地址索引。inode 是固定结构的,能够记录的硬盘地址索引数也是固定的,只有 15 个索引。其中前 12 个索引直接记录数据块地址,第 13 个索引记录索引地址,也就是说,索引块指向的硬盘数据块并不直接记录文件数据,而是记录文件数据块的索引表,每个索引表可以记录 256 个索引;第 14 个索引记录二级索引地址,第 15 个索引记录三级索引地址

  6. RAID,即独立硬盘冗余阵列,将多块硬盘通过硬件 RAID 卡或者软件 RAID 的方案管理起来,使其共同对外提供服务。根据硬盘组织和使用方式不同,常用 RAID 有五种,分别是 RAID 0、RAID 1、RAID 10、RAID 5 和 RAID 6。

    在这里插入图片描述

    实践中,使用最多的是 RAID 5,数据被分成 N-1 片并发写入 N-1 块硬盘,这样既可以得到较好的硬盘利用率,也能得到很好的读写速度,同时还能保证较好的数据可用性。使用 RAID 5 的文件系统比简单的文件系统文件容量和读写速度都提高了 N-1 倍,但是一台服务器上能插入的硬盘数量是有限的,通常是 8 块,也就是文件读写速度和存储容量提高了 7 倍。(所有数据的bit位,逐位进行异或,得到的就是校验位。 如果丢失部分数据,用校验数据和其余数据逐位进行异或运算,可到丢失部分数据。)

  7. HDFS:NameNode 负责整个分布式文件系统的元数据(MetaData)管理,也就是文件路径名、访问权限、数据块的 ID 以及存储位置等信息,相当于 Linux 系统中 inode 的角色。HDFS 为了保证数据的高可用,会将一个数据块复制为多份(缺省情况为 3 份),并将多份相同的数据块存储在不同的服务器上,甚至不同的机架上。这样当有硬盘损坏,或者某个 DataNode 服务器宕机,甚至某个交换机宕机,导致其存储的数据块不能访问的时候,客户端会查找其备份的数据块进行访问。

心得体会

  1. 看到上百T我就猜是HDFS,毕竟还没听过哪个单机这么玩的,普通单机操作系统寻址能不能到100TB还需要再计算一下。
  2. 冗余是很必要的一件事,RAID 5通过异或生成的校验位可以还原任意一块磁盘的损坏,这个设计真的是精妙啊!
  3. 引入HDFS之后还要考虑数据倾斜的问题呢。(分布式的大数据都需要考虑)

工作体验

  1. 当前没有单一这么大的文件读取过,基本都是大数据框架进行处理了。
  2. 大文件读取记得使用随机读写,不要把整个文件读取到内存中。

06丨数据库原理:为什么PrepareStatement性能更好更安全?

原文摘抄

  1. 应用程序提交 SQL 到数据库执行,首先需要建立与数据库的连接,数据库连接器会为每个连接请求分配一块专用的内存空间用于会话上下文管理
  2. 一个 SQL 提交到数据库,经过连接器将 SQL 语句交给语法分析器,生成一个抽象语法树 AST;AST 经过语义分析与优化器,进行语义优化,使计算过程和需要获取的中间数据尽可能少,然后得到数据库执行计划;执行计划提交给具体的执行引擎进行计算,将结果通过连接器再返回给应用程序。
  3. 执行引擎是可替换的,只要能够执行这个执行计划就可以了。
  4. 一个是 PrepareStatement 会预先提交带占位符的 SQL 到数据库进行预处理,提前生成执行计划,当给定占位符参数,真正执行 SQL 的时候,执行引擎可以直接执行,效率更好一点。
  5. 另一个好处则更为重要,PrepareStatement 可以防止 SQL 注入攻击。
  6. 数据库索引使用 B+ 树,我们先看下 B+ 树这种数据结构。B+ 树是一种 N 叉排序树,树的每个节点包含 N 个数据,这些数据按顺序排好,两个数据之间是一个指向子节点的指针,而子节点的数据则在这两个数据大小之间。
  7. 数据库索引有两种,一种是聚簇索引,聚簇索引的数据库记录和索引存储在一起。MySQL 数据库的主键就是聚簇索引,主键 ID 和所在的记录行存储在一起。
  8. 另一种数据库索引是非聚簇索引,非聚簇索引在叶子节点记录的就不是数据行记录,而是聚簇索引,也就是主键。
  9. 这种通过非聚簇索引找到主键索引,再通过主键索引找到行记录的过程也被称作回表
  10. 数据库实现事务主要就是依靠事务日志文件。
  11. 此外,像 MySQL 数据库还有 binlog 日志文件,记录全部的数据更新操作记录,这样只要有了 binlog 就可以完整复现数据库的历史变更
  12. 对于一般的应用开发者而言,全面掌握关系数据库的各种实现细节,代价高昂,也没有必要。我们只需要掌握数据库的架构原理与执行过程,数据库文件的存储原理与索引的实现方式,以及数据库事务与数据库复制的基本原理就可以了。

心得体会

  1. 数据库就像操作系统一样,是数据结构的集大成者。作为业务开发,很多时候了解SQL的执行过程,才能写出更合适的SQL,更好的利用数据库。
  2. Oracle也有闪回操作,类似Mysql的binlog日志文件,用于浮现数据库的历史变更。
  3. AST的语法树优化的确是每种数据库都不尽相同,靠着不同的关系代数,使得生成的执行计划更加贴近于它本身的存储的数据结构。

工作体验

  1. 工作中,也有观察过apache kylin的SqlNode生成过程,了解calcite框架的使用。对自身的无码BI系统建设有较大益处。

  2. 不同的数据库因为底层储存不尽相同,索引方式也不相同,使得SQL的编写,也需要根据数据库特性来编写。例如:

    -- 1
    select count(a), sum(b), c from table_a where d = 1 group by c;
    -- 2
    select a, b, c from table_a where d = 1;
    

    这样的两条SQL,在oracle或mysql等OLTP的数据库中,第1条会明显慢于第2条。毕竟,第一条还要做聚合计算。但是在apache kylin这样的OLAP数据库中,第1条会更加快。其预计算的特性,会将索引的度量都计算完成,存储在cube中,效率会更高。

  3. sql的优化,并不是有固定公式的,查询都是要根据不同数据库的存储特征,查询引擎来写适合它的语句。

07丨编程语言原理:面向对象编程是编程的终极形态吗?

原文摘抄

  1. 软件架构师必须站在一个很高的高度去审视自己软件的架构,去理解自己的工作在更宏大的背景中的位置和作用,才能构建出一个经得起时间考验的软件系统。
  2. 但是面向过程的复杂性随着软件规模的膨胀以更快的速度膨胀。于是很多大型软件的开发过程开始失控,最终以失败告终,人们遇到了软件危机。
  3. 事实上,现实中的面向对象编程几乎从未实现人们期望中的面向对象编程。上面举的 Java 的 User 对象示例就是典型,这是一个我们经常见到,却又非常不面向对象的对象。这个对象只有属性,没有行为,现实中的 User 对象显然不是这样。
  4. 面向数据的编程需求越来越多,能够更好迎合这一需求的编程模型开始得到青睐,比如函数式编程。
  5. 如何更好地利用 CPU 的多核以及分布式集群的多服务器特性,必须是软件编程以及架构设计时需要考虑的重要问题,软件编程越来越多需要考虑机器本身,相对应的,反应式编程得到越来越多的关注。

心得体会

  1. 计算机语言的发展也是有重心的,不同的语言会适合不同的场景。例如提到的函数式编程更适合数据,反应式编程更适合资源的利用。就好像kyligence开源的byzer,其使用SQL语言完成etl,流程编排,就十分适合分析的场景。豁然开朗,语言也只是工具!

工作体验

  1. 工作体验并不多,技术栈主要在java,也写过一点JS。JS的语法要求明显更弱,相比JAVA。从编程上来说,相对更随意,十分符合“你就说。能不能用吧”。

答疑丨Java Web程序的运行时环境到底是怎样的?

原文摘抄

文中这个故事大概发生在 2009 年,整整十年前,那个时候互联网还不像今天这样炙手可热,提供的薪水也不像今天这样有竞争力,也没有 BAT 这样的专有名词指代所谓的互联网巨头。那个时候,计算机专业优秀的毕业生向往的是微软、Oracle、IBM 这样的外资 IT 巨头,退而求其次,国内好的 IT 公司是联想、用友这些企业。事实上,那个时候在技术研发能力上,互联网公司的技术能力也是落后传统企业的,阿里巴巴最核心的数据存储依赖的是 IBM、Oracle、EMC 的解决方案,即所谓的 IOE。

我个人感觉,互联网公司的崛起大概是在七八年前,移动互联网开始出现,互联网的渗透率得到加速,BAT 逐渐开始成为家喻户晓的名字,名气大涨。其次,经过前面时间的积累,互联网企业主导的各种分布式技术、大数据技术、移动互联网技术、云计算技术的风头超过传统 IT 巨头,阿里巴巴开始去 IOE,打造自己的云计算平台,成为先进技术的代表者;最主要的还是互联网企业盈利能力大幅增加,能够提供市场上更有竞争力的薪水和股票。

但是事情真正的吊诡之处还不在这里,当今这些互联网大厂的核心技术和业务模式在十几年前就已经奠定了,经过几年的摸索,大概在七八年前开始稳定成熟。也就是说,互联网企业的技术实力和商业能力是在这些企业还默默无闻的时候就发展起来的,而在这些企业成为明星之后,并没有什么突破性的进展。想想这些所谓的互联网大厂,最近几年,并没有什么值得称道的商业模式创新和技术创新。

也许你会发现,你可能不需要追逐当前所谓的热门技术,而应该好好想想需要为自己的未来准备些什么。

心得体会

  1. 移动互联网的出现也是基于无线网络的基建,智能手机的普及。随后大量的人开始“弯道“进入互联网,让许多不用电脑的人有足够的时间打开手机就进入互联网。也是互联网最重要的一波红利。可能真的是这个社会造就了互联网公司,而不是互联网公司改变了社会。在社会的大趋势下,相应的技术就会蓬勃发展。
  2. 未来准备做什么呢?我还没有想好,总之做一项对社会有益,对人类有益的工作吧。如果可以改变社会多一点点,那就更好了。

工作体验

  1. 从工作的角度来看技术的变更,那完全就是业务需求希望往哪边走。做无码BI平台,就需要有足够的抽象意识,对SQL有够深入的了解,对OLAP的各种数据库特性有足够的了解。而明年要开始做ETL平台相关的,就需要了解HADOOP、SPARK等大数据的中间件。而中间不变的一点,就是如何更好的去用好数据,更好的分析,发现异动、提供决策。这是围绕业务打造的一个生态。而随着这个生态逐渐的完善,从原始数据到可提供决策的指标,其时间会缩短,这就是进步,改变。

你可能感兴趣的:(后端技术面试38讲--学习笔记,面试,学习,java)