设计模式详解
为什么要学习和使用设计模式?设计模式是开发前辈们总结出来的代码设计经验,使用设计模式的目的就是提升代码的可扩展性和可维护性。
常用的设计模式有23中,可归为3类:创建型模式、结构型模式和行为模式。
注意:学习设计模式的本质其实是学习其设计思想,不能简单的生搬硬套,也不能为了使用设计模式而过度设计,要带有自己的思考,合理平衡的去设计才是我们学习的目的。
创建型模式关注对象是如何创建的。将对象创建和使用相分离,使两者可以相对独立地变换。
工厂方法核心思想定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类。
大白话
产品提供者:对于多个同一性质的不同实现的对象,通过提炼出一个产品接口,通过接口来体现这些对象是同一层次的产品关系。同时创建一个抽象的工厂类来提供创建产品的抽象方法(每个产品的生产细节不同,下放至具体实现类)和提炼出来的公共方法(实现完全相同的功能)。对于每个对象,都要有相对应的实现工厂抽象类的工厂来创建。产品和工厂是一对一关系。
产品使用者:通过调用具体要使用的产品的工厂类提供的接口来获取具体的产品即可,而不需要关心产品 ...
计算机网络复习重点
一、OSI七层模型
应用层:为最终用户提供网络服务接口,包含各种应用程序协议,如HTTP、FTP、SMTP、DNS等。
表示层:处理数据的表示、安全和压缩,负责数据格式转换、加密解密等。
会话层:管理用户间的会话,负责建立、维护和终止会话。
传输层:定义端口号,负责数据的分割、流控和差错校验,主要协议有TCP和UDP。
网络层:负责逻辑地址寻址和路径选择,主要协议包括IP、ICMP等。
数据链路层:建立逻辑连接,进行硬件地址寻址和差错校验,主要协议有ARP。
物理层:负责建立、维护和断开物理连接,处理通信信道上的原始比特流传输。
二、TCP/IP模型TCP/IP模型分为四层,自下而上分别为
网络接口层
网络层
传输层(Transport)
应用层(Application)
但为了方便学习,教学中将网络接口层拆成数据链路层和物理层进行学习,以下是按这5层的学习重点描述:
(1)应用层应用层是TCP/IP模型中的最高层,直接面向用户,为应用程序提供网络服务。常见的应用层协议如下所示:
DNS(域名系统–D**omain Name **System)1. ...
手写RPC框架
什么是RPC我的理解是,RPC(远程过程调用)是一种让程序能够像调用本地函数一样调用远程服务的思想概念。而RPC协议,则是详细设计了通信的数据格式(如JSON、XML、Protobuf)、传输协议(TCP/HTTP等)和序列化方式,从而将复杂的网络通信细节封装起来。
任何人都可以定义自己的rpc协议,只要:
明确的格式规范:定义请求和响应数据的结构、字段、编码方式
完整的调用语义:包含方法标识、参数传递、返回值、错误处理机制
一致的序列化:双方使用相同的序列化/反序列化规则
基本功能实现下面,我将完整介绍如何实现一个基本的RPC框架,主要涉及服务的注册和远程调用。
环境配置创建一个Maven项目,然后分别创建如下四个模块
通用模块通用模块存放了远程调用的接口和一些公共配置。消费者需要这个调用这个接口的远程实现。而服务端提供了这个接口的实现类,并可供消费者调用。
结构很简单,如图所示
在common模块中定义一个HelloServer的接口
1234567891011/** * * 远程调用的通用接口 * * @author ldy * @date 2025/ ...
如何自己实现一个Spring的starter依赖
Spring Boot自动装配原理解析及自定义Starter开发指南在使用Springboot做项目的时候,你是否好奇,为什么项目里只要引入了那些starter为后缀命名的依赖,spring容器中就自动配置了这些依赖中的实现类,你只需要注入即可。比如RedisTemplate、RabbitTemplate等。你是否想自己也实现一个springboot可以自动配置的依赖。那么通过本篇文章,你就可以更加清晰的理解spring的自动装配机制,以及手动实现一个starter依赖。
一、SPI机制1.1 什么是SPI机制SPI,字面意思:服务提供者的接口
我的理解是,他是专门提供给服务提供者去开发的一个接口。SPI将接口的定义和实现分离开来,将两者解耦(放在不同的包)。从而提升程序的可扩展性(支持多种实现)。
举例很多框架都用到了SPI机制,比如Spring框架、数据库驱动、日志接口等。
以日志接口举例:slf4j提供了spi接口,然后有多个实现spi的依赖包可供选择,比如原生的logback或者其他开发者提供的log4j2。⭐(这里可以记下,贴合实际)
模块
主要职责
是否SPI接口
...
轻松掌握Langchain4j
一、快速入门普通maven项目1.创建maven工程2.引入依赖123456<!-- 这个依赖额外提供 OpenAI 模型调用能力 --><dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-open-ai</artifactId> <version>1.0.1</version></dependency>
3.构建聊天对象OpenAiChatModel因为Deepseek使用与OpenAi兼容的API格式,所以这里我创建了连接DeepSeek的模型
123456789101112131415public class App { public static void main(String[] args) { //1.构建openAiChatModel对象 OpenAiChatModel model = OpenAiChatMod ...
深入java集合
一、内容概览
二、算法复杂度要想深入学习集合的底层原理,就要先对复杂度的概念有个清晰的认知。
(1)时间复杂度时间复杂度表示了算法的执行时间与数据规模n之间的增长关系。
常见的时间复杂度:O(1)、O(n)、O(n^2)、O(logn)
速记口诀:常对幂指阶
(2)空间复杂度空间复杂度表示算法占用的额外存储空间和数据规模n之间的增长关系。
三、List1.ArrayList(1)数据结构ArrayList底层使用数组来存储数据的。数组是一种用连续的内存空间存储相同数据类型的线性数据结构。
(2)基础问题1.数组下标为什么从0开始这就涉及到了数组元素的内存地址的计算问题了。
寻址公式 :baseAddress + i * dataType,计算下标的内存地址速率高。
人话:基地址 + 索引下标 * 元素类型占用的空间大小
如果索引是从1开始,那么寻址公式就需要对(i-1),对于cpu来说,相当于多了一个减法指令。
2.查找的时间复杂度
随机(通过下标)查找的时间复杂度是O(1)
查找未知下标的元素的时间复杂度是O(n)
如果未知下标,但数组是排好序的,那么利用二分查找的时间复杂度是O( ...
2025年暑期学习日记
Java-Drill2025.07.011.标识符和关键字的区别是什么?标识符简单来说就是指给程序、类、变量、方法等取的名字
关键字指的是被赋予特殊含义的标识符,比如访问控制符,程序控制符、错误处理、类和方法和变量的修饰符等
2.四大访问控制符访问权限由小到高依次如下;
private: 仅在当前类中可见。可修饰对象:类、变量、方法。 注意:不能修饰外部类
default: 在同一包内可见。默认,不使用任何修饰符,可修饰对象:类、变量、方法、接口
protected: 在同一包内的类和所有子类可见。可修饰对象:变量、方法。 注意:不能修饰外部类
public: 对所有类可见。使用对象:类、变量、方法、接口
提问: 外部类为什么不能使用protected、private修饰?
3.自增自减运算符4.移位运算符java里数值类型存储形式是补码形式进行存储的。
<<:左移,低位补零,当移动位数大于等于当前变量的二进制最大表示位数时,进行取余再移位运算。所以极限情况也就是最低位移到最高位,剩余位全为0
>>算术右移,带符号右移
>>>:逻 ...
开发常见问题汇总
一、maven项目环境搭建每次创建项目时,都要借鉴已有的项目依赖和配置文件进行创建,依赖用于什么功能的,以及配置文件作用于哪些依赖的,都云里雾里的。为此,写一个通用的环境搭建的博客就方便我创建新项目,需要引入什么常见依赖就看看这篇博客,顺便看看依赖之间的关系和配置文件的使用,(●’◡’●)。
1.1 SpringBoot依赖以maven创建的项目为例,仅需基础springboot父工程,然后引入启动器和测试依赖即可。
注意:springboot父工程定义了很多需要使用的依赖版本,故部分依赖版本号无需手动指定。
123456789101112131415161718<parent> <!--继承springboot父工程--> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.0.5</version>< ...
Java网络编程
Java网络编程一、基础知识IP:
用于标记计算机设备,是分配给上网设备的唯一标志。
有两种形式:IPv4和IPv6。
IPv4:
一共32位,分成四段表示。每段用十进制标志。
IPv6:
一共128位,分成八段表示,每段每四位编码成一个十六进制位表示,数之间用冒号分开。
示例:
12345678910//1.获取主机ipInetAddress localHost = InetAddress.getLocalHost();System.out.println(localHost.getHostName());System.out.println(localHost.getHostAddress());//2.获取域名ipInetAddress ip2 = InetAddress.getByName("www.zhihu.com");System.out.println(ip2.getHostName());System.out.println(ip2.getHostAddress());//ping www.zhihu.comSystem.out.print ...
Java深入学习
这篇文章用于记录Java基础知识相关的深入学习。包括了 动态代理、反射、JVM
一、动态代理篇首先先理清代理的概念,代理就是用来增强原对象功能的。通过代理,可以无侵入式的给对象增强其他功能。
代理长什么样?代理类里面就是对象要被代理的方法。
Java通过什么来保证代理的样子?通过接口保证的,被代理对象和代理都需要实现同一个接口,而这个接口里的方法就是要被代理的所有方法。
例子JDK动态代理被代理的原对象
123456789101112131415161718192021222324252627282930public class Star implements Star_Interface { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public Star() { & ...
