有关职业规划的一点思考
大厂年薪40万程序员vs老家年薪10万体制内,某乎热议真切发生在我身上。个人由此引发的一些思考。
//
有关职业规划的一点思考背景21年申到了港大CS专业的硕士,还没入学的4月份看到了当年很多大厂的开发岗位就业路径规划,就开始准备面试,一直不间断学到22年毕业,期间基本一直在面试当中度过。手里拿到的比较亮眼的offer就是某东莞大厂的年薪40万+的offer,和某北京中厂的年薪35万的offer,这对一个非科班选手来说,已经是以前在别的行业摸爬滚打时完全不敢想象的待遇。都说一年硕士水,我想正是这种「水」给了我充分的时间思考未来的人生规划,我决定转向体制内寻找机会,在22年底,婉拒掉了手里的这两个offer,报名国考、向国企投递简历,备考体制内的考试(行测、申论、结构化面试等)。截止3月份,手里拿到了一些不错的机会。一个是老家的人才引进项目下边某科级国企中层信息技术岗位、一个邻市某大行分行业务岗位、一个同样邻市的某大行金融科技子公司的开发岗位、一个杭州的大行直属研发中心的技术研发岗位。很难讲我最后在这几个、甚至未来更多潜在选项里,会选择哪一个。但是这个取舍的过程当中思考是非常宝贵的, ...
某银行2023校招业务岗面经
国企业务岗位,面试流程基本跟公务员面试类似,无领导小组讨论+半结构化面试,对于后续的国考省考面试(如果笔试通过的话)以及其他体制内岗位有比较强的参考价值
//
无领导小组讨论问题背景
你工作所在的S省是农业大省,农村集体经济发展较为滞后,为了配合国家的乡村振兴战略,促进本省农村集体经济发展,带动农民增收致富,省里派出若干工作组到其他发展较好的模范村调研学习。你所在的工作组被分配到Y省Z县调研考察,Y省Z县打造了一批农村集体经济发展的模范村,其中「强村八策」作为政策标杆被推广供各地学习。
共有 A~H 8项政策。
A ……忘了B ……忘了C 「边角经济法」- 充分利用村落的边角资源,引入商超、农贸市场等经济形态作为生产的补充,年度收益约15万元。D 「土地托管法」- 农村外出务工人员多,人少地多,土地荒废,为进一步增强集体经济的规模效应,村民以租赁、流转、参股等形式将土地集中到村集体,集中开发,还组织培训专门的队伍进行播、种、管、收,年度村集体土地托管收益约26万元。E 「企业对接法」- 在经济优势较为明显的村,进一步推行与相关企业的合作,整合产业链,年度为村集体增收约115 ...
后端项目中连接池的应用
在医疗管理系统中,为了缓解服务器压力,引入了连接池的组件来管理连接。
//
后端项目中连接池的应用多个请求集中访问低性能服务器,如何限流项目主要实现如下功能:用户在前端输入自己的「症状」,预期得到一个包含「推荐科室」、「初步诊断」的输出。这个输入到输出的运算经由一个 NLP-BERT 的 AI 模型处理,该 AI 模型部署在服务器 B 当中,而后端部署在服务器 A 当中(实际操作中,将两者布署在了同一服务器)。
用户 输入症状 -> 后端服务器 A -> 服务器 B 运行 NLP 脚本 用户 <- 后端服务器 A <- 服务器 B 返回诊断
当有多个请求同时进入 NLP 服务器,服务器只有 4GB 内存,两个 CPU,性能不够而经常出现宕机无法响应的情况。为此需要将请求限流。实现时采用了连接池的方法。
AI 服务器端通过 server.listen(1),我们将所用端口允许的最大连接数限制为 1。
12345678910111213141516171819202122232425262728293031323334353637383940414 ...
操作系统基础知识
操作系统基础知识校招面经整理、热身
//
操作系统基础知识进程和线程的区别:进程是程序调度的基本单位,既包括时间概念——一段由一系列指令占用的 CPU 的时间片,也包括资源概念——处理这些指令所需的各种资源,包括内存空间,进程上下文,I/O权限等。线程是进程中任务执行的基本单位,是比进程更细的粒度对资源的划分,进程中占用的 CPU 时间片可以继续细化为一个个具体的任务,每个任务分别占用一小段时间片。同时不同线程也拥有自己的线程上下文,并共享所在进程内的公共内存空间,为了更好操作这些公共内存空间,线程间需要一些同步、互斥机制(如各种锁、信号等),共享内存以及同步、互斥机制,就成为了线程间通信的手段。例如 Java 当中启动 Main 函数以后相当于启动了一个 JVM 进程,而 Main 函数所在线程作为该进程的主线程。
CPU 主要调度是线程还是进程:从系统角度看,CPU 的调度是以进程为粒度的。每次 CPU 挂起、就绪、运行、阻塞、终止等操作的基本对象都是进程。CPU 要负责对运行的进程调度所需的各种资源,并在当前进程挂起时为其保存上下文。线程更多的是进程内部的概念,其切 ...
编写单元测试相关
工作中需要给接口编写单元测试,增加单测覆盖率,涉及到测试环境的搭建,如 Mock、Fake 等,稍作记录。
//
入门单元测试编写的一些总结本文主要参考
测试规范实践方案
Mockito 详解
Fake、Mocks、Stubs
写单测的时候发现别人写的模拟测试环境的代码有点看不懂,看了测试规范还是有点懵逼,于是读了一些博客,简单梳理了一下。
模拟外部服务, Mock、Fake、Stub其实模拟的目的简单,就是我们测试的对象 A,运行当中多少需要依赖一些外部的服务、对象和数据库,本地单测环境下里没法构建这些完整的服务,于是需要在本地模拟这些对象和服务的实现。
模拟的方法也很简单,
对于你需要调用的外部服务,自己写一个预设好的返回值(保证调用时返回确定的结果)。这就是一个 Mock。
如果需要调用一个外部对象比较完整的功能,那么干脆使用一个新的实现,可以基本模拟该对象的大部分行为,也能方便其他测试复用。这就是一个 Fake。
对于需要访问数据库等情况,在内存中建立一个虚拟的数据库交互对象,插入一些预设好的数据,以供访问数据的接口进行增删改查,这就是一个 Stub。
Mock借助 ...
Java 基础知识、JVM、Java多线程、Java 网络编程
JVM 、 Java 基础知识、多线程和网络编程校招面经整理、热身
//
Java 基础知识、JVM、Java多线程、Java 网络编程相关Java SE 基础String、StringBuffer、StringBuilder的区别:
String 用 final 修饰了 char[],是不可变类,可以视为常量,若要修改的话需要生成一个新的 String 对象。
StringBuffer 和 StringBuilder 的 char[] 是可变的,可以进行修改。
其中 StringBuffer 的方法加了同步锁,线程安全。
而 StringBuilder 的方法没有加同步锁,非线程安全,但性能较好。
HashMap 底层原理、添加元素的底层实现:
1.8 之前,数组 + 链表,key 的 hashCode 经过若干次扰动后得到哈希值,求余(hash & (size() - 1))之后放入数组,冲突则使用链地址法,添加元素采用头插法。扩容后需要重新计算各个 key 的 hash。
1.8 之后,扰动算法改进为一次扰动, hashCode 高 16 位与低 16 位 异或后获 ...
CI/CD 流水线梳理
对工作中碰到的 CI/CD 流程做一点简单梳理。
//
CI/CD 流水线本文参考以下文档:
Continuous Integration
什么是 CI/CD抽象的 CI/CD 流程并不复杂。
CI「持续集成」使得开发者可以频繁提交更改的代码,合并到应用当中,并自动构建应用镜像,运行不同级别的自动化测试(针对类、函数、功能模块等)来验证更改没有产生破坏性的错误,也没有与现存代码产生冲突。
代码库提交 -> 静态(代码)分析 ->
CD(Continuous Delivery)「持续交付」将 CI 已经验证的代码合并到代码库,满足可以随时部署到生产环境的条件。
CD(Continuous Deployment)「持续部署」将前一个 CD 构建就绪的应用镜像部署到生产环境。
对应 Console 的流水线流程
构建
推到 Repo 合并入 master,从此步骤开始构建一个可部署的镜像 Deploy Candidate,进入后面的步骤
Linting 静态分析
单元测试
集成测试
部署
部署到开发环境
部署到 QA 环 ...
分布式系统、消息中间件相关
使用 Hadoop、Spark、Kafka、RocketMQ 等分布式组件、消息组件时涉及到的问题。
//
分布式系统、消息中间件相关Kubernutes(K8s) 的工作原理,配置管理虚拟容器集群的优点K8s 是一种虚拟机管理程序,适用于布署和管理分布式虚拟机集群(Cluster)。K8s 的虚拟机更加适配于容器化管理,在操作系统层次上布署一层容器运行时 Container Runtime 服务来提供容器运行的环境,比如可以选择 Docker 作为 Container Runtime。Container Runtime 上可以运行多个 K8s 最小管理单元 Pods。K8s 采用 Namespaces 机制实现对资源的隔离、分组。 在系统目录下创建不同的 Namespace,不同 Namespace 彼此相独立隔绝,拥有只有自己可见的资源结构,包括硬件资源如 CPU、内存、页块大小,软件资源如进程树、文件目录等。Namespace 可以用 YAML 文件配置。K8s 的 Label 功能,可以给 K8s 对象(Nodes、Pods 等)绑定若干个键值对 Key-Value Pai ...
Thrift 相关知识点
Thrift 作为常用的RPC框架,我实习的项目也是以此构建的,因此记录相关知识点以备复盘。
//
Thrift 相关知识点需求:微服务为了实现技术解耦,业务上引入了「微服务」的概念,将不同的业务逻辑分散为独立的服务,需要时再相互调用,提高了可维护性和可靠性。
微服务的实现有如下两个痛点:跨语言调用不同功能间的跨进程调用(由于种种原因,这些功能可能由不同语言实现),需要解决跨语言的支持问题。跨语言调用的主体称作「工作单元」,可以是某个进程,也可以是某个内存中的数据结构。常见的跨语言场景可以按如下分类:
工作单元内部协作:直接解释某些脚本语言(如 Lua 等)。
工作单元外部协作:
单进程:动态链接库调用(通信的前提是不同语言之间有相同的二进制接口 ABI)
多进程:远程过程调用(RPC),thrift 就是用来实现 RPC 的一种方案。
Thrift 定义了一种中间语言(接口定义语言 IDL)来作为沟通的统一标准,再由自己的编译器将 IDL 分别编译为不同语言的代码(Java,C++,Python 等),或反向操作。
依赖底层细节调用方和服务提供方除了要声明 所需/ ...
Flexport 面试
Flexport 的风格跟大多数外企一样,主要考察做题。
//
一面考察了两道算法题(第二道当场没想出来,不确定后续是否还有其他题),题本身不难,可能自己有点钻牛角尖没做出第二问。在这里记录以供复盘。
随机字符串生成
输入:一个字符串 input,是一个由单词和空格组成的句子(无前导空格,无标点,单词之间仅以一个空格间隔,字符全是小写英文字母),以及一个整数 N 表示生成句子的单词个数。
输出:一个字符串 output,包含 N 个单词,这 N 个单词按照如下规则生成:在 input 句子中随机取一个单词,作为输出句子中的第一个单词,记为 word_1,(word_1 在句子中可能重复出现)。每一个 word_1 之后紧跟着的下一个单词,组成一个单词池,在这个池中继续随机抽取一个单词,作为句子的第二个单词,记为 word_2,…… 以此类推,直到句子有 N 个单词为止。如果某一步取到了 input 句子的最后一个单词,则下一个单词应该为 input 的第一个单词,即 input 可以视为一个字符串循环队列,各元素之间以空格分开,最终拼接而成。因为单词每次都是随机抽取的,所以对于 ...