前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >C# 数组基础

C# 数组基础

作者头像
郑小超.
发布于 2018-01-26 07:26:47
发布于 2018-01-26 07:26:47
1.2K00
代码可运行
举报
文章被收录于专栏:GreenLeavesGreenLeaves
运行总次数:0
代码可运行

一、数组的基础知识

1、数组有什么用?

如果需要同一个类型的多个对象,就可以使用数组。数组是一种数组结构,它可以包含同一个类型的多个元素.

2、数组的初始化方式

第一种:先声明后赋值

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int[] array = new int[3];
array[0] = 0;
array[1] = 1;
array[2] = 2;

第二种:使用数组初始化器对数组进行赋值。注:数组初始化器只能在声明数组变量时使用,不能在声明数组变量之后使用.

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//正确
int[] array = new int[3] { 1, 2, 3 };

//错误
int[] array1=new int[3];
array1 =  { 1, 2, 3 };

关于第二种方法,C#提供了两个方式的"语法糖";

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//语法糖一
int[] array = new int[] { 1, 2, 3 };

//语法糖二
int[] array={1,2,3};

3、引用类型数组

C#除了能声明和处理预定义类型的数组之外,还能声明自定义类型的数组。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Person
{
    public string FirstName{get;set;}
    public string LastName{get;set;}    
}
Person[] person=new Person[2];

预定义类型数组能干的事,自定义类型数组也都能干.

4、多维数组

二维数组的声明方式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int[,] twodim = new int[2, 3];
twodim[0, 0] = 1;
twodim[0, 1] = 2;
twodim[0, 2] = 3;
twodim[1, 0] = 4;
twodim[1, 1] = 5;
twodim[1, 2] = 6;
twodim[2, 0] = 7;
twodim[2, 1] = 8;
twodim[2, 2] = 9;

语法糖:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int[,] twodim ={
   {1,2,3},
   {4,5,6},
   {7,8,9}
};

三维数组:

因为日常开发中不常用到,所以就不解释了.百度百科

5、锯齿数组

锯齿数组是一个特殊的二维数组,常规的二维数组都是矩形,大部分都是各行的个数都相同,而锯齿数组则不一样,锯齿数组的第一行有3个,第二行可能有6个,第三行可能有7个......以此类推.锯齿数组的声明方式如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int[][] jagged = new int[3][];
jagged[0]=new int[2]{1,2};
jagged[1] = new int[6] { 3, 4, 5, 6, 7, 8 };
jagged[2] = new int[4] { 6, 8, 9, 2 };
for (int row = 0; row < jagged.Length; row++)
{
      for (int element = 0; element < jagged[row].Length; element++)
      {
            Console.WriteLine("第{0}行,第{1}个,值为{2}", row, element, jagged[row][element]);
       }
}
Console.ReadKey();

二、Array类

使用方括号创建数组其实是用Array的表示法,当我们使用方括号创建了一个数组时,C#编译器会创建一个派生自抽象基类的Array的新类.这样使用方括号创建的数组对象就可以使用Array类为每个数组定义的方法和属性了.如:可以使用foreach迭代数组,其实就是使用了Array类中GetEnumerator()方法.

1、使用静态方法CreateInstance创建一维数组,并使用SetValue对数组进行赋值,使用GetValue获取数组中的值

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Array array=Array.CreateInstance(typeof(int), 5);
for (int i = 0; i < array.Length; i++)
{
      array.SetValue(i + 10, i);
}
for (int i = 0; i < array.Length; i++)
{
     Console.WriteLine(array.GetValue(i));
}

2、使用静态方法CreateInstance创建二维数组,并使用SetValue对数组进行赋值,使用GetValue获取数组中的值

注:通过GetUpperBound获取维度的上限,通过GetLowerBound获取维度的下限

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Array array=Array.CreateInstance(typeof(int),5,6);
int value = 0;
for(int row=0;row<array.GetUpperBound(0);row++)
for (int element = 0; element < array.GetUpperBound(1); element++)
{
     array.SetValue(value, row, element);
     value++;
}
for (int row = 0; row < array.GetUpperBound(0); row++)
     for (int element = 0; element < array.GetUpperBound(1); element++)
     {
         if (element == array.GetUpperBound(1) - 1)
         {
             Console.WriteLine();
         }
         else
         {
             string nbsp = " ";
             string res = array.GetValue(row, element).ToString().PadLeft(2, '0');
             res=element == array.GetUpperBound(1) - 1 ? res : res + nbsp;
             Console.Write(res);
         }
      }
                    
}
Console.ReadKey();

3、使用静态方法CreateInstance创建三维数组,并使用SetValue对数组进行赋值,使用GetValue获取数组中的值

注:通过GetUpperBound获取维度的上限,通过GetLowerBound获取维度的下限

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Array array = Array.CreateInstance(typeof(int), 5, 6, 7);
int value = 0;
for (int x = 0; x < array.GetUpperBound(0); x++)
       for (int y = 0; y < array.GetUpperBound(1); y++)
              for (int z = 0; z < array.GetUpperBound(2); z++)
              {
                    array.SetValue(value, x, y, z);
                    value++;
               }

for (int x = 0; x < array.GetUpperBound(0); x++)
      for (int y = 0; y < array.GetUpperBound(1); y++)
            for (int z = 0; z < array.GetUpperBound(2); z++)
            {
                  Console.WriteLine("x坐标:{0},y坐标:{1},z坐标:{2},值为:{3}", x, y, z, array.GetValue(x, y, z));
             }
Console.ReadKey();

部分截图

4、复制数组

数组是引用类型,所以将一个数组变量赋值给另一个数组变量,就会得到两个引用同一个数组的变量,所以通过任何一个引用修改数组的值,两个引用都会受影响.

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int[] array = { 1, 2, 3 };
int[] otherArray = array;
array[2] = 6;
Console.WriteLine(otherArray[2]);
otherArray[2] = 66;
Console.WriteLine(array[2]);

所以单纯的通过复制引用的方法,并不能实现数组的复制,必须通过其它的方法来复制数组,C#提供了两种复制数组的方式:

第一种:C#中的数组都实现了ICloneable接口,所以通该接口中定义的Clone()方法就能实现数组的浅拷贝(什么是浅拷贝,后续会介绍).

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int[] array = { 1, 2, 3 };
int[] arrayClone = (int[])array.Clone();
array[2]=66;
Console.WriteLine(object.ReferenceEquals(array,arrayClone));//False 说明使用Clone()方法拷贝后的数组是重新创建的
Console.WriteLine(arrayClone[2] +"..." + array[2]);

第二种:Array.Copy()

复制一维数组:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int[] array = { 1, 2, 3 };
int[] arrayCopy=new int[array.Length];
Array.Copy(array, arrayCopy,array.Length);//最后一个参数为要复制的个数
for (int i = 0; i < arrayCopy.Length; i++)
{
      Console.WriteLine(arrayCopy[i]);
}

复制二维数组:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int[,] array = { {1,2,3},{4,5,6},{7,8,9} };
int[,] arrayCopy = new int[array.GetUpperBound(0)+1, array.GetUpperBound(1)+1];
Array.Copy(array,arrayCopy,array.Length);//最后一个参数为要复制的个数
for (int i = 0; i <= arrayCopy.GetUpperBound(0); i++)
     for (int x = 0; x <= arrayCopy.GetUpperBound(1); x++)
            Console.WriteLine("第{0}行,第{1}个,值为:{2}",i,x,arrayCopy.GetValue(i,x));
Console.ReadKey();

第三种:CopyTo

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int[] array = { 1, 2, 3 };
int[] arrayCopyTo=new int[array.Length];
array.CopyTo(arrayCopyTo,0);
            Console.WriteLine(object.ReferenceEquals(array,arrayCopyTo));
for (int i = 0; i < arrayCopyTo.Length; i++)
{
     Console.WriteLine(arrayCopyTo[i]);
}

Clone()和Array.Copy()的区别主要是:Clone()方法直接复制整个目标数组,然后进行拆箱就可以使用,但是Array.Copy()方法则必须要提供相同维数的数组和需要复制的元素个数,才能复制成功。

Clone()和CopyTo()方法的区别主要是:CopyTo()需要提供一个开始复制的起始索引.

 什么是浅拷贝和深拷贝?

当数组中存在引用类型的元素时,这个时候使用Clone()或者Array.Copy()或者CopyTo()方法进行的数组复制都是浅拷贝,只会复制引用类型的索引,这意味这当修改原数组中的引用类型的值时,拷贝后的数组中的引用类型的值也会做相应的改变,所以使用上述方法进行的数组拷贝都将是浅拷贝.所以如果你想要创建包含引用类型的数组的深层副本,就必须迭代数组并创建新对象.这个过程也叫深拷贝.

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Person p = new Person("张三", 23);
object[] array = { 1, 2, 3, p,6 };
object[] arrayClone = (object[])array.Clone();
p.Name = "李四";
Console.WriteLine((arrayClone[3] as Person).Name);

class Person
{
     public Person()
     { }
     public Person(string name,int age)
      {
           this.Name = name;
           this.Age = age;
      }
       public string Name { get; set; }
       public int Age { get; set; }
}

说明Clone()方法确实是浅拷贝,至于Array.Copy()和CopyTo()也是浅拷贝-这两个请自行验证.

5、数组排序

(1)、简单类型数组排序(简单类型如:System.String、System.Int、System.Double、System.Float等)

Array类使用QuickSort算法对数组中的元素进行排序。主要通过Array.Sort()方法来进行排序,Sort()方法需要数组中元素都实现IComparable接口,因为简单类型(如System.String和System.Int32)实现了IComparable接口,所以可以对包含这些类型的元素进行排序.如下代码,就是简单的对string类型数组和int数组进行排序,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
string[] player ={
     "LeBron James",
     "Stepen Curry",
     "Kevin Durrent",
};
Array.Sort<string>(player);
foreach (var item in player)
{
      Console.WriteLine(item);
}

int[] nums = { 9, 2, 4, 5, 6, 8, 9, 2 };
Array.Sort<int>(nums);
foreach (var item in nums)
{
      Console.WriteLine(item);
}

(2)、自定义类型利用Sort()方法排序

a、通过自定义类型实现IComparable接口,来实现自定义类型数组的排序。注:该方法适用于要进行的自定义实体类(本例中为Person类)可修改的情况下!

如果数组的类型为自定义类型,且需要使用Sort()对该书组进行排序,那么当前自定义类就必须实现IComparable接口,该接口只定义了一个方法CompareTo(),如果要比较的对象相等,该方法就返回0,如果该实例应排在参数的前面,该方法返回-1,如果该实例应排在参数的后面,该方法返回1.CompareTo方法的返回值规则和string.Compare()方法相同,如下图:

 如上图示,当前实例应该排在参数的前面,所以result的值应为-1

ok,说明上面的结论正确(这里对象相等和当前实例排在参数后面的情况自行证明).那么CompareTo()方法的返回也应该这么写,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
static void Main(string[] args)
{
            Person[] people =
            {
                new Person{FirstName="Damon",LastName="Hill"},
                new Person{FirstName="Niki",LastName="Lauda"},
                new Person{FirstName="Ayrton",LastName="Senna"}
                
            };
            Array.Sort<Person>(people);
            foreach (var item in people)
            {
                if (item == null)
                    Console.WriteLine("null");
                else
                Console.WriteLine(item.ToString());
            }
            Console.ReadKey();

}
class Person:IComparable<Person>
{
            public string FirstName { get; set; }
            public string LastName { get; set; }

            public int CompareTo(Person other)
            {
                if (other == null) return 1;
                int result = string.Compare(this.FirstName, other.FirstName);
                if (result == 0)//如果FirstName相等,则判断LastName
                    result = string.Compare(this.LastName, this.LastName);
                return result;
            }

            public override string ToString()
            {
                return this.FirstName + " " + this.LastName;
            }
}

b、当要进行排序的自定义类型不能进行修改的时候,就采用b方法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
        static void Main(string[] args)
        {
            Person[] people =
            {
                new Person{FirstName="Damon",LastName="Hill"},
                new Person{FirstName="Damon",LastName="Green"},
                new Person{FirstName="Niki",LastName="Lauda"},
                new Person{FirstName="Ayrton",LastName="Senna"}
                
            };
            Array.Sort<Person>(people,new PersonCompare(PersonCompareType.LaseName));
            foreach (var item in people)
            {
                if (item == null)
                    Console.WriteLine("null");
                else
                Console.WriteLine(item.ToString());
            }
            Console.ReadKey();

        }
        public enum PersonCompareType
        { 
            FirstName=0,
            LaseName=1
        }
        public class PersonCompare : IComparer<Person>
        {
            private PersonCompareType _compareType;
            public PersonCompare(PersonCompareType compareType)
            {
                this._compareType = compareType;
            }
            public int Compare(Person x, Person y)
            {
                if (x == null && y == null)
                    return 0;
                if (x == null) return 1;
                if (y == null) return -1;
                switch (this._compareType)
                {
                    case PersonCompareType.FirstName: return string.Compare(x.FirstName, y.FirstName);
                    case PersonCompareType.LaseName: return string.Compare(x.LastName, y.LastName);
                    default: throw new ArgumentException("unexcepted compare type");
                }
            }

            
        }
        public class Person
        {
            public string FirstName { get; set; }
            public string LastName { get; set; }
            public override string ToString()
            {
                return this.FirstName + " " + this.LastName;
            }
        }

c、传递一个比较两个对象大小的委托delegate int Comparison<in T>(T x, T y),该方法最为简洁,即不污染要进行排序的对象,又能使用lambda表达式

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
        static void Main(string[] args)
        {
            Person[] people =
            {
                new Person{FirstName="Damon",LastName="Hill"},
                new Person{FirstName="Damon",LastName="Green"},
                new Person{FirstName="Niki",LastName="Lauda"},
                new Person{FirstName="Ayrton",LastName="Senna"}
                
            };
            Comparison<Person> compare = (Person x, Person y) =>
                {
                    if (x == null && y == null)
                        return 0;
                    if (x == null) return 1;
                    if (y == null) return -1;
                    int result = string.Compare(x.FirstName, y.FirstName);
                    if (result == 0)
                        result = string.Compare(x.LastName, x.LastName);
                    return result;
                };
            Array.Sort<Person>(people, compare);
            foreach (var item in people)
            {
                if (item == null)
                    Console.WriteLine("null");
                else
                    Console.WriteLine(item.ToString());
            }
            Console.ReadKey();
        }
        public class Person
        {
            public string FirstName { get; set; }
            public string LastName { get; set; }
            public override string ToString()
            {
                return this.FirstName + " " + this.LastName;
            }
        }

综合上面的三种方法,个人推荐第三种方法,进行自定义类型数组的排序工作,当然如果排序的逻辑很复杂,第三种未必就是最好的.

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017-08-14 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
云实例初始化的行业标准:Cloud-Init
Cloud-Init1 是跨平台云实例初始化的行业标准。它得到了所有主要公共云提供商的支持,适用于私有云基础设施的配置系统以及裸机安装。Cloud-Init 将在启动时识别其运行所在的云环境,读取来自云端提供的任何元数据,并据此初始化系统。这可能涉及设置网络和存储设备,配置 SSH 访问密钥以及系统的许多其他方面。之后,Cloud-Init 还将解析并处理传递给该实例的任何可选用户或供应商数据。在你想要创建自定义的 Linux 部署镜像时或者每次部署一个新的 Linux 服务器时,有很多事情需要初始化并且进行自动化处理。Cloud-Init 可以帮助我们实现这些自动化任务。
用户10807116
2024/06/06
2360
kvm-初始化cloud-init(二)
作者介绍:简历上没有一个精通的运维工程师。请点击上方的蓝色《运维小路》关注我,下面的思维导图也是预计更新的内容和当前进度(不定时更新)。
运维小路
2024/11/08
1570
kvm-初始化cloud-init(二)
kvm-初始化cloud-init(一)
虚拟化,简单来说就是把一台服务器/PC电脑,虚拟成多台独立的虚拟机,每台虚拟机之间相互隔离,每个虚拟机都有自己独立的操作系统,磁盘,网络资源。虚拟化是一个很庞大的系统,我的介绍主要是帮助你入门,让你了解基本技术原理,具备搭建操作虚拟化的能力。由于涉及到内容较多,这里的目录就只是以简单分类介绍和说明,不再针对单个小节进行目录列出,主要涉及的分类包括以下几个方面:
运维小路
2024/11/07
1320
kvm-初始化cloud-init(一)
一个超级牛皮的容器管理工具Container Desktop
大家好,波哥又来给大家推荐好东西啦! 欢迎大家在评论区留言评论自己想了解的工具、方向或职业等互联网相关内容,点赞和推荐多的,波哥会优先安排解答! 关注波哥 介绍 Container Desktop 是一款为 Podman 设计的跨平台桌面伴侣应用程序,提供直观的图形化界面,简化容器管理。作为业界首个跨平台容器用户界面解决方案,它通过定制化连接技术解决了不同操作系统间的通信难题。在 Windows 上,它利用自定义 TCP 中继实现 WSL 与原生环境的通信;5.2.13 版本引入基于 SSH 中继的新方法,结合 Windows 命名管道,提升安全性并减少 TCP 服务暴露风险。该技术基于 gvisor-tap-vsock 改进,支持 Podman 和 Docker。尽管项目创建者坦言这是其首次开源尝试,并感受到开发挑战,但 Container Desktop 仍被视为“完成状态”,展现了其在容器管理领域的重要价值。 主要功能与使用 Podman Desktop 提供以下关键功能:
IT运维技术圈
2025/03/17
1420
一个超级牛皮的容器管理工具Container Desktop
低成本基于WordPress手动搭建个人博客
在数字化时代,个人博客成为了许多人展示自己才华、分享生活点滴、甚至开展副业的重要平台。WordPress是一个功能强大的网站构建工具,它不仅易于使用,而且拥有丰富的插件和主题,非常适合用来创建个人博客。本文将引导您完成使用WordPress搭建个人博客的全过程。
用户10081398
2024/11/10
1630
如何在CentOS 7上将ngx_pagespeed添加到Nginx
ngx_pagespeed,或者pagespeed,是一个Nginx模块,旨在通过精简资源的规模来缩短客户端浏览器加载它所需的时间,从而自动优化您的网站。如果您还不熟悉它,请查看其官方网站。
angel_郁
2018/09/21
1.3K0
在本地KVM中安装使用Cloud-init
Cloud-init是一个Linux虚拟机的初始化工具,被广泛应用在AWS和OpenStack等云平台中,用于在新建的虚拟机中进行时间设置、密码设置、扩展分区、安装软件包等初始化设置。本文主要研究在本地KVM虚拟机,也就是没有云平台的情况下,如何使用cloud-init进行初始化工作。示例虚拟机的操作系统是CentOS 7.1。
星哥玩云
2022/07/13
1.7K0
16-cloud-init
cloud-init是linux的一个工具,当云主机启动系统,cloud-init可从nova metadata服务或者config drive中获取metadata,用于初始化云主机的操作。
小朋友呢
2020/01/07
2.8K0
玩转CVM之Cloud-Init排障
Cloud-Init 是一个纯开源的工具,它是虚拟机内部的一个服务,在开机启动的时候会被执行,非常驻服务,执行完就会退出。腾讯云的 Linux 公有镜像都预安装了 Cloud-Init 服务,主要用于实现对 CVM 实例的初始化操作,以及执行一些用户在创建 CVM 实例的时候指定首次开机启动要执行的自定义脚本。
苏欣
2019/07/16
6.6K0
再见了 VMware,一款更轻量级的虚拟机!
Multipass是一个轻量虚拟机管理器,是由 Ubuntu 运营公司 Canonical 所推出的开源项目。运行环境支持 Linux、Windows、macOS。在不同的操作系统上,使用的是不同的虚拟化技术。在 Linux 上使用的是 KVM、Window 上使用 Hyper-V、macOS 中使用 HyperKit 以最小开销运行VM,支持在笔记本模拟小型云。
终码一生
2022/04/15
1.2K0
再见了 VMware,一款更轻量级的虚拟机!
OpenStack实践(十):Cloud Init+Config Drive定制实例
openstack安装详见:OpenStack实践(一):Ubuntu16.04下DevStack方式搭建p版OpenStack
loong576
2019/09/10
5.7K0
OpenStack实践(十):Cloud Init+Config Drive定制实例
基于Linux下搭建NextCloud构建自己的私有网盘
Nextcloud是一款开源免费的私有云存储网盘项目,可以让你快速便捷地搭建一套属于自己或团队的云同步网盘,从而实现跨平台跨设备文件同步、共享、版本控制、团队协作等功能。它的客户端覆盖了Windows、Mac、Android、iOS、Linux 等各种平台,也提供了网页端以及 WebDAV接口,所以你几乎可以在各种设备上方便地访问你的云盘。他可以帮您简单快速在个人,公司电脑、服务器甚至是树莓派等设备上架设一套属于自己或者团队专属的云同步网盘,所以它是一款开源网盘的绝佳解决方案
星哥玩云
2022/06/02
5.4K1
基于Linux下搭建NextCloud构建自己的私有网盘
KubeVirt macvtap虚拟机创建过程 手动实验
MACVTAP 的实现基于传统的 MACVLAN。该实验中会起两个libvirt容器,一个作为客户端去测试连接虚拟机,也就是左边这个。右边会在容器中起虚拟机,容器的eth0做一个macvtap给虚拟机用,macvtap0会把收到的包都发给虚拟机的eth0
后端云
2022/06/09
1.7K0
KubeVirt macvtap虚拟机创建过程 手动实验
非云环境中Kubernetes的配置和运行:技术栈
本文将详细介绍相关技术栈的构成组件,包括 HAProxy、Corosync、Pacemaker、dnsmasq、cloud-init、LVM、Gluster、Docker 等概念。
深度学习与Python
2020/09/28
7280
非云环境中Kubernetes的配置和运行:技术栈
网站-全套服务-从0到1
onephone 作者:史文峰(richiewfshi)腾讯工程师,现主要从事大数据研发和后台开发,喜欢捣鼓技术、动漫、跑马。 01. 这样开始的... 朋友“搞事情”,自己有偿帮忙搭了一套线上服务,包括官网、小程序后台、文档集站点、个人博客站点等。 初期,流量小,节约资金,一切从简,后期,流量大了,再考虑扩容或迁移服务(目前完全能 hold 住)。 基于一台腾讯云服务器搭建了全套服务,站点均在同一个二级域名下。 依赖的服务 1、腾讯云服务 云服务器 CVM 对象存储 COS 网站备案 域名管理,SS
腾讯云DNSPod团队
2020/06/28
1.3K0
蓝军技巧之SSRF利用方法
SSRF漏洞在互联网公司中应该是除了越权之外最普遍的漏洞了。关于漏洞的原理,绕过,传统的扫端口、各种探测等利用方式等就不再赘述,这里分享下自己作为企业蓝军中常用的一些SSRF的利用途径。
瓦都剋
2022/03/30
2.2K0
再见 Docker,是时候拥抱下一代容器工具了
Linux 容器是由 Linux 内核所提供的具有特定隔离功能的进程,Linux 容器技术能够让你对应用及其整个运行时环境(包括全部所需文件)一起进行打包或隔离。从而让你在不同环境(如开发、测试和生产等环境)之间轻松迁移应用的同时,还可保留应用的全部功能。
iMike
2019/09/25
1.5K0
再见 Docker,是时候拥抱下一代容器工具了
课件:Docker实用篇
例如一个项目中,部署时需要依赖于node.js、Redis、RabbitMQ、MySQL等,这些服务部署时所需要的函数库、依赖项各不相同,甚至会有冲突。给部署带来了极大的困难。
终有救赎
2023/10/16
3240
课件:Docker实用篇
NextCloud私有云盘安装部署记录
描述:由于个人家里的NAS以及公司团队对私有网盘的进行日常工作文件同步以及协同办公的需求,所以有了这篇文章,讲解记录从选项到安装以及同步使用等相关操作;
全栈工程师修炼指南
2022/09/29
24.2K0
NextCloud私有云盘安装部署记录
podman快速入门详解与实践
Podman 原来是 CRI-O 项目的一部分,后来被分离成一个单独的项目叫 libpod。Podman 的使用体验和 Docker 类似,不同的是 Podman 没有 daemon。以前使用 Docker CLI 的时候,Docker CLI 会通过 gRPC API 去跟 Docker Engine 说「我要启动一个容器」,然后 Docker Engine 才会通过 OCI Container runtime(默认是 runc)来启动一个容器。这就意味着容器的进程不可能是 Docker CLI 的子进程,而是 Docker Engine 的子进程。
互联网-小阿宇
2022/11/21
1.3K0
相关推荐
云实例初始化的行业标准:Cloud-Init
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文