C#语言高阶开发

目录

数据结构

集合

动态数组ArrayList

习题:声明一个Monster类,有一个Attack方法,用一个ArrayList去封装Monster的对象,装10个,遍历monster的list让他们释放攻击方法

哈希表HashTable

创建一个武器类,有一个属性叫做id,每个武器对象的id不一样,创建10把武器,把这10把武器通过id,存储在哈希表中,可以通过id在哈希表中找到对应的武器

栈Stack

栈在游戏开发中的应用

队列Queue

游戏开发中的应用

泛型

手动输入一组数列(可任意长度),并对这个数列进行排序,每次提示用户输入:1、添加一个数字;2、排序并显示数列

书写一个怪物(Monster)类,在怪物类的构造中将其添加到一个静态列表,以怪物类做为基类派生Boss和Gablin的对象产生不用的攻击行为(多态),可以写一个方法,让怪物按攻击力进行排序从小到大。

字典

书写一个方法,可以把输入的数字转换成中文数字

委托

老师们会在下课时打铃(事件) 学生们想在打铃事件发生的时候做自己的事情;小明想在打铃的时候去买东西吃;小张想在打铃时去打水;小红想在打铃时去打羽毛球

事件

观察者模式

匿名委托与Lambda表达式

有一个int类型的List,升序排序和降序排序,不能使用List的Sort方法,只能自己写一个排序的方法,通过委托传递方法变量去改变排序的逻辑

匿名方法

Lambda表达式 匿名方法的升级

泛型委托

Action的演示

Func的演示


数据结构

描述数据之间的关系

行为:添加数据、删除数据、插入数据、查找数据

追加数据:向结构的末尾添加一个数据

删除数据:向结构中删除指定的数据

插入数据:向结构中某位置插入指定的数据

查找数据:可以查找并访问到该数据

修改数据:对该结构指定的数据进行重新赋值

线性、链式、树状、图形、散列

链式,是非连续的内存空间,是每个数据分成三部分

头、数据、尾,每个数据的尾部连接下一个数据的头部

所以在内存不是连续的空间,而是一个一个的空间,通过头尾地址连接在一起

集合

Collection是C#写好的数据结构类库

ArrayList、HashTable、Stack、Queue

如果你是用这些数据结构类的模板,要先引用System.Collections;

就可以通过类名去实例化它的对象

动态数组ArrayList

是封装过后的数组,里面的元素容器为Object类型

这样ArrayList就适用于所有的数据类型

因为Object类型是所有类的父类,又因为里氏转化原则,父类可以装载子类,所以ArrayList可以装载所有数据类型

属性:

Count:记录当前拥有多少个元素

Capacity:记录当前可以包含多少元素

方法:

添加.Add(Object value)    把当前这个对象添加到数组中

删除 .Remove(Object value) 查询此元素,并移除第一个匹配的元素项

.RemoveAt(int index) 根据下标号移除该元素

插入 .Insert(int index ,Object value) 把对应对象插入到对应的下标

访问/修改:通过索引器下标号

排序:Sort();

反转:Reverse();

检测是否包含:Contains(Object value)

检测该集合是否包含改元素,如果包含返回true,不包含返回false

查找索引.IndexOf(Object value)

找到第一个匹配该元素的下标号并返回

如果没找到,则返回-1

习题:声明一个Monster类,有一个Attack方法,用一个ArrayList去封装Monster的对象,装10个,遍历monster的list让他们释放攻击方法


internal class Monster{public string name;public Monster(string name){this.name = name;}public void Attack(){Console.WriteLine("{0}攻击了", name);}}static void Main(string[] args){ArrayList monsterList=new ArrayList();for(int i=0;i<10;i++){monsterList.Add(new Monster("第"+i+"号哥布林"));}for (int i = 0; i < monsterList.Count; i++){if(monsterList[i] is Monster){(monsterList[i] as Monster).Attack();//ArrayList装载的是Object类型,需要里氏转换原则}}}

哈希表HashTable

也是System.Collections集合下的数据结构类

它储存的也是object类型的对象,但是它在内存中是散列排布

因为这个特性,非常适合存储大量的数据

在HashTable中一个键只能对应一个值,一个值可以对应多个键,多对一的关系

HashTable存储的是<键,值>对

HashTable table=new HashTable();

属性:

Count:HashTable包含的键值对的数目

Keys:HashTable中键的集合

Values:HashTable中值的集合

方法:

增删改查

Add(key,value)在哈希表中添加一对键值对

Remove(key)删除键值

因为一个值有可能对应多个键,这样就不能把整个键值对删除掉

只要没有键指向这个值,就会自动被释放掉,所以只需要删除键值就可以了

Contains(key)检测是否包含此键值对

ContainsKey(key)检测是否包含此键

ContainsValue(value)检测是否包含这个值

访问,索引器[键]

在内存中散乱排布,用foreach去遍历键

foreach(var key in table.keys)

{

Console.WriteLine(hashtable[key]);

}

创建一个武器类,有一个属性叫做id,每个武器对象的id不一样,创建10把武器,把这10把武器通过id,存储在哈希表中,可以通过id在哈希表中找到对应的武器

static void Main(string[] args){Hashtable table=new Hashtable();//假设有一把武器,叫霜之哀伤,id为123//并把霜之哀伤放进我的武器目录里Weapon a = new Weapon("霜之哀伤");table.Add("123",a);table.Add("456",a);Console.WriteLine(table["456"]);}internal class Weapon{public string name;public Weapon(string name){this.name = name;}public override string ToString(){return name;}}

栈Stack

也是System.Collections下的数据结构类,存储的依然是Object 类型的对象

Stack stack=new Stack();

Count:实际拥有的元素个数

栈的释放顺序是先进后出

压栈——Push(Object 对象)把这个对象添加到栈的顶部

弹栈——Pop()把栈顶的元素弹出来,会删除

Peek() 返回栈顶的元素,不删除

在遍历弹栈的时候要注意,pop方法会删除你的对象,导致Count属性发生改变,

所以,应该用一个变量存储一下一开始的Count值,根据这个变量,来弹栈就可以把栈中所有的数据弹出去

Stack stack = new Stack();

            for(int i=0;i<10;i++)

            {

                stack.Push(i);

            }

            int static_Count=stack.Count;

            for(int i=0;i<static_Count;i++)

            {

                Console.WriteLine(stack.Pop());

            }

栈在游戏开发中的应用

用来实现”返回/撤销”功能。可以将每一步的操作或者是坐标信息加入到stack中,当玩家按下返回/撤销键时将上一步操作从栈中移除并根据其中的信息在游戏中反向操作

常常被用到在游戏”状态/窗口/场景”管理中。在游戏中,往往会有多个窗口叠加在一起,或者从一个场景进入到子场景。这时,通过在进入“新场景/打开新窗口”时,将这个”场景/窗口”加入到stack中,玩家选择返回时再从栈中弹出并销毁,所有的事件和操作都只对当前的顶端的窗口生效

队列Queue

是System.Collections下的数据结构类,存储Object类型的对象

Queue queue=new Queue();

队列的释放顺序:先进后出

属性

Count:该结构包含的元素个数

方法:

EnQueue(Object value)进入队列的末尾处

DeQueue() 返回并移除队列最前面的那个元素

Peek() 队列中队首的元素返回,但不删除

游戏开发中的应用


回合制游戏中的行动顺序队列(Turn Queue)
回合制和半回合制游戏中常常有速度、行动力的概念来决定场上所有单位的行动顺序,这个时候可以通过队列来安排。当然,很多游戏中会有提升或降低速度的技能和物品,这个时候会需要重新生成队列。

管理经营类游戏中的生产队列
很多管理经营类游戏,或者即时战略游戏中都会有生产队列的概念。通过使用队列来提前规划之后的生产顺序可以使玩家操作起来更为方便。一个典型的例子就是文明系列中在城市里的生产列队,提前安排之后需要生成的单位或设施,将后续需要制造的东西依次加入队列,当当前生产任务完成时,从队列中移除并获取下一个需要生成的单位。

行动队列
很多及时战略游戏和MOBA类游戏中都有用队列提前安排之后的行动的功能。例如DotA中可以在TP的时候按住Shift将跳刀加到行动队列中实现落地瞬间跳走,沙王施法前摇时将跳到放到队列中实现跳大等操作。

剧情对话
当剧情对话会因为玩家的选择产生分支的时候,常常需要用树结构来储存,但归根结底,这可以被当作一种非线性的队列。实际运行的时候,还是可以用Queue来储存和操作正在播放的剧情文字,分支产生并被选择以后再将该分支下的对话加入到队列中。

动画播放,多节点移动
游戏动画中,有时候会有沿着一系列节点移动的操作,这个过程可以使用队列来完成,将所有节点按照顺序加入队列,然后用dequeue获取并移除队列顶端的点来实现按照相同顺序移动。

消息、事件的传输和分发
一些网游或者多进程的单机需要用接收、处理从网络或其他进程传入的指令和消息,而当本地在处理消息的时候,其他陆续传入的消息将在队列中等待,然后当前一个任务执行完毕后从队列中获取下一个需要被执行的指令或需要处理的消息。

泛型

因为在编程中想先不定义数据类型,只想先写逻辑,可以使用Object类型,这样逻辑就适用于所有类型,但是,在运行中,Object类型的变量会需要转换到对应类型,浪费资源,所以出现泛型,代替Object类型的方案

使用泛型,可以延迟定义数据类型,来编写程序

泛型是一种将逻辑应用到不同数据类型上的机制,可以通过类型代替符来暂时代参数的数据类型,这样只需要在编译的时候,编译器会自动将替代符编译成对应数据类型来处理

泛型方法

    定义泛型方法

    访问修饰符 返回类型 方法名<T,U>(T 参数,U参数){}

可以在方法名后使用<类型替代符>来定义一个泛型方法

手动输入一组数列(可任意长度),并对这个数列进行排序,每次提示用户输入:1、添加一个数字;2、排序并显示数列

static void Main(string[] args){List<int> list = new List<int>();list.Add(1);     list.Add(4);list.Add(8);list.Add(2);list.Add(3);list.Add(9);list.Add(5);list.Add(6);list.Add(7);list.Add(10);Console.WriteLine("提示:用户输入1,可添加一个数字;如果用户输入2,排序并显示此数列");int a=int.Parse(Console.ReadLine());if(a==1){list.Add(a);}if(a==2){list.Sort();for(int i=0;i<list.Count;i++){Console.WriteLine(list[i]);}}}

书写一个怪物(Monster)类,在怪物类的构造中将其添加到一个静态列表,以怪物类做为基类派生Boss和Gablin的对象产生不用的攻击行为(多态),可以写一个方法,让怪物按攻击力进行排序从小到大。

static void Main(string[] args)

        {

            for(int i = 0; i < 10; i++)

            {

                new Goblin("第" + i + "号哥布林");

            }

            new Boss("拉格拉罗斯");

            //Console.WriteLine(MonsterManager.monsterList[1]);

            for (int i = 0; i < MonsterManager.monsterList.Count; i++)

            {

                MonsterManager.monsterList[i].Attack();

            }

        }

internal class MonsterManager

    {

        public static List<Monster> monsterList = new List<Monster>();

        public static Random r=new Random();

    }

    class Monster

    {

        public string name;

        public int attack;

        public Monster (string name)

        {

            this.name = name;

            MonsterManager.monsterList.Add(this);

        }

        public virtual void Attack()

        { }

        public override string ToString()

        {

            return String.Format("{0}/攻击力,{i}",name,attack);

        }

    }

    class Goblin : Monster

    {

        public Goblin(string name) : base(name)

            //先去执行base指向的public Monster (string name),

            //已经把name的赋值了,再执行自己的攻击

        {

            attack =MonsterManager.r.Next(50,100);

        }

        //用overrider关键字重写Attack()方法

        public override void Attack()

        {

            Console.WriteLine("{0}丢了一块石头,砸人特别疼",name);

        }

    }

    class Boss:Monster

    {

        public Boss(string name):base(name)

        {

            attack=MonsterManager.r.Next(200,500);

        }

        public override void Attack()

        {

            Console.WriteLine("{0}一口炎爆术喷了出来,特别吓人", name);

        }

}

字典

书写一个方法,可以把输入的数字转换成中文数字

把123转换为:壹贰参. Dictionary<char,char>

思路:建立一个0-9的字典,作为key存储,对应value壹贰参,输入参数作为键在字典里查找,再把值保存下来

internal class Program

    {

        static void Main(string[] args)

        {

            Console.WriteLine("请输入一个数字");

            string input=Console.ReadLine();

            UpperNum(input);

        }

        public static void UpperNum(string input)

        {

            Dictionary<string , string> dic = new Dictionary<string, string>();

            dic.Add("1", "壹");

            dic.Add("2", "贰");

            dic["3"] = "叁";

            dic["4"] = "肆";

            dic.Add("5", "伍");

            dic.Add("6", "陆");

            dic["7"] = "柒";

            dic["8"] = "捌";

            dic["9"] = "镹";

            dic["0"] = "零";

            string result = "";

            for(int i = 0; i < input.Length; i++)

            {

                result = result+dic[input[i].ToString()];

            }

            Console.WriteLine(result);

        }

}

委托

是方法的载体(引用),可以承载(一个或多个)方法

是一种特殊数据类型,专门用来存储方法

所有的委托都派生自System.Delegate类

委托可以让我们把方法当作变量去使用

解决了很多代码冗余的问题,也解决了方法回调的问题

委托的定义

访问修饰符delegate返回类型 委托类型名(参数列表)

委托的变量

委托类型名 委托变量名;

委托类型名 委托变量名=new 委托类型(返回类型与参数列表一致方法)

委托的赋值

在装载方法的时候,不用写小括号

委托变量名=返回类型与参数列表一致方法

委托的调用

委托变量名(参数)

委托变量名.Invoke(参数);

列表的查找速度比链表要快

链表的修改速度要比列表快

回调

把委托变量传入方法中去调用

委托的本质

就是方法引用的队列,先进先出,一旦调用会把队列中所有的方法执行完

委托的注册

委托名+=方法名

就可以将多个方法注册进委托变量中

委托的注销

委托名-=方法名

可以将方法从委托列表中移除

委托变量一旦重新赋值,以前引用的方法全部丢失

可以使用委托变量=null全部清空方法列表

老师们会在下课时打铃(事件) 学生们想在打铃事件发生的时候做自己的事情;小明想在打铃的时候去买东西吃;小张想在打铃时去打水;小红想在打铃时去打羽毛球

static void Main(string[] args)

        {

            Teacher t = new Teacher("王老师");

            Student xiaoming = new Student("小明", "买东西吃");

            Student xiaohua = new Student("小花", "打羽毛球");

            t.RegisterCallEvent(xiaoming.DoThing);

            t.RegisterCallEvent(xiaohua.DoThing);

            t.Call();

        }

delegate void CallDelegate();

    internal class Teacher

    {

        public string name;

        CallDelegate callDel;

        public void RegisterCallEvent(CallDelegate del)

        {

            callDel += del;

        }

        public void LogoutCallEvent(CallDelegate del)

        {

            callDel -= del;

        }

        public Teacher(string name)

        {

            this.name = name;

        }

        public void Call()

        {

            Console.WriteLine("{0}打铃了", name);

            if(callDel != null)

            {

                callDel();

            }

        }

}

internal class Student

    {

        public string name;

        public string thing;

        public Student(string name,string thing)

        {

            this.name = name;

            this.thing = thing;

        }

        public void DoThing()

        {

            Console.WriteLine(name+thing);

        }

}

事件

委托变量如果公开出去,很不安全,外部可以随意调用

所以取消public,封装它,可以自己书写两个方法,供外部注册与注销,委托调用在子方法里调用,这样封装委托变量可以使它更安全,这个叫做事件。

特性:

  1. 外部不能随意调用,只能注册和注销
  2. 只能自己去调用自己的委托

C#为了方便封装委托变量,推出一个特性event事件,在委托变量前用event修饰这个变量,这个委托变量就变成了事件,这样的话,这个委托变量就算公开出去也没有关系,因为外部只能对这个变量进行注册和注销,只能内部进行触发。

观察者模式

模式——视图

发布——订阅

源——收听者

一系列对象来监听另一个对象的行为,被监听者一旦触发事件/发布消息,则被所有监听者收到,然后执行自己的行为

就是使用委托/事件,让一系列对象把它们的行为来注册到我们的委托中

一群对象在观察另外一个对象的行为,当这个对象的行为达成一定条件,则触发了一群对象的反应,要做到以上功能,要搭配事件使用

把一群对象的反应行为注册到被观察的对象的事件中去

匿名委托与Lambda表达式

有一个int类型的List,升序排序和降序排序,不能使用List的Sort方法,只能自己写一个排序的方法,通过委托传递方法变量去改变排序的逻辑

delegate bool SortDel(int a,int b);

    internal class Program

    {

        static void Main(string[] args)

        {

            List<int> list = new List<int>();

            Random r = new Random();

            for(int i = 0; i < 10; i++)

            {

                list.Add(r.Next(1,1000));

            }

            //匿名方法Sort(list,delegate(int a,int b) { return a>b;});

            Sort(list, (a, b) => a < b);//lambad表达式

            for(int i = 0; i < list.Count; i++)

            {

                Console.WriteLine(list[i]);

            }

        }

        public static void Sort(List<int> list,SortDel del)

        {

            for(int i=0; i < list.Count; i++)

            {

                for(int j=0; j < list.Count-1-i; j++)

                {

                    if (del(list[j],list[j+1]))

                    {

                        int temp=list[j];

                        list[j]=list[j+1];

                        list[j+1]=temp;

                    }

                }

            }

        }

    }

匿名方法

和委托搭配使用,方便我们快速对委托进行传参【作用】

不需要我们去定义一个新的函数

直接用delegate关键字代替方法名,后面跟上参数列表与方法体

Delegate(参数列表){方法体}

Lambda表达式 匿名方法的升级

更加简写

(参数列表)=>{方法体}

当你的方法体只有一条语句的时候,可以不写return,甚至可以没有花括号

参数列表的参数甚至可以不写数据类型

如果说方法体里一旦出现了return,一定要加上花括号

泛型委托

自定义泛型委托

delegate T 委托名<T>(T 参数);

C# 提供好了两个泛型委托的模板供我们使用

这两个模板基本上就可以适用于所有的委托

所以其实是不需要我们自定义的

  1. 不带返回类型的泛型委托——Action<类型1,类型2,……,类型n>参数列表对应的参数类型
  2. 带返回类型的泛型委托——Func<类型1,类型2,……,类型n>参数列表的末尾类型是作为返回类型使用

Action的演示

static void Main(string[] args)

        {

Test(100, ActionEvent);

        }

public static void ActionEvent(int a)

        {

            Console.WriteLine(a);

        }

        public static void Test(int num,Action<int> del)

        {

            del(num);

        }

Func的演示

static void Main(string[] args)

{

List<int> list = new List<int>();

            Random r = new Random();

            for(int i=0;i<10;i++)

            {

                list.Add(r.Next(1,100));

            }

            Sort(list,delegate(int a,int b) { return a>b;});

            for(int i=0;i<list.Count;i++)

            {

                Console.WriteLine(list[i]);

            }

}

public static void Sort(List<int> list,Func<int,int,bool> func)

        {

            for(int i=0;i<list.Count;i++)

            {

                for(int j=0;j<list.Count-i-1;j++)

                {

                    if(func(list[j],list[j+1]))

                    {

                        int temp=list[j];

                        list[j]=list[j+1];

                        list[j+1]=temp;

                    }

                }

            }

        }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/191209.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【数据中台】开源项目(3)-Linkis

关于 Linkis Linkis 在上层应用程序和底层引擎之间构建了一层计算中间件。通过使用Linkis 提供的REST/WebSocket/JDBC 等标准接口&#xff0c;上层应用可以方便地连接访问MySQL/Spark/Hive/Presto/Flink 等底层引擎&#xff0c;同时实现统一变量、脚本、用户定义函数和资源文件…

web:very_easy_sql(sql、ssrf、gopher协议sql注入)

题目 页面显示如下 显示不是内部用户&#xff0c;无法识别信息 查看源码&#xff0c;找到一个use.php 访问之后显示如下 随便输入了一个&#xff0c;发现url有参数显示 试一下靶机的网址&#xff0c;返回nonono 联系之前原始页面写的“不是内网用户&#xff0c;无法别识身份”…

【PTA-C语言】实验三-循环结构I

如果代码存在问题&#xff0c;麻烦大家指正 ~ ~有帮助麻烦点个赞 ~ ~ 实验三-循环结构I 7-1 求交错序列前N项和 &#xff08;分数 15&#xff09;7-2 寻找250&#xff08;分数 15&#xff09;7-3 最大公约数和最小公倍数&#xff08;分数 15&#xff09;7-4 统计字符&#xff0…

Redis 发布订阅机制深入探索

Redis 的发布订阅&#xff08;pub/sub&#xff09;机制是一种消息传递模式&#xff0c;允许消息的发送者&#xff08;发布者&#xff09;和消息的接收者&#xff08;订阅者&#xff09;通过一个中介层&#xff08;频道&#xff09;进行通信&#xff0c;而无需彼此直接交互。以下…

231202 刷题日报

周四周五&#xff0c;边值班边扯皮&#xff0c;没有刷题。。 今天主要是做了: 1. 稀疏矩阵压缩&#xff0c;十字链表法 2. 快速排序 3.349. 两个数组的交集​​​​​ 4. 174. 地下城游戏 要注意溢出问题&#xff01;

外包搞了6年,技术退步明显......

先说情况&#xff0c;大专毕业&#xff0c;18年通过校招进入湖南某软件公司&#xff0c;干了接近6年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试&#xf…

vue项目报错及解决npm run build:prod打包错误

vue项目报错及解决npm run build:prod打包错误 执行dev环境时加载失败了该变量&#xff0c;在package.json文件中 删掉 解决方法&#xff1a; 打包成功&#xff1a;

使用 OpenFunction 在任何基础设施上运行 Serverless 工作负载

作者&#xff1a; 霍秉杰&#xff1a;KubeSphere 可观测性、边缘计算和 Serverless 团队负责人&#xff0c;Fluent Operator 和 OpenFunction 项目的创始人&#xff0c;还是多个可观测性开源项目包括 Kube-Events、Notification Manager 等的作者&#xff0c;热爱云原生技术&am…

Hdoop学习笔记(HDP)-Part.16 安装HBase

目录 Part.01 关于HDP Part.02 核心组件原理 Part.03 资源规划 Part.04 基础环境配置 Part.05 Yum源配置 Part.06 安装OracleJDK Part.07 安装MySQL Part.08 部署Ambari集群 Part.09 安装OpenLDAP Part.10 创建集群 Part.11 安装Kerberos Part.12 安装HDFS Part.13 安装Ranger …

MathType 7.5.2中文版软件使用期到了怎么办?

MathType 7.5.2中文版作为一款专业的公式编辑器&#xff0c;MathType受到很多人的青睐&#xff0c;它可以将编辑好的公式保存成多种图片格式或透明图片模式&#xff0c;可以很方便的添加或移除符号、表达式等模板&#xff08;只需要简单地用鼠标拖进拖出即可)&#xff0c;也可以…

基于SpringBoot蜗牛兼职网的设计与实现

摘 要 随着科学技术的飞速发展&#xff0c;社会的方方面面、各行各业都在努力与现代的先进技术接轨&#xff0c;通过科技手段来提高自身的优势&#xff0c;蜗牛兼职网当然也不能排除在外。蜗牛兼职网是以实际运用为开发背景&#xff0c;运用软件工程原理和开发方法&#xff0c…

css中元素水平居中的方式

文章目录 前言水平居中&#xff1a;垂直居中方法一: text-align: centerdisplay: table-cell方法二:父元素静态定位子元素通过相对定位来实现方法三:通过静态和相对定位方法四 css图片居中用text-align:center无效怎么回事&#xff1f;如何让图片在DIV中水平和垂直两个方向都居…

接口自动化测试思路和实战之模块化测试脚本框架

模块化测试脚本框架 需要创建独立的可描述的模块、程序片断以及待测试应用程序的脚本。这些小脚本进行组合&#xff0c;就能组成用来独立运行特定的测试的测试用例脚本。 场景一: 开发把 access_token接口地址由/cgi-bin/token 改为/cgi-bin/get_token或者修改参数等 》开发把…

【LeetCode】链式二叉树OJ题---C语言版

链式二叉树OJ题 一、单值二叉树&#xff08;1&#xff09;题目描述&#xff1a;&#xff08;2&#xff09;思路表述&#xff1a;&#xff08;3&#xff09;代码实现&#xff1a; 二、二叉树最大深度&#xff08;1&#xff09;题目描述&#xff1a;&#xff08;2&#xff09;思路…

docker容器中创建非root用户

简介 用 docker 也有一段时间了&#xff0c;一直在 docker 容器中使用 root 用户肆意操作。直到部署 stable diffusion webui 我才发现无法使用 root 用户运行它&#xff0c;于是才幡然醒悟&#xff1a;是时候搞个非 root 用户了。 我使用的 docker 镜像文件是 centos:centos…

LeetCode的几道题

一、捡石头 292 思路就是&#xff1a; 谁面对4块石头的时候&#xff0c;谁就输&#xff08;因为每次就是1-3块石头&#xff0c;如果剩下4块石头&#xff0c;你怎么拿&#xff0c;我都能把剩下的拿走&#xff0c;所以你就要想尽办法让对面面对4块石头的倍数&#xff0c; 比如有…

Linux shell中的函数定义、传参和调用

Linux shell中的函数定义、传参和调用&#xff1a; 函数定义语法&#xff1a; [ function ] functionName [()] { } 示例&#xff1a; #!/bin/bash# get limit if [ $# -eq 1 ] && [ $1 -gt 0 ]; thenlimit$1echo -e "\nINFO: input limit is $limit" e…

CPU 使用率和负载Load

优质博文&#xff1a;IT-BLOG-CN 一、CPU 使用率 CPU使用率是 CPU处理非空闲任务所花费的时间百分比 。例如单核CPU 1s内非空闲态运行时间为0.8s&#xff0c;那么它的CPU使用率就是80%&#xff1b;双核CPU 1s内非空闲态运行时间分别为0.4s和0.6s&#xff0c;那么&#xff0c;…

IDEA2023安装教程(超详细)

文章目录 前言安装IntelliJ IDEA1. 下载IntelliJ IDEA2. 运行安装程序3. 选择安装路径4. 选择启动器设置5. 等待安装完成6. 启动IntelliJ IDEA7. 配置和设置8. 激活或选择许可证9. 开始使用 总结 前言 随着软件开发的不断发展&#xff0c;IntelliJ IDEA成为了许多开发人员首选…

基于JSP的网络考试系统/在线考试系统的设计与实现

摘 要 网络考试系统是由高校的一个网络考试&#xff0c;按照章程自主开展网络考试系统。网络考试是实施素质教育的重要途径和有效方式&#xff0c;在加强校园文化建设、提高学生综合素质、引导学生适应社会、促进学生成才就业等方面发挥着重要作用&#xff0c;是新形势下有效凝…