后端项目中连接池的应用
在医疗管理系统中,为了缓解服务器压力,引入了连接池的组件来管理连接。
//
后端项目中连接池的应用多个请求集中访问低性能服务器,如何限流项目主要实现如下功能:用户在前端输入自己的「症状」,预期得到一个包含「推荐科室」、「初步诊断」的输出。这个输入到输出的运算经由一个 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 可以视为一个字符串循环队列,各元素之间以空格分开,最终拼接而成。因为单词每次都是随机抽取的,所以对于 ...
2022 猿辅导校招 Java 后端开发秋招
//
一面Java 基础
谈谈 Java 程序怎么实现跨平台兼容的?
比如现在有一个 windows 32 位环境下编译好的 Class 文件,放到 linux 64 位环境下,可以运行吗?
Javac 编译以后形成了 Class 文件,这个过程大致是怎么样的?
字节码直接就能执行吗,跟机器码有什么区别?
Java 进程跟线程的联系和区别?
线程有哪些状态呢?
wait() 和 sleep() 在面对锁的时候表现有什么不同?
计算机网络
客户端想和服务器建立 TCP 连接,要进行什么操作?
TCP 通信时,上层的应用对 TCP 收到的数据会怎么处理?
数据库
通常有哪些手段可以优化 MySQL 的查询效率呢?
说说联合索引失效条件?
怎么查看查询语句用到的索引呢?
算法题考了两道算法,不知道是我第一题做快了还是本来就准备考两道题。代码平台是牛客网。
将二叉搜索树转换为有序双向链表。调试不方便,简单写完核心逻辑(中序遍历放入 List 中再按序修改指针即可),讲完思路就算过了。
一个纯数字字符串,判断其是否可以通过加分隔点表示一个有效的 IP 地址(比如 “1111” 串可以 ...
面试综合技巧(不定期更新)
复盘面试中优化自己表现的软技巧。
//
1.话题引导对一个开放性多角度的问题,尽量朝自己熟悉的领域展开,回答的时候对不熟的领域不要过多涉猎,蜻蜓点水即可。例如,当面试官问你「Java 中进程和线程有什么区别、联系」的时候,如果你只回答了 JVM 单进程、多线程、程序入口启动主线程执行 main 方法等等,那么很容易将话题引到 Java 多线程、并发编程那一块,恰好我对这块知识了解不多。于是,我会再补一句「例如,JVM 在主线程之外,还可能会并发地运行 GC 线程」,这样话题就有可能进一步扩展到我相对更熟悉的 GC 方面,降低暴露我知识盲区的风险。我们就成功通过话题的引导,掌控了面试的节奏。
