自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(56)
  • 收藏
  • 关注

原创 MySQL - 索引

在B+树中每一个节点都是一个页:非叶子节点为索引页,叶子节点为数据页。(8.0是版本号,具体以使用的版本号为主),可以看到创建的数据库,打开数据库可以看到表的信息MySQL创建的表格数据都是以.idb为后缀的,每一个表中又包含多个页。页头中包含上一页和下一页的页数,方便页数的起始计数。

2025-12-21 17:59:41 924

原创 MySQL数据库 - 约束和联合查询

创建成绩表格,因为成绩与学生和课程有关,所以需要加入学生id和课程id,此参加表为一门科目的成绩表,所以在添加一个成绩信息,为了和其它表格建立联系需要创建外键约束:成绩表与学生表的联系,课程表和成绩表的联系。两个表格间需要确定关联时,就可使用外键约束,例如以上的班级表中包含教室id,每一个学生都有一个班级,在学生表中可添加class_id,就可以通过class_id建立两个表的联系。因为学生表与班级表建立了外键联系,在添加学生信息时,需要先有班级的id信息才可添加学生信息,否则会出现报错。

2025-12-14 19:45:26 740

原创 MySQL数据库 - 常见的操作

在上面的表中创建的时间是默认的,在填入表的数据时就可以不填写考试时间这一列,在参数列中填写的有,exam_name(考试科目),venue(考试地点),examinee char(考试人员)),candidata_number (考生号)state bool (参考状态)。例如:创建一个考试参考人员登记表,表名位ERF(Examination Registration Form),参数需要包含,考试的科目,考试的地点,考试时间,参考人员姓名,考试号,参考状态。

2025-11-30 00:31:33 615

原创 Java EE - 多线程下单例模式的设计

由于线程t1只执行判断的逻辑,每一次都需要在内存中读取,再到cup执行判断语句,编译器为了更快的执行逻辑,会将内存的读取操作优化到寄存器直接读取(cpu的执行速度比内存的执行更快),即将count变量拷贝一份到寄存器中,当t2线程输入时,对t1线程中的判断操作不影响,导致无法真正终止t1线程。如果此时已经将instance初始化,再一次调用getInstance方法,只需要返回instance,但是执行方法逻辑时,会先进行加锁操作,再进行判断是否为首次创建,而锁是需要资源的,频繁的使用锁会导致性能的下降。

2025-11-17 17:55:17 857

原创 Java EE - 常见的死锁和解决方法

创建两个线程t1和t2,定义两个锁对象locker1和locker2,两个线程并发执行,t1线程先获取锁对象locker1,t2线程获取锁对象locker2,在保持获取锁的基础上,线程t1请求获取锁对象locker2,线程t2请求获取锁对象locker1,由于此时锁的获取需要解锁后才可申请,两个线程同时请求对方的锁,此时的两个线程就都进入阻塞等待,形成死锁。以上情形如果是在多线程的情况下执行,就会引发多个线程进行阻塞等待,可能所有线程都无法完成任务,还会消耗资源,形成死锁。2)锁是不可争夺的;

2025-11-16 21:44:35 855

原创 Java EE - 线程安全的产生及解决方法

线程安全问题是在多线程并发的情况下,程序执行的结果与预期的结果不一致导致出现的问题,可以先看以下例子:创建两个线程t1 和 t2,定义一个变量count,在两个线程中对变量count分别执行累加操作(count++)5000次,然后输出count变量,预期输出结果是10000.1.操作系统在给线程分配资源的时候是随机的,可能先一段时间执行t1线程,再一段时间执行t2线程,也有可能t1执行完在分配给t2线程,或者t2先执行完后执行t1线程,两个线程并发的过程中就可能存在时间上的间隙(不在同一时间上执行)。

2025-11-12 14:42:27 829

原创 Java中的反射机制和lambda表达式

在获取的构造方法,成员方法,字段需要修改时,需要调用setAccissble方法,表示是安全的设置,同时实例化对象,确定获取的是哪一个对象的构造方法,成员方法,字段,最后分别使用invoke和set方法执行方法和字段的修改,完成反射的基本过程。getMethod方法需要的参数列表有两部分,第一个是需要反射的方法名,第二个是方法中的参数列表,类型是Class<?反射是java中在程序运行时可以获取到类的名称,方法,构造,字段的一种机制,根据获取到的类获取类的实例化对象,进而可使用类中的方法,访问类的成员。

2025-11-10 17:00:10 851

原创 Java EE - 线程的状态

Blocking状态即阻塞状态,同时再两个线程同时申请各自加锁的对象导致的状态,例如:线程t1已经加锁了o1对象,线程t2加锁了o2对象,此时t1线程申请再加锁o2对象,t2线程再申请加锁o1对象,由于两个线程都已加锁并未解锁,申请新的锁对象就会一直处于阻塞状态中,t1和t2线程的状态都为Blocking状态。线程进入无限制时间的等待就是warning状态,线程进入warning状态通常是线程进入阻塞状态,或者,线程中使用了wait方法,需要等待notify方法的唤醒。,所以可以给当前线程对象加锁,使用。

2025-11-08 17:59:04 866

原创 Java EE - Thread类的基本使用

Thread类是Java标准库中提供用来管理线程的类,里面封装操作系统对线程管理方面的API,Java中创建的每一个线程,可以理解为Thread类的实例化对象,用来描述线程信息,可以视为Thread类是对操作系统提供线程管理的API进一步的抽象和分离。定义一个MyThread类,继承于Thread类,Thread中有一个run方法,需要在子类中重写,MyThread类重写完成后,实例化MyThread的对象,就完成线程的创建,但是线程的真正的调用需要使用Thread类或者子类中的start方法。

2025-11-04 21:31:53 799 1

原创 Java数据结构 - 哈希表的模拟实现

字符有对应的ASCII值,刚好对应创建数组的下标,可以制定一个哈希函数(下标作为属性),因为数组的下标只有 0 - 25,需要将字符处理,字符a的ascii值是97,如果对应0下标存储,让字符a 减去97就可以得到,97刚好是字符a的ascii值,字符b的下标对应是1,而b的ascii值是98,获取1下标需要减去97,对应的是字符a的ASCII值,依此类推可以获取到一个哈希函数。

2025-11-02 14:49:05 866

原创 Java数据结构 - Map和Set

Set是底层是通过红黑树(RB-Tree)实现的,而红黑树是在搜索树的基础上增加了颜色的属性,是每个节点都有颜色的属性,要么是红,要么是黑,维持着左右子树的平衡,近似于一棵完全二叉树,当需要搜索时时间复杂度为O(logN),即树的高度;

2025-10-26 16:55:12 636

原创 Java EE - 进程与多线程

在操作系统中,并不会每时每刻都只执行一个进程,进程的执行需要系统分配资源,当系统暂时不执行进程时,可能进程的所有指令还未执行完成,等系统再次分配资源时,需要继续往下执行进程的指令,但是需要知道进程上一次执行的位置在那里,此时就可以使用文件描述符,文件描述符记录了进程执行的指令数(PC来查询),进程的PID,指令的执行结果等信息,等再次执行该进程,通过文件描述表就可以恢复到原来的进程执行的位置。每一次进程的执行系统都会统计,当系统发现一些进程长时间未被执行时,系统就会向该进程分配多一些资源,去执行该进程。

2025-10-25 17:30:53 641

原创 经典排序算法的实现与解析

去数组的最左边元素和最右边元素和中间元素三者比较,取中间值作为基准值,交换的次数可以得到优化,数组【5,1,2,3,4】,如果选定5作为基准值,就需要将1,2,3,4元素交换到5前面,而选定中间值2,只需要将5元素交换到4后面即可,减少了交换的次数。基准值的元素,左右区间都找到交换的元素,进行交换,重复上述过程,直到循环结束,最后交换基准值位置和left下标位置的元素,完成基准值对左右区间的划分,递归左右区间。例子:给定一个数组arr[52,2,63,61,22,44,7,33],使用快速排序完成排序。

2025-10-19 20:04:20 605

原创 Java数据结构 - 优先级队列的模拟实现与使用

优先级队列(PriorityQueue)是一种优先级别先出队列的数据结构,底层使用堆来实现,而堆的底层是在完全二叉树的基础上扩展的,通常分为大根堆和小根堆,大根堆的根节点的值在树中最大的,而小根堆的根节点值是最小的,因此优先级队列会提供两个基本的操作,增加元素和出元素,实现优先级别高的元素位于顶部元素。

2025-10-12 21:52:46 594

原创 Java数据结构 - 二叉树

二叉树是一种非线性的数据结构,每一个节点的孩子节点不超过2个(度不超过2),通常会定义一个根节点root,一个节点可以有左孩子节点 left 和右孩子节点 right;如果一棵二叉树从上到下,从左往右(除最后一层)的每一个节点都有两个孩子节点(最后一层节点度为0),这样的一棵二叉树可以称为满二叉树;一棵二叉树有n个节点,深度为K,深度为K,有N个节点的满二叉树从上到下,由左往右 0 - N 编号,有且仅当这一棵二叉树的n个节点与这一棵满二叉树从0 - n的编号一一对应时,这样的一棵二叉树可以成为。

2025-10-07 18:32:38 976

原创 Java数据结构 - 队列的模拟实现和使用

队列是一种先进先出的线性数据结构,在底层是使用链表实现,有队头和队尾,在队头进行出队列操作,在队尾实现进队列操作。队列中常见的方法如下:队列Queue是一个接口类型,不能实例化对象,在使用时通常创建LinkedList对象,使用Queue类型的引用接收,相关接口的关系图如下:队列方法的使用//1.实例化LinkedList对象//2.方法的使用//offer方法:入队列//此时的队列元素 1 -》 2 -》 3//获取队列中的元素个数。

2025-10-04 15:47:24 3997

原创 Java数据结构 - 栈的模拟实现和使用

栈在数据结构是一种先进后出的数据结构,有栈顶和栈低,常见的的方法如下:功能的使用//push方法:将元素加入栈中//栈底元素//栈顶元素//判断栈是否为空//false//获取栈中元素个数//2//pop方法:将栈顶元素从栈中出去//2出栈//1出栈//判断是否为空//true//获取元素个数//0。

2025-09-29 12:25:16 636

原创 Java数据结构 -双链表的模拟实现

双链表是数据结构链表(LinkedList)中的其中一种,由不同的节点连接而成,节点的构成主要由三部分:val(节点值),next(下一个节点),prev(上一个节点),在实现时会定义head(头节点)和last(尾节点),与顺序表相比,在插入元素时时间复杂度可以达到O(1),明显提高增加元素的效率,在空间的分布上,不一定是连续的存储空间,元素的查找主要通过遍历节点,所以在查找效率上时间复杂度为O(n)。

2025-09-24 17:38:28 309

原创 Java数据结构 - 单链表的模拟实现

单链表是数据结构链表中的其中一种,与之对应的还有双链表,此处模拟实现的单链表主要实现其增删查改,搜索,遍历等功能。

2025-09-19 15:03:41 813

原创 Java数据结构 - 顺序表模拟实现与使用

顺序表在内存中的存储是连续的,它是线性表中的其中一种,使用顺序表可以对数据进行增删查改。

2025-09-07 21:46:26 894

原创 Java SE - 图书管理系统模拟实现

图书管理系统的对象有普通用户和管理员,可以通过登录系统进行选择,对于普通用户可以操作的对象是书架上的图书,可以查询,展示,借阅,归还,退出等操作,而管理员操作对象也是书架上的图书,可以对图书进行查找,展示,增加,删除,退出图书系统的操作,以上就是简单设计框架。1.实现一个书籍类,成员变量有书名,作者,类型,价格,书籍的情况(是否借出),这一些成员变量除了书籍的情况,其它都用private修饰,完成封装,使用set或get方法完成初始化或获取,重写toString方法,可根据需求修改。

2025-06-23 21:57:02 1081

原创 Java SE -异常

一个异常通常表示一个对应的类,每一个异常都有自己的.java为后缀的文件,当使用当前的异常不符合当前处理的问题,就可以使用自定义异常。例如:实现一个密码输入异常。1.定义一个PassWordException的类,继承于Exception这个类,在类中定义构造方法,并完成父类的构造。2.定义一个密码类,定义一个密码变量并赋值,类中可以定义一个匹配方法,如果匹配失败,可以抛出异常原因,使用自定义的类。//密码//声明异常//密码不匹配,输出原因if(!

2025-06-22 16:53:12 843

原创 Java SE - String自定义类型

String方法介绍。

2025-06-19 20:25:56 1072

原创 Java SE - 抽象类和接口

抽象类也是类的一种,与普通类的区别在于抽象类需要被abstract关键字修饰,抽象类中也可以有方法和成员变量,但是抽象类中的方法都是抽象方法,抽象方法是被abstract修饰的方法,与普通方法的区别在于抽象方法不会有具体的实现,只进行方法的声明,具体方法由继承的子类实现,继承的子类必须将父类的抽象方法全部重写,否则继承的子类也是一个抽象类。此时就完成深拷贝,通过拷贝对象的引用修改类中指向的对象,不会修改原有引用指向的对象,即通stu1中引用指向对象的修改,不会改变stu中引用指向对象的值。

2025-06-18 17:07:10 867

原创 Java SE - 继承与多态

执行的是子类的重写方法,因为在完成构造方法是,调用的方法是重写的,此时会发生动态绑定,实际上调用的是子类重写的方法,此时num因为构造方法还未执行完,并未完成初始化,输出的是默认值0;多态简单理解就是多种形态,当同一个行为或者属性展示的对象不一样时,呈现的状态就不一样,例如:Animal作为父类,存在子类Dog和Cat,父类存在一个eat() 的成员方法,当对象是Dog时就是吃狗粮,当对象是Cat时就是吃猫粮,对象不同,呈现的状态就不一样,此时就发生了多态。被final修饰的方法不可被重写;

2025-06-12 17:25:49 955

原创 Java SE - 类和对象入门指南

protected和private不能修饰直接类,一般用于修饰类中的成员变量和方法,protected的使用与public类似,区别在于protected修饰的在不同包中只能被子类中使用,private修饰的成员和方法只能在类中使用。Java是一门面向对象的语言,其中三大特性是封装,继承和多态,而封装就是类和对象中的一大特性,使用封装可以使类中的成员变量或方法不被直接的访问,在类中使用方法获取封装成员变量或方法,在实例化对象的过程中,通过引用间接的访问封装成员变量或方法,有效的保护类内部的具体实现过程。

2025-06-11 16:41:28 1001

原创 Java SE - 数组

Arrays是一个类,其中包含多种方法,以上调用的是toString重载的方法,参数类型是char[]。创建一个数组时,使用new关键字开辟的空间是在堆区上的,此时数组名相当于一个引用,存放开辟空间的地址。方法区用于存放虚拟机加载的类信息,静态变量,常量等数据,方法编译后的字节码文件存储该区域。本地方法栈与虚拟机栈的功能类似,本地方法栈存放的是native修饰的方法;引用的作用是通过引用可以找到引用所指向的对象,访问对象中的成员变量。虚拟机栈用于存放方法调用时开辟的栈帧,方法调用结束栈帧销毁;

2025-06-10 18:29:56 381

原创 C语言 — 通讯录模拟实现

include "contact.h"//包含自定义头文件。

2025-06-08 11:06:17 2182

原创 C语言 — 编译和链接

调用函数时会开辟运行时堆栈(即函数栈帧的创建),一般函数是从main函数进入,在开辟过程会保存局部变量和函数的地址,全局或静态变量会存储于静态区,直到函数销毁而销毁,最后随main函数的结束而终止程序 ,并输出结果。汇编过程是将汇编代码转换为二进制代码,每一条汇编语句都代表一条指令,将汇编语句与机器语句通过对照表转换,不做任何优化,通过以下指令将test.s的文件转换为test.o的目标文件。语义分析阶段是对语法层面的意思进行转换,包括声明,类型的匹配和转换等,此时会报告错误信息,经过语义分析后的语法树。

2025-06-05 15:46:34 1065

原创 C语言 — 文件

第一个参数数据存放位置的起始地址,第二个参数是元素的大小,第三个参数是读取的个数,第四个参数是读取数据的文件起始地址,返回类型是size_t。第一个参数是写入数据的起始地址,第二个参数是元素的大小,第三个参数是个数,第四个参数是文件起始地址,返回类型是size_t.第一个参数是文件流,第二个参数是数据的格式,第三个参数是对于的变量,返回类型是int。fflush是将文件缓冲区的数据进行刷新,对于文件输入流的数据,终止读取,对于文件输出流的数据进行写入,函数的参数是文件指针,返回类型是int。

2025-06-01 21:06:30 1035

原创 C语言 — 动态内存管理

int arr[0];//柔性数组sizeof计算时不会包含柔性数组的大小。char ch[0];//柔性数组int main()return 0;

2025-05-31 18:27:54 1636

原创 C语言 — 自定义类型(结构体,联合体,枚举)

在结构体的传参中,一般使用的是传址调用,因为如果采用传值调用,函数调用时会开辟函数栈帧,为函数的参数开辟临时的空间,当结构体成员比较多时,会占用较大的内存空间,程序的运行会消耗更多的时间,消耗较大的性能,因此在结构体的传参中一般使用结构体指针传参,占用的空间是4个字节,开辟的函数栈帧内存空间较小,可以有效提高程序性能。按F10执行输出语句,输出结构体的大小4,因为占用同一内存空间,开辟的大小是4字节,成员的最大对齐数是4,此时大小为4的整数倍,最终输出4.在结构体声明后,创建全局变量后赋值;

2025-05-31 14:57:18 782

原创 C语言 — 内存函数和数据的存储

假设数组元素是1 - 10,拷贝4个元素,将第二元素起的4个元素拷贝到数组前4个元素,如果是从后往前拷贝,预期拷贝的数据是 3 4 5 6 5 6 7 8 9 10,实际上拷贝的结果是5 6 5 6 5 6 7 8 9 10,这是因为,目标数据的后两个元素被源头数据的后两个元素覆盖,当源头数据使用前两个元素时,此时的3 和 4 数据已经被拷贝成 5 和 6 ,导致目标数据的前两个元素也是拷贝5 和 6。memmove函数拷贝的可以是有重叠的内存空间,如在同一个数组中拷贝。

2025-05-24 16:43:49 1165 1

原创 JAVA SE — 循环与分支和输入输出

i 是从1开始进入循环的,满足第一次while循环的表达式,进入while循环的内部语句,遇到第二次while循环,满足表达式,进入第二次while循环的内部,i++,一直循环到不满足第二层while循环的表达式,即 i 不等于5,跳出第二次while循环时,i 等于5,判断if语句的表达式,不满足,到输出语句,输出5和空格,i++变为6,重新进入第一层while循环,满足 i < 10,进入第二层while消耗会,满足判断条件,i一直++,满足i!,输入Random后回车,会自动生成导包需要的文件。

2025-05-22 23:44:26 664

原创 C语言—字符函数和字符串函数

strtok函数是将指定字符串中的分隔符替换为\0,第一个参数是字符串起始位置,第二参数是分隔符的地址,第一次调用,如果字符串有指定分隔符,返回字符串起始位置的地址,再次调用时,第一个参数为NULL,如果字符串中找到指定分割符,将分隔符替换为\0,返回上一次替换分隔符位置的下一位置,如果调用时查找的字符串没有指定分隔符,返回空指针。strcpy函数是将源头字符串拷贝到目标字符串中,第一个参数是目标字符串的起始地址,第二个参数是源头字符串的起始地址,返回的参数是char*类型,返回的是目标字符串的起始地址。

2025-05-19 23:28:16 877

原创 C语言—指针4

2.数组名单独放在sizeof内部,此时的数组名是代表整个数组,求出整个数组的大小,在sizeof内部对数组名取地址时,同时解引用操作,也是表示数组名单独放在sizeof内部,sizeof(*&arr)=sizoef(arr);无法正常的输出全部结果,因为第三次打印时传递的strlen函数接收的地址不是真实的地址,导致程序终止,可以调试观察,按F10进入调试,打开监视窗口,按F10逐过程观察。输出结果:在x64的环境下输出,指针大小为8个字节。输出结果:在x64环境下输出,指针大小为8个字节。

2025-05-16 18:25:12 336

原创 C语言中函数指针数组的应用,qsort函数的使用和基于冒泡排序思想对qsort函数的模拟实现

因为模拟实现的qsort函数需要排序的类型不只排序整型,还要排序结构体或者字符串等类型的数据,因此可以考虑将交换的元素类型转换为最小的内存单位数据类型char*,指向的位置访问一个字节,强制类型转换后需要对比相邻元素的大小,但是指针指向只能访问一个字节的大小,为了能比较相邻元素,在强制类型转换后在其后加上j*width或(j+1)*width,此时指向的就是相邻两个元素的起始位置。冒泡排序的主要思想是通过相邻元素的对比进行交换,需要确定排序的躺数,及每一趟排序需要交换的次数,先实现一个简单的冒泡排序。

2025-05-14 10:37:43 886

原创 Java SE所需工具与常见类型和运算符介绍

设置好一些设置后,可以开始编写java程序,可以先了解一些Java程序一个常见的模板,public class 的对类的声明,Main为创建的文件名,public static void main(String[] args)中的main区别于c语言中的main函数,此处的main表示的是Main这个类中的一个方法,main大括号内的是语句,与C语言中的语句类似,但是格式上可能有所区别。JRE是Java程序运行时所需的的环境,通过它,Java的开发者可以将自己开发的程序发布到用户手中,提供给用户使用。

2025-05-13 00:10:53 623

原创 C语言—指针3

假设需要排序的的元素有2个:2,1,只需要交换一趟,一趟交换一次,如果有3个元素:3,2,1 ,第一趟需要3和2交换:2,3,1,再将3和1交换,2,1,3;由此可得,在排序过程中,大的数据往下沉,小的数据往上浮,就像气泡一样,于是将这种排序算法形象地称为冒泡排序。可以观察到,pc1与数组名指向的位置的相同,但是此时pc1等于&ch,表示的是整个数组的地址,pc2为&ch+1,输出的地址指向数组后的地址,与首元素地址相差7byte,&arr是数组的地址,+1 操作是跳过整个数组的。

2025-05-09 21:31:44 895

原创 C语言—指针2

第一次交换并没有成功交换,输出的结果还是num1=10 num2=20,这是因为Swap1函数接收的函数参数时,开辟了新的内存空间进行存num1和num2,改变的为x和y形参的的值,,函数栈帧销毁时,x和y的值并不能存储返回,因此x和y只是实参的一份临时拷贝,改变形参并不一定改变实参;第二次交换交换成功,将num1和 num2的地址作为参数传参时,接收的函数参数改变时,是通过地址指向的位置改变,x指向num1的地址,y指向num2的位置,此时改变形参可以改变实参。结论:const修饰指针变量的时候。

2025-05-08 20:10:01 625

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除