当前位置:   article > 正文

Java面试必考点第10讲:架构的演进之路与前沿技术_架构演进 面试

架构演进 面试

本课时会讲解分布式系统架构以及面试中做项目介绍的技巧,重点有如下三部分。

  1. 介绍系统架构的演进:包括微服务架构、云原生以及业界最新趋势 ServiceMesh。

  2. 讲解微服务的基础知识点:Docker 和 K8s。

  3. 面试技巧,教你如何更有效地做项目介绍。

系统架构演进

首先以演进的方式来了解不同的系统架构。

单体架构

最简单的系统架构是单体服务,如下图所示。


      

一个项目中的多个服务,混合部署在一个进程内,服务之间的交互都是通过进程内调用完成的,正如图中 Service 之间的红色箭头所示。这样做的好处是可以快速开发、部署服务,服务之间调用的性能也最好。

 

当然,这种架构缺点也非常多,比如:

  • 随着业务的增长,项目越来越臃肿;

  • 服务之间因为 JAR 包引用导致频繁的依赖冲突;

  • 服务资源变更困难,因为一个服务可能被多个不同的业务引用,升级资源需要多个业务方同时升级;

  • 因为不同业务方都可以直连服务的数据资源,这个架构也存在明显的数据安全风险;

  • 修改代码后回归困难、架构难以调整等等。

以上所有问题都是因为服务耦合在一起导致的。在服务规模不大的情况下,比较适合采用单体架构,方便快速迭代。但是当服务规模变大时,单体架构就不是一个好的选择。

微服务架构

当服务的规模变大时,为了解决服务耦合的问题,出现了 SOA 就是面向服务架构,它的起源是为了解决企业应用问题,随着不断演进,发展到目前业界普遍采用的微服务架构,微服务架构如下所示。

微服务架构的思想就是让服务尽可能做到高内聚、低耦合,不同的服务单独开发、单独测试、单独部署。服务之间通过 RPC 或者 HTTP 进行远程交互,如图中的蓝色加粗箭头所示。

 

微服务架构解决了单体架构的耦合问题,但同时也带来了新的问题。因为服务部署在不同的进程或服务器中,要使用服务前需要先找到服务,即所谓的服务发现。

 

一般微服务使用两种发现方式,一种是前面课程介绍过的 RPC 方式,通过注册中心进行服务的注册和订阅,来完成服务发现,比如图中间灰色的 Registry 模块。这种方式由服务的调用端获得到全部可用服务节点,由 Client 侧进行负载均衡,调用服务。另外一种是通过 HTTP 协议调用服务端提供的 RESTful 接口,这种方式不需要 Client 侧做服务发现,而是在 Server 端通过 Nignx 这样的反向代理来提供 Server 侧的负载均衡。

 

不论哪种方式,服务的交互都从进程内通信变成了远程通信,所以性能必然会受到一些影响。此外由于很多不确定性的因素,例如网络拥塞、Server 端服务器宕机、挖掘机铲断机房光纤等等,需要许多额外的功能和措施才能保证微服务流畅稳定的工作。前面在 Spring Cloud 内容中提到的 Hystrix 熔断器、Ribbon客户端负载均衡器、Eureka注册中心等等都是用来解决这些问题的微服务组件。

CAP 原则与 BASE 理论

在微服务架构中,有必要了解一下分布式系统中的 CAP 原则与 BASE 理论。如下图所示,CAP 原则指的是在一个分布式系统中,Consistency 一致性、 Availability 可用性、Partition tolerance 分区容错性,这三个特性最多只能同时满足两个,三者不可兼得。


      

其中一致性指所有节点在同一时间的数据完全一致;可用性指任何时候对分布式系统总是可以成功读和写;分区容错性是指当某些节点或网络分区故障的时候,仍然能够提供满足一致性和可用性的服务。

 

既然无法同时满足三个特征,那就会有三种取舍。

 

第一个选择是 CA,就是放弃分区容错,这也就等同于放弃了分布式系统,所以 CA 只存在于单机系统。

 

第二个选择是 CP,也就是选择强一致和分区容错,允许极端情况下出现短时的服务不可用。采用 CP 原则实现的分布式系统比如 ZooKeeper。ZooKeeper是一个分布式协调系统,强一致性是 ZK 的主要目标,允许出现短时的系统不可用。也正是因为这个原因,ZK 其实并不适合用来做微服务的注册中心。其他选择 CP 实现的系统还有 Consul、etcd 等。

 

第三个选择是 AP,也就是选择分区容错和高可用,允许数据出现短时间不一致。采用 AP 原则的分布式系统有 Eureka、Nacos。在服务注册的场景,短期的不一致一般不会对服务交互产生影响,因此采用 AP 原则的注册中心才是微服务比较适合的选择。

 

然后,介绍一下 BASE 理论,如上图底部的词汇所示,BASE  是指 Basically Available 基本可用,Soft-state 软状态,Eventual Consistency 最终一致性,它是对 CAP 中一致性和可用性权衡的结果。BASE 的核心思想是即使无法做到强一致性,也可以根据系统特点,采用适当的方式达到最终一致性。

云原生服务

继续讲解系统架构的演进。微服务架构的思路是服务解耦合,这会导致一个大的业务拆分成众多小的服务,每个服务的部署需要考虑单点问题,需要多机房多节点部署,会造成系统资源的浪费。

 

另外在服务扩容时需要重新整理服务运行依赖的环境,对微服务的普及有一定阻碍。容器化技术把服务的运行环境进行打包管理,解决了服务扩缩容时对运行环境的管理问题以及服务器的利用率问题。因此随着容器技术逐渐成熟,微服务架构也快速普及。

 

云原生架构由微服务组成,它不是一种业务系统架构,而是一种能够快速、持续、可靠、规模化地交付业务服务的模式。

 

如下图所示,图上部列出了云原生的三个特征:

  • 容器化的微服务,这是云原生的主体;

  • Devops,是对微服务的动态管理;

  • 持续交付能力,这是云原生的目的。


      

云原生服务需要底层的云服务提供 IaaS 基础设施或者 PaaS 平台设施来运行,IaaS 可以理解为提供了服务器资源,PaaS 平台可以理解为提供了运行环境。

 

常见的实现方式有两种:自建的私有云和云厂商提供的公有云。公有云比如阿里云、AWS、腾讯云等等,像新浪微博内部使用的是私有云与公有云结合的混合云模式。

 

接下来看云原生应用开发的最佳实践原则:12 要素,如下图所示。


      

12 要素定义了设计 SaaS 应用时需要遵循的一些基本原则,SaaS 是软件即服务的缩写,通过云原生应用来提供服务。  

 

第 1 个要素是基准代码,是指代码由版本管理工具来管理,一个应用只有一份基准代码,运行时有多个的部署实例。

 

第 2 个要素依赖,是指要在应用中显示的声明依赖,方便服务进行构建。

 

第 3 个要素配置,指要在环境中存储配置,而不是写在代码配置文件中。也就是说,配置与代码要分开管理,从代码外部进行加载,例如测试环境的配置、仿真环境的配置以及生产环境的配置都应该从对应的环境中进行加载。

 

第 4 个要素后端服务,是指要把依赖的后端服务统一看作资源来对待。不论是 DB、缓存还是 HTTP 服务。

 

第 5 个要素是构建、发布、运行,是指要严格区分应用的构建、发布、运行这三个步骤,并且必须按顺序进行。

 

第 6 个要素进程,是指应用以一个或多个进程运行,要保证应用的无状态性。

 

第 7 个要素端口绑定,是指不同的应用使用不同的端口提供服务。应用与端口是绑定的,不是指具体的某个端口号,而是指一旦服务启动确定了端口,那么这个端口就能够提供对应的服务,直到应用进程停止。

 

第 8 个要素并发,是指应用进程之间可以并发处理,因此可以通过多进程方式进行水平扩展。

 

第 9 个要素易处理,是指应用应该容易被管理,可以通过优雅停机和快速启动,构建最健壮的服务。

 

第 10 个要素开发/生产等价,是指要保证在开发、预览、生产等不同环境下的应用,尽可能一致。

 

第 11 个要素日志,是指要合理记录应用的运行日志,并把日志当作一种事件流来对待,方便对日志的收集和处理。

 

第 12 个要素管理进程,是指要把后台管理任务当作一次性进程来运行,而不是常驻后台进程的方式。

 

以上 12 要素是对设计云原生服务的指导原则,在实际项目中可以结合实际业务场景进行架构设计,不一定完全照搬。

Service Mesh

云原生应用是目前大部分互联网公司的服务架构推进方向,那么下一代的服务架构是什么样呢?这里介绍一个最新的服务化趋势,它离实际应用可能还有些遥远,我们可以静待它的发展。

 

Service Mesh 是 2017 年逐渐在国内进入大家视野的一种架构方式,被誉为下一代的微服务。Service Mesh 在微服务的基础上引入了一个 Sidecar 边车的概念,如图中左下方的放大图所示,每个服务会伴生着部署一个 Sidecar,服务之间的交互不再由服务自身来完成,服务所有的出、入请求都交由这个 Sidecar 来进行处理,通过管理平面对所有的 Sidecar 进行统一管理,由 Sidecar 来实现服务发现、负载均衡、流量调度等能力。


      

目前最有代表性的 Service Mesh 开源实现,是由 Google、IBM、Lyft 三家一起维护的 Istio,有兴趣的话可以持续关注,这里就不详细展开了。

 

那么 Service Mesh 与微服务的区别是什么呢?Service Mesh 又可以解决哪些问题呢?如下图所示。


      

微服务的出现是为了解决多个服务之间耦合的问题,如图中绿色的竖线,就是微服务架构做的事情,把 Service A、B、C 进行了解耦,服务单独部署、单独管理。这时每个服务都需要实现例如服务发现、服务的远程交互、交互过程中的负载均衡、高可用策略、服务熔断等等一系列的功能,这些功能与服务自身的业务逻辑没有任何关系。

 

Service Mesh 的思路是把业务逻辑与业务无关的功能进行解耦,如图中红色的线,对服务进行横切,把与服务交互相关的功能从服务中剥离出来,统一交给 Sidecar 去实现,让服务更聚焦于业务逻辑,提高研发效率。同时由于功能相对独立,Sidecar 可以更专注于服务的交互与管理,更方便实现极致的功能与性能。

 

所以,Service Mesh 不是一个全新的技术,它对业务与服务交互、管理进行了拆分,提供统一、强大的服务管理能力,是在微服务基础上的演进。

 

另外,Service Mesh 由于使用独立的 Sidecar 进程,天然适合为不同语言的服务提供统一的服务治理能力,因此跨语言服务治理也是 Service Mesh 的一个重要特点,像微博基于 Motan 研发的 Weibo Mesh,初衷就是为了解决内部不同语言之间服务化的问题。

 

由于引入了额外的 Sidecar,Service Mesh 的架构复杂度更高,也会带来额外的可用性和性能问题,这也是 Service Mesh 架构需要努力解决的问题。

架构设计的意义

通过了解系统架构的演进,我们发现,从单体架构到微服务架构,实现了服务之间解耦,但带来了额外的服务发现与交互问题;从微服务到 Service Mesh,实现了业务与服务治理功能的解耦,但是引入了额外的可用性和性能问题,架构复杂度也随之提高。那么这样做的意义在哪里?

 

系统架构的设计从来就是一个权衡的艺术,很多情况下,我们只是让问题进行了转移,方便对问题进行集中整治和处理,让服务更聚焦业务研发,不同的功能就交给专门的组件来处理,正所谓术业有专攻。通过架构的演进,虽然当下没有消灭复杂度,但可以成功的让问题变的透明化,变的业务无感知,提升服务整体的开发效率与扩展能力,拓宽服务能力的上限。

容器化基础

微服务之所以能够快速发展,很重要的一个原因就是:容器化技术的发展和容器管理系统的成熟。所以接下来学习微服务架构的基础,容器化技术 Docker 和容器集群管理系统 Kubernetes。

Docker 作用

Docker 的作用主要是快速的构建、部署、运行服务,通过服务镜像能够为服务提供版本管理。

 

通过容器化技术可以屏蔽不同运行环境的差异,让服务在任何 Docker 环境中运行,就像 Java 的一次编译到处运行。

 

Docker 是轻量虚拟化技术,可以在一台宿主机上运行多个服务,对运行的服务之间进行了有效的隔离,提高宿主机的资源利用率。

Docker 特点

  1. 开源,意味着可以免费使用 Docker 容器技术。

  2. 基于 LXC 实现的轻量虚拟化,Docker 容器直接运行进程,不需要模拟,运行效率非常高。

  3. 能够支持大规模构建。

  4. Docker 的架构十分灵活,可扩展不同的实现,例如支持不同存储驱动实现。

  5. Docker 提供可视化 UI,管理非常简单。

Docker 主要概念
  1. 镜像,就是服务代码和运行环境的封装,服务的版本管理就是通过镜像来实现的,镜像是部署的基础。

  2. 容器,就是 Container,容器是基于镜像的服务运行状态,可以基于一个镜像运行多个容器。

  3. 守护进程是运行在宿主机上的管理进程,用户通过 Client 与守护进程进行交互。

  4. 客户端是用来和守护进程交互的命令行工具,也可以通过 Socket 或者 RESTful API 访问远程的 Docker 守护进程。

  5. 镜像仓库,类似我们的 Git 代码仓库,镜像仓库用来保存、管理不同服务不同版本的镜像。服务部署时会从镜像仓库拉取对应版本的镜像进行部署。

Docker 实现原理

Docker 是通过对不同运行进程进行隔离来实现虚拟化,主要利用三种方式来实现服务的隔离,如下图所示。

      

首先是利用 Linux 的 Namespace 命名空间,来隔离进程之间的可见性,不同的服务进程彼此属于不同的 Namespace,互相无法感知对方的存在。

 

Docker 实现了 Host、Container、None 和 Bridge 四种网络模式,默认使用 Bridge 桥接模式。每一个容器在创建时都会创建一对虚拟网卡,两个虚拟网卡组成了数据的通道,其中一个会放在容器中,另一个会加入到 Docker0 的网桥中。Docker0 网桥通过 iptables 中的配置与宿主机上的网卡相连,所有符合条件的请求都会通过 iptables 转发到 Docker0 并由网桥分发给对应的容器网卡。为了防止容器进程修改宿主机的文件目录,Docker 通过改变进程访问文件目录的根节点,结合 Namespace 来隔离不同容器进程可以访问的文件目录。

然后,通过 Namespace,Docker 隔离了进程、网络和文件目录,但是在进程运行中的 CPU 和内存等还是共享状态。Docker 通过 Control Groups 也就是 Cgroups 来对进程使用的资源进行限制,包括 CPU、内存和网络带宽等。

 

那么,Docker 是如何把镜像运行起来的呢?Docker 的镜像是分层结构,例如一个服务镜像可以由操作系统层、基础环境层、Web 容器层、服务代码层,层层依赖构成。通过 UnionFS 就是联合文件系统把 Image 中的不同分层作为不同的只读目录,而 Container 是在只读的镜像目录上创建的可读可写的目录,通过这种方式来把镜像运行起来的。Docker 提供了 AUFS、Overlay、Devicemapper、ZFS 等多种不同存储驱动实现。

Kubernetes 作用

Kubernetes 也叫 K8s,因为 K 与 s 之间一共有 8  个字母。K8s 是一个容器集群管理系统,不是一个 PaaS 平台,PaaS 平台是可以运行在 K8s 之上的。

 

K8s 的作用是进行容器集群管理,它只针对容器管理,不部署源码不编译应用。它能够实现服务容器的自动部署与按指定条件进行自动扩缩容服务,来实现对应用的管理,支持应用的负载均衡、滚动更新、资源监控等等。

Kubernetes 特点
  1. 可移植,支持在公有云,私有云,混合云中运行;

  2. 可扩展,K8s 采用模块化实现方式,插件化的架构,可挂载,可组合;

  3. 自动化,支持服务的自动部署,自动重启,自动复制,自动伸缩。

Kubernetes 重要概念

K8s 中的概念非常的多,这里列出了比较重要的几个。

 

K8s 是容器集群管理系统,容器首先需要运行在宿主机上,因此,K8s 首先要管理宿主机集群,K8s 分为 Master 节点和 Node 节点,也叫 Worker Node。

 

Master 负责管理节点,管理 K8s 集群。Master 协调集群中的所有行为/活动,例如应用的运行、修改、更新等。

 

Node 节点用来运行容器。Node 上可以运行多个 Pod,Pod 是 K8s 创建或部署的基本单位,Pod 中可以运行多个 Container,一个 Container 就是一个运行中的服务镜像。

Pod 中的 Container 共享网络与存储。

 

Service 是 K8s 中的一个逻辑概念,通过对不同的 Pod 添加标签,来划分为不同的 Service。

 

Deployment 表示用户对 K8s 集群的一次更新操作,可以是创建一个新的服务,更新一个新的服务,也可以是滚动升级一个服务。

Kubernetes 架构

下图是 K8s 架构图,图左侧绿色的模块代表 Master 节点,右侧蓝色的模块代表运行容器的Worker Node 节点。

      

先来看 Master 节点中的架构,灰色的部分是 Master 中的模块,其中 API Server 是用户对 K8s 中资源操作的唯一入口,创建应用部署、管理部署状态等都需要通过 api server 进行。API Server 提供了认证、授权、访问控制、API 注册和发现等机制。

 

Controller Manager 负责维护集群的状态,比如故障检测、自动扩展、滚动更新等,Controller Manager 包含多个可以扩展 Controller,例如 Node Controller 负责初始化 Node 节点,获取运行中的 Node 信息、Route Controller 负责配置集群间通信的路由信息、Service Controller 负责监听服务创建、更新、删除等事件来调整负载均衡信息等等。

 

Scheduler 负责资源的调度,按照预定的调度策略选择哪个 Pod 运行在哪个节点上。

 

另外图下方的绿色模块是用来保存整个集群的状态的 etcd。

 

图最左侧的 kubectl 是用于运行 K8s 命令的管理工具,kubectl 与 API Server 进行交互,通过 API Server 下发对 K8s 集群的指令。

 

再来看图右侧的 Worker Node。刚才介绍概念时提过,Node 用来运行应用容器,所以 Node 中必须要有一个容器运行时,可以是 Docker,也可以是其他的容器技术,例如 Rkt。

 

Node 中部署应用时,每个应用都由一个 Pod 组成,可以把 Pod 看作一个虚拟服务器,上面可以运行一个或多个 Container 容器。当应用服务需要多个进程共同协作时,可以把这些协作的镜像打包放在一个 Pod 中,共享 Pod 的存储和网络。比如 istio 中的 Sidecar 代理模式,就是通过在服务的 Pod 中注入一个 Sidecar 镜像来实现与服务 IP 绑定,进行流量控制的。

 

看到右面图中灰色的两个 Node 模块,kubelet 负责与 Master 通信,它周期性地访问 APIcontroller 进行检查和报告、执行容器的操作,维护容器的生命周期,也负责 Volume(CVI)和网络(CNI)的管理。

 

kube-proxy 处理网络代理和每个容器的负载均衡,它通过改变 iptables 规则来控制在容器上的 TCP 和 UDP 包。

 

K8s 把所有被管理的资源看作对象,对资源的管理就变成了对对象属性的设置。K8s 对对象的配置采用 YAML 格式进行描述。K8s 中的对象概念非常多,大致可以分为四类:

  • 资源对象,例如 Pod、Job;

  • 配置对象,例如 Node、Namespace、Service;

  • 存储对象,例如 Volume、PresidentVolume;

  • 策略对象,例如 SecurityContext、ResourceQuota、LimitRange 等等。


如果感兴趣,可以在课后练习。比如最简单的,可以在单机环境中,使用 Minikube 来部署 K8s 进行练习。

考察点与加分项

考察点

系统架构主要看一个人的综合能力和发展潜力怎么样,考察点有这几个方面:

 

第一,要对分布式架构有自己的理解。比如系统可用性、扩展性,比如故障的应对方法,包括熔断、容灾、流量迁移、多机房多活;再比如架构设计中的解耦合等等。

 

第二,要了解系统架构优化的常用方法。比如:并行、异步、水平扩展和垂直扩展、预处理、缓存、分区(Sharding)等等。

 

第三,会考察对负责的工作了解程度、是否有责任⼼。如果连自己负责的服务的部署规模,调用量级都不清楚,怎么能有很强的责任心呢?

 

最后一个是解决问题能力,是否能灵活运用各种知识。

加分项

加分点主要在于表现出面试者的学习能力和思考能力。

 

第一个,了解业界最新趋势,比如 Service Mesh 的思路和要解决的问题。

 

第二个,在介绍项目时,如果有不同方案的选型或对比会更好。比如在介绍项目架构时,有两个方案,一个是同步方案,一个是异步方案,这两个方案各有什么优缺点,最后结合业务场景、实际需求、请求量级 选择了某一种。

面试技巧

介绍项目

面试时,一定会遇到介绍项目这个问题。我见过的大多数人在里表现的并不好:要么讲不清楚项目的结构与交互流程;要么不能理解项目架构为什么要这样设计;要么没有思考过项目存在哪些问题,有哪些可以改进的地方。不仅是针对面试,在工作中我们更应该搞清楚这些问题,尤其是工作 1~3 年的工程师们。

 

那么,在面试中如何更好地介绍自己负责的项目?如下所示,图中这些方法是根据面试考察点总结的,并且会提示每个方法要重点体现哪些能力。


      

第一步,要简单交代项目背景,让面试官可以快速进入到项目上下文,更容易理解项目架构。一般采用 STAR 法则来进行介绍:

  • Situation 介绍项目背景,比如这个项目是研发一个短视频 APP,配合公司主客户端来交叉提高用户量与活跃度;

  • Task 介绍自己的任务,比如我在这个项目中负责后端服务的架构设计与研发;

  • Action 介绍自己做了哪些工作,比如当时用了 2 周时间做架构设计,4 周时间做研发,2 周时间测试上线;

  • Result 介绍结果,这个也是大部分人容易忽视的部分,比如项目上线后 2 个月用户数 100w,后端服务接口总量峰值 50000qps,主要接口服务 SLA p99 小于 50ms。


注意背景介绍是为后面详细介绍做铺垫,简洁明了即可。这一步主要体现你的表达能力。

 

第二步,重点介绍项目的架构,这也是面试官最想了解的部分。

 

务必要结合架构图、交互流程图来介绍,避免对一些关键问题理解歧义。架构图要注意边界清晰,就是你的服务与其他依赖的外部服务之间的边界,以及你服务内部模块之间的边界都要描述清晰。这有利于你下一步介绍自己做了哪些内容。这一步要体现出你对项目架构的理解。

 

第三步,介绍你在这个项目中具体做了哪些内容,例如我设计了整个架构,或者我实现了架构图中的某几个模块。注意这一步是你面试的绝对加分点,必须要把握住。

 

这里要突出你在项目中做的最有挑战的点、优雅的架构设计、或者独特有效的解决方案。比如在数据量非常大的场景下,通过优化 Redis 存储结构,减少了 70% 的 Redis 使用容量;比如对查询接口应用双发功能使 p999 降低了 60%;再比如使用了 Trace 功能来快速定位问题,等等。这一步要体现出你的实现能力与亮点。

 

第四步,要为第三步介绍的优秀架构或解决方案提供证明,比如前面介绍了系统架构中使用模块化来提高扩展性,那这里就可以说系统上线后,通过模块化方式支持了 7 个新业务的接入来体现你设计的架构的优点。

 

这里要注意,所有的结果必须是可以量化的,不要用性能大幅提升,极大提高灵活性这类很虚的描述。好一点的表述可以是这样:通过增加二级缓存,对后端服务的调用请求从 7000qps 降低到 600qps。这一步要体现出你对项目的掌握能力和了解程度。

 

第五步,思考项目存在哪些问题,或者还有哪些可以进行优化的点。

 

例如,现在项目 QPS 不高,某些任务是同步处理的,会有一定效率问题,这些处理步骤是可以异步执行的,如果请求量级增加,可以考虑使用 kafka 进行异步处理。处理时还应该考虑消息重复的问题,可以把处理逻辑设计成幂等性的。这一步要体现你对项目的思考以及总结反思能力。

 

如果我作为面试官,遇到一位按照上面 5 个方向来交流的候选人,一定会非常看好他。

面试技巧

再来介绍几个备战面试的小技巧。

 

第一点,肯定要提前思考、提前准备。

 

像项目架构图怎么画更容易理解,项目中到底哪个设计最有亮点,项目还存在哪些可以改进的地方等等问题,可能要花很多时间才能找到比较理想的答案,在面试现场临时回答难度非常大。一定要根据我前面的方法,提前准备。

 

第二点,要记住项目在精不在多。

 

有的人在介绍项目时,会抛出好几个项目,但每个项目介绍的都很潦草。在面试中,面试官是想通过项目介绍来考察你的各方面能力,一个重点的项目就足够了。一定要选你最了解、最能代表你能力的来介绍。

 

第三点,我了解的,就是我的。

 

有的同学可能因为机遇的原因,没有负责过重点的项目,不过项目介绍这么重要的考察点,也不能白白在这里丢分。你可以多了解一下其他同事或团队负责的项目,只要你能把细节搞明白,把架构理解透,那么知识就是你的,依然可以拿来进行介绍。

 

第四点,要重点体现对架构的理解,对设计的思考。

 

这会让面试官觉得你会很有潜力。你可以在介绍项目设计思路时做适当的延伸。例如你可以说:在我的业务场景下,可以容忍低概率的消息丢失,所以基于性能优先考虑,去掉了 Kafka 的 ACK 应答。如果是严格要求不丢消息的场景,我会使用同步应答,并且使用最高消息可靠性等级。

 

至此,《32个Java面试必考点》的所有内容结束,感谢支持。




这是为《32个Java面试必考点》准备的小彩蛋,给你提供一些职场里实用的建议和技巧。主要内容涉及四个方面:

  1. 如何打造一份有吸引力的简历

  2. 面试结束后应该做些什么

  3. 职场成长建议

  4. 一些高效工作和学习的小 Tips

如何打造一份有吸引力的简历

首先来看怎么写简历。大部分候选人都是倒在了简历筛选这一关。HR 或者面试官一般只会在简历上停留 10~30 秒,如果简历不吸引人,再优秀的候选人也会错失良机。

好简历的特点
  • 结构清晰、主次分明。


简历可以分为基本信息、项目经历、自我总结等部分,各个部分要做到主次分明,特别是项目介绍,建议按照发生时间倒序来排列,最新的项目放在最前。


多个项目之间也要分主次。重点的项目、最能体现你能力和工作成果的项目,要详细介绍,次要的项目尽量简洁,同一类型的项目建议不要重复。关于项目怎么介绍已经在前面第 10 课中介绍过了,不论是面试还是简历都可以使用 STAR 法则,在简历中 STAR 法则的各个要素可以更加精练。


  • 语句通顺,没有错别字,尤其是一些英文名称的拼写。


语句不通或者太过于口语化,会让人觉得你的逻辑和表达沟通能力不太好。而错别字会让人觉得你做事不细心不专业,不重视面试,工作中说不定 Bug 频出。另外,技术工作里有很多英文单词,要注意检查拼写和大小写,要让面试官第一印象觉得你是个严谨的人。


  • Less is more,少即是多。


简历的内容不是越多越好,建议不要超过 2 页。如果不能让面试官快速找到想要的信息,马上就会被 Pass。简历一定都是体现你能力的关键信息,可有可无的信息一律都要删除。比如,教育背景只保留高等教育阶段即可,高中就不需要出现。如果是社招,大学里无关紧要的证书就不用体现等。


  • 所有的结果都是可以量化的。


这点是很多人都会忽视的地方。简历里不能只说“做了什么”,要说“做成了什么”,可量化的结果更加真实可信。比如你设计的服务架构在线上支持了 20W 的 QPS;比如完成了 15 个功能模块的设计与开发,比如优化后响应时间提升了 70% 等等。最好用数字来体现。


  • 自我评价部分要更加务实,而不是空洞的描述。


像”性格开朗、责任心强、善于组织、协调和沟通,能良好地与团队合作“这虽然看上去挺像那么回事儿,但比较空洞,千篇一律没有特点。你可以考虑使用关键词+说明的形式,分条来写自我评价。比如这样说:“项目经验丰富:主导过授权认证、支付、视频、账户等项目落地,对不同类型项目架构方案和实现有深刻理解”。

写简历的技巧

知道了好简历的特点,但是还不够,下面这些技巧可以帮你进一步打磨简历。


1. 了解工作岗位的要求,针对岗位来调整简历。


好的简历不一定是通用的,要根据应聘的公司和岗位做针对性的优化,提高匹配度。有个重要的原则就是要突出你非常合适这个岗位,简历中要强调你的优势、技能、特长,正好是招聘职位所需要的。这样会极大的提高成功率。


2. 要想在海量简历中脱颖而出,你必须要塑造自己的特点,引起面试官的兴趣。


先审视自己,寻找自己的优点。比如,你参与过非常多的项目,那么实战经验绝对是你的加分项;如果你没有太多的项目经验,那你是不是逻辑清晰、思维非常敏捷?或者你的自我学习能力非常强,阅读过很多开源框架的代码?另外,如果你参与过 GitHub 开源项目或者经常撰写技术博客,一定要在简历中体现,这也是面试官非常关注的点。

 

但切记,你简历中突出的点,也会是面试官重点考察的点,要能把握住,不要给自己挖坑。


3. 可以换一个视角,找经验丰富的朋友来帮忙 Review 你的简历,听听哪里不足或修改建议。


4. 如果你没有参与过比较重大的项目,或者项目经验并没有太多出彩的地方,建议你看看负责过的项目上、下游是否有比较有特色服务,或者你熟悉的其他小组是否有重点的项目。


正所谓他山之石可以攻玉,你可以向同事请教学习,了解那些项目的架构、存在的问题、思考解决的方式。面试时,你可以从参与者的角度进行介绍,这不是鼓励你去造假,而是能够体现出你对技术的热情和好学。


但要记住,如果不能做到真正的了解,结果可能适得其反。


5. 如果你的简历存在硬伤,可以考虑另辟蹊径。


比如你项目经验丰富,技术能力高超,但是学历不高,这样简历很可能通不过初筛,连面试机会都难以获得。这时找朋友内推或者直接投递简历给公司内部的技术人员是非常有效的手段,你可以多加入一些技术交流群,就有机会联系到目标公司的技术人员帮忙内推。


不过要注意技术人员对技术能力比较注重,技术能力一般的话从这条路上很难走通。

面试结束后应该做些什么      

前面讲了很多面试前的准备工作,不过你也不要忽略了面试后需要做什么。这里给出几点建议。

 

1. 第一个建议,面试结束后,一般面试官都会询问候选人有没有哪些想知道的问题。这也是个表现的机会,千万不要什么都不问。

 

你可以提前准备 1~2 个问题,可以是对面试中的问题进行补充和延伸。例如:

  • “刚才面试中提到的问题,我觉得还可以如何如何设计,您看是否可行,能否给一些建议?”,这样可以体现出你对技术的兴趣和执着;

  • 对面试公司的技术或架构进行简单的询问,例如“我听说您的公司对 xxx 框架进行了改造,我想了解一下主要是想解决什么样的问题”,这可以体现出你对业界技术趋势的了解;

  • 获取一些建议,“您看我这次面试中哪些地方需要改进”;

  • 询问一下面试的岗位职责,主要负责哪些业务线和工作,使用的何种技术栈等等。


另外,如果是 HR 面试,可以询问一下关于岗位的职业发展和职业晋升途径等问题,表现出职业规划意识和上进心。

 

       2. 第二个建议,面试结束后一定不要马上询问面试结果。这是缺乏耐心的一种表现。

 

       3. 第三个建议,在面试结束后,回家一定要做面试复盘与总结。

 

       每次面试不论成功与否都非常有意义,面试结束后都要对面试中的问题进行记录。回答不上来的问题要及时查阅资料或源码搞明白,补充自己的知识短板。以及思考自己在面试中的哪些行为触发了面试官的不满,在下次面试时可以扬长避短。

职场成长建议      

如果你通过努力成功进入到了心仪的公司,一定不要懈怠放松,职场成长和新技术学习一样,不进则退。那么在职场中该如何保持竞争力,如何提升自己呢?首先就是要明确努力的方向。

 

你要主动从业务角度、产品角度来思考问题,思考如何能在业务角度更好的为公司产生价值。比如,如果能通过优化业务的交互和处理流程可以为公司节约 30% 服务器成本,那么就应该持续思考要如何解决新流程下的技术难题。

 

当有多个方向时,要衡量可行性、难度与收益,优先突破最有价值的方向。比如降低运行成本和提高研发效率来比较,可以优先以降低成本为方向。

 

有了方向以后,要把方向转化为可执行的计划,规定时间和阶段,按计划分步完成。有时候,这些计划会与本职工作产生冲突,要协调好时间和效率,不要影响日常工作。

 

最后,这种有价值的方向可能并不容易发现,又或者因为某些原因无法进行,这个时候不要急躁,可以调整为学习某个在自己的职业规划中必须要掌握的新技术。

 

这里给不同工作经验的朋友一些建议:

  • 工作 1~2 年,以学习知识为主,先打好基础,注意知识广度的培养,保持对新技术的好奇心,切忌心浮气躁;

  • 工作 3 年以后,需要多一些主动思考,培养自我学习能力,要有意识的提升团队协作、跨团队沟通、项目设计等能力;

  • 工作 5 年以上,要重点树立起自己的技术品牌。要经常思考业务或项目中存在什么样的问题,如何解决,解决后的收益是什么,对于管理能力要有意识的加强。

       然后,要努力打造自己的技术品牌和技术口碑,积累自己的技术价值。

 

比如,工作中有强烈的责任心,只要交代给你的事情一定会言出必行,负责到底;再比如经常协助同事排查解决技术问题,经常做一些有技术深度的分享或技术问题排查案例分享等等。

 

不要简单认为这份工作不合适,我就再找另一个,没必要那么辛苦打造什么技术品牌。要知道,你后续的职场人脉都是建立在你的技术品牌基础之上的,维持好的技术品牌会对你职业中后期发展大有裨益。

 

最后,要经常进行总结与自我反思。真正的成长都是在总结与反思之后获得的。某项工作或阶段性任务完成时,都要及时总结,既有助于发现改进空间,也有利于后续准备晋升素材。

 

可以分这几条进行总结:

  • 获得了哪些收益

  • 开发过程中遇到了哪些问题

  • 哪些问题是可以在设计初期就可以避免的

  • 哪些问题需要提早解决

  • 在开发过程中自己有哪些地方做的不好,后续要如何改进等等

  • 完成一次项目重构,可以总结一下旧的项目中都存在哪些问题、重构时哪些地方获得的收益最明显等等。

高效学习 Tips

下面从经验出发,分享几个高效学习的 Tips。

    

  1.  必须要有积极主动的心态,如果主观上不想去做一件事,肯定无法做到有效率。现在种树是为了日后乘凉。

  2. 要把任务分解成多个简单、单一的目标,争取每次只做一件事,按自己的待办事项表,一项一项进行处理,越专注效率就会越高。

  3. 要规划好时间计划,并按规律执行,这样可以有效避免拖延症。注意时间计划中要安排出充足的休息时间,会休息才能更好的工作。

  4. 要使用正确的方法执行工作或学习任务。比如学习时,可以通过断点调试、阅读源码、画类关系图、流程图、架构图等方式来进行。

  5. 要有阶段的产出,这样会让自己经常获得成就感,能够更好的坚持执行计划。阶段的产出物可以是定期的工作记录,小组内的技术分享、总结的技术博客等等。

  6. 要做好总结与改进,刚开始执行计划时可能还不太习惯,效率并不太高,随着按阶段不断总结和改进,工作和学习效率也会不断的提高。


在职场打拼就好比下棋,没有人天生就是高手,你必须多看多学、多实战切磋才能不断进步。而且高手在落子的时候,永远思考的都是下一步,想到的可能性越多,棋力也就更高。职场也是一样的道理,就像我也是从一名大学生,靠自己摸索了 10 年逐渐成为现在的技术专家。你只有不断往前看、往全局看,才知道如何走好下一步。希望你能根据自己的情况,不断尝试,找到最适合自己的成长方式。

 

所有内容至此结束,感谢阅读。


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/624730
推荐阅读
相关标签
  

闽ICP备14008679号