【代码随想录】二叉树(4)
二叉树完全二叉树的节点个数给定一个完全二叉树,求节点个数。
完全二叉树从数组的形式上看就是中间没有空节点 root = [1,2,3,4,5,6]
首先想到的自然是层序遍历,完全二叉树的结构和层序遍历太契合了,一旦我们发现空节点立刻就能返回。
class Solution { public int countNodes(TreeNode root) { if(root == null) { return 0; } LinkedList<TreeNode> list = new LinkedList<>(); list.offer(root); int n = 1; while(!list.isEmpty()) { TreeNode node = list.poll(); if(node.left == null) { r ...
【代码随想录】二叉树(3)
二叉树二叉树的最大深度给定一个二叉树,找出其最大深度。
之前用一种较为曲折的方式解二叉树的层序遍历时貌似已经实现过求二叉树的最大深度。最容易想到的还是递归。
import static java.lang.Math.max;class Solution { public int maxDepth(TreeNode root) { return digSeek(root, 0); } public int digSeek(TreeNode node, int depth) { if(node == null) return depth; int left = 0; int right = 0; if(node.left != null) { left = digSeek(node.left, depth + 1); } if(node.right != null) { ...
【操作系统】实现一个简单文件系统
实现一个简单文件系统前言
这是操作系统实践课程的一个实验作业,让我们在虚拟磁盘上实现一个简单的文件系统,我认为有一定的难度,虽然是小组完成(幸好组里有大佬)。
现在已经是假期了,重新把这个简单文件系统的实现梳理一遍。(平时没时间)(~~ 要被划掉的内容 ~~)
首先来说,把一些重要的数据结构体看一下。
主要结构体
目录(Direction)和目录项(Direction Entry)分别是什么?
目录简单来说就是文件夹,目录中有若干目录项,目录项可以是文件或者子目录,目录将文件组织成树形结构,目录项中包含一些文件的元信息(文件索引号、文件名、父目录等),通过文件索引号可以找到索引节点inode,而索引节点中保存了文件存储的磁盘块号,于是就能读取到文件数据。
下面的两张图有助于理解我们这个简单文件系统实现,但是要注意,这两张图是inode的实现,而我们这个采用的是FAT,还是有区别的。
UserOpen图2中每个进程都有自己的files_struct文件打开表,用于管理进程打卡的文件,文件打开表的索引称为文件描述符fd。这里以链表的形式实现文件打开表。
typedef struct ...
【代码随想录】二叉树(2)
二叉树前言:之前临近期末实在没精力写博客了 :face_with_head_bandage: (原谅我吧),最近把随想录的算法题再整理一下。
二叉树的层序遍历二叉树的层序遍历在我印象中就是按照每层从左到右一个一个遍历过去,这里的输入是一个包含空的数组,输出则是一个二维数组,其中的元素表示每层。
输入:root = [3,9,20,null,null,15,7]输出:[[3],[9,20],[15,7]]
这里的输入只是一个示意,实际输入的是一个根节点
每行的数组长度是不确定的,所以我打算采用ArrayList的add方法动态增加元素
搜索同一层结点的时候就是关键
先用最容易想到的方法,访问一层第n中的每个节点都从根节点开始,访问n次
/** * 输入当前子树的根节点和树高n,将子树的n高的节点的值存入ArrayList中 * @param cur * @param n * @param list */public void addList(TreeNode cur, int n, ArrayList<Integer> list) { if(n == 1 ...
【初探Linux】窥探Read系统调用源码2
系统调用—Read
read源码搜索sys_read:https://elixir.bootlin.com/linux/v6.8.1/source/fs/read_write.c#L627
上一篇已经对read系统调用的源码进行了一定程度的初步解读,那么我又产生了新的疑问:read的具体实现是有多种的,系统应该是会根据不同的文件采取对应的读取方式的,也就是说会调用不同的read具体实现,那么系统具体是如何实现的?于是便有了这篇博客。
// fs/read_write.c// 输入参数:// fd:文件描述符(用户进程打开的文件句柄)// buf:用户空间缓冲区指针(数据将被读取到这里)// count:请求读取的字节数// 输出结果:读取到的字节数SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count){ return ksys_read(fd, buf, count);}ssize_t ksys_read(unsigned int fd, char __user *buf, ...
【初探Linux】窥探Read系统调用源码
系统调用—Read
read简介系统调用read的作用是:从与文件描述符fd相关联的文件中读取 n bytes个字节的数据,并把它放入到数据缓冲区buf中。
概要:
read函数在<unistd.h>头文件中定义。
原型是:ssize_t read(int fd, void *buf, size_t count);
说明:
read()函数尝试从文件描述符fd中读取count个字节到buf开头的缓冲区中。
如果count=0;read返回0,并且没有其他结果,如果count>SSIZE_MAX,结果未指定。
ssize_t:有符号整型,与long类似。typedef long size_t
size_t:无符号的ssize_t,:typedef unsigned long size_t
返回值
调用成功返回读取的字节数,文件指示符指到对应的位置。这个返回值可能会比count,比如以下情况:
当文件的整体字节比count小时,读到文件尾。
我们从管道或者终端读取
我们读取时被一个信号打断了等等情况。
调用失败的时候返回-1;并且errno会被设置,这时候文件的 ...
【初探Linux】文件压缩和打包
文件压缩和打包这里主要看zip和tar
zip适合于需要压缩并打包的场景,特别是在Windows环境下;而tar通常用于Linux/Unix系统中,适合打包大型目录,并且与不同的压缩工具搭配使用。一下是常见的用法:
zip test.zip test #zip 压缩文件名 原文件夹 (只包含文件夹test)zip test.zip test -r #zip 压缩文件名 原文件夹 包含test文件夹中所有文件unzip test.zip -d ziptesttar -cf test.tar test # 压缩文件tar -xf test.tar -C tardir # 解压缩到指定目录(不指定默认当前目录,会覆盖文件)
以下是一个实验,按照要求使用命令完成。
A. 将位于当前用户(shiyanlou)家目录下的03.tar.gz压缩文件中所有的html文件(包括所在目录)解压并解包到当前用户(shiyanlou)家目录下的Desktop目录中。mkdir temptar -xzf ~/03.tar.gz -C ~/tempfind temp -name '*html ...
【初探操作系统】进程管理
理解Linux进程进程概念我对于程序已经有了一定程度的认知——一段指令集合。那么进程又是什么,进程不应该就是一种程序吗?一个经典的例子,把程序比喻成菜谱,记录了做一道菜的过程,那么进程就是动手做出一道菜的过程。可以说,进程就是执行的程序,程序的一次执行。
程序是静态的,进程是动态的实体
进程是操作系统进行资源分配和调度的基本单位。每个进程都有独立的内存空间、文件描述符、环境变量等资源,进程之间相互隔离,互不干扰。
进程具有并发性,也就是说,程序的执行并不一定是顺序的,是并发的,并发能够极大提高了程序的执行效率和资源利用率,于是引入线程的概念。
线程(Thread) 是进程中的一个执行单元,是CPU调度的基本单位。一个进程可以包含多个线程,这些线程共享进程的内存空间和资源,但每个线程有自己的栈和程序计数器。
多线程编程可以提高程序的并发性和响应性,但也需要注意线程安全问题(如竞态条件、死锁等)。
进程状态创建(New):进程正在被创建。
就绪(Ready):进程已准备好运行,等待CPU分配时间片。
运行(Running):进程正在CPU上执行。
阻塞(Blocked):进程等待某些 ...
【初探Linux】系统调用函数开发
Linux内核系统调用开发流程?
省流:
1、kernel/sys.c里实现函数
2、Include/linux/syscalls.h在系统调用表里声明
3、arch/x86/entry/syscalls/syscall_64.tbl里映射:462 ——> sys_get_process_memory_info
4、make clean && make -j$(nproc)编译内核
5、make install && update-grub安装新内核,更新GRUB
获取源码:从Linux官网或Git仓库克隆内核源码。
环境准备:安装编译工具和相关依赖。
配置内核:使用make menuconfig等工具配置内核选项。 *****这一步就是开发过程
编译内核:通过make命令编译内核和模块。
安装内核:使用make install安装内核和make modules_install安装模块。
更新引导程序:更新GRUB配置,确保系统使用新内核。
测试内核:重启并验证新内核是否正 ...
【初探Linux】文件结构及基本操作
Linux文件结构文件组织结构:目录树状结构,FHS(Filesystem Hierarchy Stardard)标准
在Linux系统中,常见的文件夹及其全称如下:/bin - Binary(可执行文件):包含系统启动和日常操作所需的基础命令程序。/boot - Boot(启动文件):包含启动加载程序文件和系统启动所需的内核文件。/dev - Devices(设备文件):存放设备文件,用于与硬件设备交互。/etc - Etcetera(配置文件):存放系统的配置文件和管理脚本。/home - Home(用户目录):包含所有用户的个人文件夹。/lib - Library(库文件):存放共享库文件,支持程序运行。/lost+found - Lost and Found(丢失和找到的文件):用于存放通过文件系统修复过程中恢复的文件。/media - Media(可移动存储设备):挂载可移动存储设备的默认位置,如CD、USB等。/mnt - Mount(挂载点):用于临时挂载文件系统。/opt - Optional(可选程序包):包含额外的应用程序包,一般是第三方软件的安装目录。/proc ...