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;

                    }

                }

            }

        }

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SeaTunnel及SeaTunnel Web部署指南(小白版)

现在你能搜索到的SeaTunnel的安装。部署基本都有坑&#xff0c;官网的文档也是见到到相当于没有&#xff0c;基本很难找到一个适合新手小白第一次上手就能成功安装部署的版本&#xff0c;于是就有了这个部署指南的分享&#xff0c;小主已经把可能遇到的坑都填过了&#xff0c;希…

android keylayout键值适配

1、通过getevent打印查看当前keyevent数字对应事件和物理码 2、dumpsys input 查看输入事件对应的 KeyLayoutFile: /system/usr/keylayout/Vendor_6080_Product_8060.kl 3、通过物理码修改键值映射&#xff0c;修改/system/usr/keylayout/目录下的文件

redis-cluster集群模式

Redis-cluster集群 1 Redis3.0引入的分布式存储方案 2集群由多个node节点组成,redis数据分布在节点之中,在集群之中分为主节点和从节点3集群模式当中,主从一一对应,数据写入和读取与主从模式一样&#xff0c;主负责写&#xff0c;从只能读4集群模式自带哨兵模式&#xff0c;可…

视频剪辑有妙招:批量置入封面,轻松提升视频效果

随着社交媒体的兴起&#xff0c;视频已经成为分享和交流的重要方式。无论是专业的内容创作者还是普通的社交媒体用户&#xff0c;都要在视频剪辑上下一番功夫&#xff0c;才能让视频更具吸引力。而一个吸引的封面往往能在一瞬间抓住眼球&#xff0c;提高点击率。还在因如何选择…

基于Mapmost Alpha工具快速搭建3D场景可视化大屏

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

h5如何使用navigateBack回退到微信小程序页面并携带参数

前言 在h5中使用navigateBack回退到微信小程序页面很常见&#xff0c;但是有一种交互需要在回退之后的页面可以得到通知&#xff0c;拿到标识之后&#xff0c;进行某些操作&#xff0c;这样的话&#xff0c;由于微信官方并没有直接提供这样的api&#xff0c;就需要我们开动脑筋…

【计算思维】蓝桥杯STEMA 科技素养考试真题及解析 6

1、明明买了一个扫地机器人&#xff0c;可以通过以下指令控制机器人运动: F:向前走 10 个单位长度 L:原地左转 90 度 R:原地右转 90 度 机器人初始方向向右&#xff0c;需要按顺序执行以下那条指令&#xff0c;才能打扫完下图中的道路 A、F-L-F-R-F-F-R-F-L-F B、F-R-F-L-F-F…

如何搭建Zblog网站并通过内网穿透将个人博客发布到公网

文章目录 1. 前言2. Z-blog网站搭建2.1 XAMPP环境设置2.2 Z-blog安装2.3 Z-blog网页测试2.4 Cpolar安装和注册 3. 本地网页发布3.1. Cpolar云端设置3.2 Cpolar本地设置 4. 公网访问测试5. 结语 1. 前言 想要成为一个合格的技术宅或程序员&#xff0c;自己搭建网站制作网页是绕…

virtualList 封装使用 虚拟列表 列表优化

虚拟列表 列表优化 virtualList 组件封装 virtualList 组件封装 本虚拟列表 要求一次性加载完所有数据 不适合分页 新建一个select.vue 组件页面 <template><div> <el-select transfer"true" :popper-append-to-body"true"popper-class…

redis-cluster集群(目的:高可用)

1、特点 集群由多个node节点组成&#xff0c;redis数据分布在这些节点中&#xff0c;在集群中分为主节点和从节点&#xff0c;一个主对应一个从&#xff0c;所有组的主从形成一个集群&#xff0c;每组的数据是独立的&#xff0c;并且集群自带哨兵模式 2、工作原理 集群模式中…

Android系统调试工具大全:解密adb、dumpsys、procrank等神器

Android系统调试工具大全&#xff1a;解密adb、dumpsys、procrank等神器 引言 Android开发中&#xff0c;调试是一个非常重要的环节&#xff0c;本文将介绍一些常用的Android系统调试工具&#xff0c;包括adb、logcat、procrank、dumpsys、dmesg、top、free、df、trace、pm、…

如何使用Google My Business来提升您的内容和SEO?

如果您的企业有实体店&#xff0c;那么使用Google My Business&#xff08;GMB&#xff09;来改善您的本地SEO并增强您的在线形象至关重要。Google My Business &#xff08;GMB&#xff09; 是 Google 提供的补充工具&#xff0c;使企业能够控制其在 Google 搜索和地图上的数字…

【数字化转型方法论读书笔记】-数据中台角色解读

一千个读者&#xff0c;就有一千个哈姆雷特。同样&#xff0c;数据中台对于企业内部不同角色的价值也不同&#xff0c;下面分别从董事长、CEO、 CTO/CIO、IT 架构师、数据分析师这 5 个角色的视角详细解读数据中台。 1、董事长视角下的数据中台 在数字经济时代&#xff0c;企业…

【从入门到起飞】JavaSE—多线程(3)(生命周期,线程安全问题,同步方法)

&#x1f38a;专栏【JavaSE】 &#x1f354;喜欢的诗句&#xff1a;路漫漫其修远兮&#xff0c;吾将上下而求索。 &#x1f386;音乐分享【如愿】 &#x1f384;欢迎并且感谢大家指出小吉的问题&#x1f970; 文章目录 &#x1f354;生命周期&#x1f384;线程的安全问题&#…

每日一题 1410. HTML 实体解析器(中等,模拟)

模拟&#xff0c;没什么好说的 class Solution:def entityParser(self, text: str) -> str:entityMap {&quot;: ",&apos;: "",>: >,<: <,&frasl;: /,&amp;: &,}i 0n len(text)res []while i < n:isEntity Falseif …

Java—学生信息管理系统(简单、详细)

文章目录 一、主界面展示二、学生类三、系统功能方法3.1 main()方法3.2 添加学生信息3.3 删除学生信息3.4 修改学生信息3.5 查看所有学生信息 四、完整代码4.1 Student .Java4.2 StudentManger.Java 前言&#xff1a;本案例在实现时使用了Java语言中的ArrayList集合来储存数据。…

【Java系列】SpringBoot 集成MongoDB 详细介绍

目录 写在前面 一、步骤介绍 步骤 1: 添加 MongoDB 依赖 步骤 2: 配置 MongoDB 连接信息 步骤 3: 创建实体类 步骤 4: 创建 Repository 接口 步骤 5: 使用 Repository 进行操作 二、特殊处理 写在前面 在Spring Boot中集成MongoDB的过程相对简单&#xff0c;以下是一个…

git的用法

目录 一、为什么需要git 二、git基本操作 2.1、初始化git仓库 2.2、配置本地仓库的name和email 2.3、认识工作区、暂存区、版本库 三、git的实际操作 3.1 提交文件 3.2 查看git状态以及具体的修改 3.3 git版本回退 git reset 3.1 撤销修改 四、git分支管理 4.…

一体化大气环境监测设备实时守护我们的空气质量

WX-CSQX12 随着空气污染问题的日益严重&#xff0c;大气环境监测设备成为了我们生活中不可或缺的一部分。而一体化的大气环境监测设备&#xff0c;更是为我们的环境保护工作带来了更多的便利和效益。 一体化大气环境监测设备是一种集成了多种功能于一体的环保设备&#xff0c;…

USB驱动开发基础

USB标准 USB1.0&#xff0c; 1996&#xff0c;低速1.5Mbps和高速12Mbps&#xff0c;USB1.1 iMac G3&#xff0c;Type A和Type B接口USB 2.0 2000&#xff0c; 480Mpbs&#xff0c;Type A/B/C接口、Micro A/BUSB 3.0 5Gbps, 随着USB 3.2命名规定&#xff0c;现在也叫USB 3.2 Ge…