基本概念
1.软件生命周期由哪些阶段组成(三个时期,八个阶段)
软件生命周期通常划分为以下结构:
软件定义时期:
问题定义
可行性研究
软件开发时期: 3. 需求分析 4. 总体设计(概要设计) 5. 详细设计 6. 编码与单元测试 7. 综合测试(集成测试与确认测试)
软件维护时期: 8. 软件维护
2.软件设计过程中应该遵循的基本原理有哪些?
在设计过程中,应遵循以下核心准则:
模块化:将系统划分为功能独立的模块。
抽象:提取核心逻辑,忽略非本质细节。
逐步求精:从宏观到微观,分层分解功能。
信息隐蔽与独立性:提高模块内部的内聚性,降低模块间的耦合性。
3.大型软件系统的测试步骤是怎么样的
测试遵循“自底向上”的过程:
单元测试:针对具体模块(函数/类)进行测试。
集成测试:将模块组装,测试接口间的协同。
确认测试(系统测试):验证系统是否满足需求规格说明。
验收测试:由用户主导,确认软件是否可投入运营。
4.面向对象方法学的有点有哪些’
复用性高:通过类和继承减少重复工作。
易维护性:封装性使得局部修改不影响全局。
稳定性好:更接近人类对现实世界的认 ...
基础知识
HTML:超文本标记语言,用于描述网页内容(文本、图片、声音等)。
作用:负责网页的结构与内容。
说明:定义页面中有哪些元素,如标题、段落、表单、图片、链接等。
本质:网页的“骨架”。
JavaScript:脚本语言,用于实现前台数据验证(如判空)和增加网页交互性。
作用:负责网页的行为与交互逻辑。
说明:实现表单校验、事件响应、DOM 操作、异步请求(Ajax)等。
本质:网页的“动态与交互”。
CSS:层叠样式表,用于增强网页样式并实现样式与内容分离
作用:负责网页的样式与布局。
说明:控制颜色、字体、大小、位置、页面布局(如 Flex、Grid)等。
本质:网页的“外观与美化”。
常考 <form> 标记的 action(提交地址)和 method(提交方式)属性,以及 <input> 的各种类型(text, password, submit, reset 等)
request:用于封装和获取页面提交的数据信息,常用方法是 getParameter(String name)。
response:用于设置响应信息,如重定向 sendRe ...
基本概念
软件项目的特殊性(4点)与 软件项目管理的特殊性是什么?
软件项目的特殊性 (4点):
不可见性 (Invisibility): 软件是逻辑实体,看不见摸不着,进度难以直观衡量。
复杂性 (Complexity): 技术复杂、业务逻辑复杂,且需求多变。
一致性/顺从性 (Conformity): 软件必须适应硬件、环境和遗留系统,而不是环境适应软件。
可变性 (Changeability): 软件容易被修改,导致“需求蔓延”。
软件项目管理的特殊性:
它是智力密集型的创造性活动。
独特性强,没有完全相同的两个项目。
不确定性高,很难精准预测进度和成本。
软件项目的招标步骤通常包括哪些?
招标 (Solicitation): 甲方发布招标公告(RFP/RFQ)。
投标 (Bidding): 乙方编写标书并投递。
开标 (Opening): 公开开启标书。
评标 (Evaluation): 专家评审技术和商务部分。
决标/授标 (Awarding): 确定中标单位。
签约 (Contracting): 签署正式合同。
四大开发模型是什么?Scrum 的三大角色、四 ...
核心概念
操作系统的核心职能是有效地组织和管理计算机系统中的硬件资源(如处理器、内存、硬盘、外设),并向上层应用程序或用户提供简洁的服务功能接口,屏蔽硬件管理的复杂性。内核是操作系统的核心,主要模块包括进程调度、内存管理、设备管理、文件系统和网络管理
值得注意的是,不同的操作系统采用不同的内核架构:Linux内核通常采用宏内核(Monolithic Kernel),将大部分服务集成在内核空间中以追求高性能;而 iOS 采用混合内核(Hybrid Kernel),它结合了宏内核和微内核的优点,其核心是 Mach 微内核和 BSD 系统
进程管理
简单点说:
进程管理的核心任务: 决定谁来使用 CPU,以及用多久。
通俗理解:
想象 CPU 是一个 大厨,而“进程”就是一道正在做的 菜(比如炒宫保鸡丁)。代码是菜谱。
虽然大厨一次只能颠一个勺,但他动作极快,一会儿切这道菜的肉,一会儿翻那道菜的锅。在旁人看来,就像他在同时做四五道菜。这就是并发。
你需要学习的关键点:
进程 vs 线程: 进程是资源分配的单位
进程状态: 就绪(Ready)、运行(Running)、阻塞(Blocked) ...
架构设计
Spring AI Alibaba 项目在架构上包含三个清晰的层次:
Agent Framework:以 ReactAgent 设计理念为核心的 Agent 开发框架,内置了自动上下文工程和 Human In The Loop 等高级能力。
Graph:一个更底层级别的工作流和多代理协调框架,是 Agent Framework 的底层运行时基座,用于实现复杂的工作流编排,同时对用户开放 API。
Augmented LLM**:基于 Spring AI 框架的底层原子抽象,提供了模型、工具、消息、向量存储等构建 LLM 应用的基础。
设计理念
ReactAgent
ReactAgent是 1.1 版本的核心组件之一,它基于 ReAct(Reasoning + Acting) 范式。这意味着 Agent 不仅仅是调用 LLM,它还可以在一个循环中运行,通过“思考(Reasoning)”来分析任务、决定使用哪个“工具(Acting)”,然后“观察(Observation)”工具结果,并迭代此过程,直到任务完成。
就是我们先去进行一个思考,然后再去进行工具的调用,根据结果再去进 ...
高并发日志系统设计
我们可以将整个日志生命周期划分为五个关键阶段:采集 -> 传输 -> 处理 -> 存储 -> 应用。
根本性设计:
结构化日志: 将不同日志封装成不同数据结构。
传输解耦: 使用 Kafka 作为日志总线。
分流消费: 一部分流式处理(热路径),一部分存储(冷路径)。
结构设计
统一日志规范:
会定义一个公共的日志基础 Schema (Base Schema),所有日志都必须包含某些字段,需要保证:
一致性 (Consistency): 确保任何来源的日志都有相同的核心结构,便于机器解析和人类理解。
可关联性 (Correlatability): 能够将分散在不同系统、不同时间的日志串联起来,形成完整的事件链。
可检索性 (Searchability): 优化核心字段,使其易于索引和查询。
timestamp: 事件发生时间(UTC, 毫秒级精度)。
格式: 必须是 ISO 8601 格式,例如 2025-10-09T06:10:35.123Z。
时区: 必须是 UTC (协调世界时)。这消除了所有因服务器时区不同导致的混乱,是分布式系 ...
基础知识
容器化
想象一下传统开发流程中的经典难题:“在我的电脑上明明是好的,怎么一到服务器上就出问题了?”
这个问题的根源在于环境不一致。开发者的电脑和服务器的操作系统、依赖库、配置文件等可能存在细微差别,导致程序行为不一致。
核心逻辑: 我们需要一种技术,能将我们的应用程序及其所有依赖(代码、库、配置文件等)打包在一起,形成一个标准化的、可移植的“集装箱”。这个“集装箱”在哪里运行,其内部环境都完全一致,从而彻底解决环境依赖问题。
这就是**容器化(Containerization)**思想的由来。
Docker 就是目前最流行的容器化工具。它引入了几个核心概念来实现这个目标。
2.1 镜像 (Image)
它是什么: 镜像是一个只读的模板,是应用程序的“安装包”或“光盘”。它包含了运行应用程序所需的一切:代码、运行时、库、环境变量和配置文件。
如何构建: 通过一个名为 Dockerfile 的文本文件来定义构建步骤。Dockerfile 就像一张“菜谱”,指导 Docker 如何一步步制作出这个“安装包”。
核心逻辑: 镜像是静态的、标准化的交付物。一次构建,处处运行。这就保证 ...
K8S
1.k8s 基础组件有哪些,什么功能?
Kubernetes 遵循典型的 C/S(客户端/服务器)架构,由**控制平面(Control Plane / Master)和数据平面(Data Plane / Node)**组成。
控制平面组件 (Master Components):
kube-apiserver:
功能: 集群的统一入口和大脑中枢。所有组件之间的通信都通过它进行。它以 RESTful API 的形式暴露了 Kubernetes 的所有功能,并负责处理请求的认证、授权、准入控制,然后将有效资源对象的状态持久化到 etcd。
etcd:
功能: 集群的分布式键值存储系统。它负责存储集群的所有状态数据,如 Pod、Service、Deployment 的定义和状态等。etcd 的高可用性和数据一致性是整个 K8s 集群可靠性的基石。
kube-scheduler:
功能: 专职的“调度员”。它持续监听(Watch)apiserver,发现新创建的、尚未分配节点的 Pod。然后根据一系列预设的调度策略(如资源需求、亲和性、污点容忍等)为 Pod 选择一个最 ...
RAG
1.什么是RAG
RAG,全称是 Retrieval-Augmented Generation,中文可以理解为 “检索增强生成”。
而是一种将**信息检索(Information Retrieval)系统与大语言模型(LLM)的生成(Generation)**能力相结合的技术框架。
解决了LLM的:
知识局限性 (Knowledge Cutoff):LLM 的知识都来自于其训练数据,这些数据有明确的截止日期。对于截止日期之后的新知识,模型是无法感知的。
事实幻觉 (Hallucination):LLM 在回答它不确定的问题时,有时会“编造”听起来合理但实际上是错误的答案,这在需要高度事实准确性的场景中是致命的。
缺乏领域专有知识 (Lack of Domain-Specific Knowledge):对于一些非常专业或企业内部的私有领域,通用的大模型由于没有接触过相关数据,无法提供精准的回答。
当模型需要回答问题时,不直接让它依赖内部知识进行生成,而是先从一个外部的、可信的知识库中检索出与问题最相关的信息,然后将这些信息作为上下文(Context)和原始问题一起提供给大语言模型 ...
异常解决
1.就比如说你这个部署到线上了,然后他抛了一个异常,然后那你这个应该怎么排查呢
线上出现异常,我会遵循一套从宏观到微观、由表及里的排查SOP(标准作业程序)来定位和解决问题。
第一步:信息收集与初步判断
确认影响范围:首先,快速判断这个异常的影响面有多大。是影响了所有用户,还是部分用户?是核心功能还是边缘功能?这决定了问题的紧急程度。
查看监控告警:立即查看监控系统(如Prometheus/Grafana, Zabbix)的告警信息。检查应用的
关键指标,如:
应用层面:QPS、响应时间(RT)、错误率(Error Rate)是否突增?
JVM层面:CPU使用率、内存占用、GC活动是否异常?
主机层面:服务器的CPU、内存、磁盘I/O、网络流量是否正常?
依赖服务:数据库、Redis、MQ等中间件的健康状况如何?
这一步的目标是快速定位问题是出在应用本身,还是外部依赖。
第二步:日志分析与精准定位
聚合日志平台检索:登录ELK(Elasticsearch, Logstash, Kibana)或类似日志平台,根据告警信息中的时间点、错误信息关键字(如Runti ...
分布式
1.分布式事务设计
TCC、Saga、本地消息表、事务消息
本地消息表
这是一种实现“最终一致性”的常用方案,核心思想是将业务操作和发送消息这两个步骤,放在同一个本地事务里来保证原子性。
事务发起方:在执行核心业务逻辑时(例如:创建订单),会在同一个数据库事务中,向一张本地的“消息表”插入一条消息记录,这条记录的状态初始为“待发送”。
事务提交:当本地事务成功提交后,订单数据和“待发送”的消息记录会同时落库。
消息投递:我会用一个独立的、可靠的后台任务(比如使用定时任务调度框架如XXL-Job)去轮询这张消息表,把所有“待发送”状态的消息发送到消息队列(MQ)中。
状态确认:消息成功投递到MQ后,后台任务会更新消息表中的记录状态为“已发送”或直接删除。如果投递失败,它会进行重试。
事务消费方:下游服务消费MQ中的消息,并执行相应的业务逻辑。为了防止重复消费,消费方必须保证接口的幂等性。
消息的发送不是实时的,存在一定的延迟。需要额外维护一个后台任务。
事务消息
第一阶段 (Prepare Message):生产者先向MQ Server发送一条“半消息”或“预备消息”。这条 ...
JUC
1.线程池常见的坑
线程池的参数配置:核心线程的数量,和最大线程的数量是业务场景来的,CPU密集型,比如数据的计算业务,就是CPU的数量+1。
IO密集型根据业务压测的值来决定的,最佳线程数=((线程等待时间+线程CPU时间)/线程CPU时间)*CPU数量
比如,我们服务器CPU核数为8核,任务线程CPU耗时20ms,线程等待等等耗时80ms,那么最佳线程数=(80+20)/20*8=40线程,那我们最大线程数就是80个
共享线程池,次要的逻辑拖垮主要的逻辑。避免所有的业务都共享一个线程池,防止一个次要的业务一直在执行业务,占用线程池。而主要的业务并没有足够的线程数来执行,影响到了我们主要的服务。这样做是不合理的。我们应该要做线程池的隔离,使用Future.get方法的时候,使用带超时时间的,因为他是阻塞的,防止被其他抢占。
@Async是Spring中一个注解,他不是线程池,他其实是SimpleAsyncTaskExecutor,不会复用线程,适合执行大量短时间的线程。还是尽量自己定义一个异步的线程池,然后使用@EnableAsync来注册
使用线程池的时候,不使用 ...













