Powershell:关于hashtable你想知道的一切
译者语:本篇为一篇译文,详细介绍了在powershell中如何使用hashtable这种数据类型.本文为本人2018年最后一篇博文(哈哈,一年内写没写几篇),也是本人的第一次译文,有不足之处还请指教.祝大家元旦快乐!
我在工作中经常用到它,现在想停下来讨论一下它(hashtable).昨天夜里小组会议后我教了一些同事如何使用hashtable,我很快意识到初识hashtable时我也曾经有与他们相同的困惑.Hashtable在powershell里着实非常重要因此我们需要对它有充会的理解.
hashtable是元素的集合
首先,我想让你们把hastable看作传统意义上定义的集合.这将会使你对后面它在高级应用中是如何工作的有一些基本的了解.通常很多困惑都源自于对此没有认知.
什么是数组
在讨论什么是hashtable之前,我想要先提一下数组.就本讨论而言,数组是一系列元素或者对象的集合(或列表)
$array = @(1,2,3,5,7,11)
一旦数组中有了对象,你就可以使用foreach
来迭代它们或者索引来访问某元素
foreach($item in $array)
{
Write-Output $item
}
Write-Output $array[3]
同样,你可以使用索引来更新值
$array[2] = 13
这里我仅仅介绍了数组的一些皮毛,但是把我们下面将要讨论的hashtable引到了正确的话题上.
什么是hashtable
我们首先从一般的,被许多编程语言都采用的技术性描述开始,然后再转到powershell里对它的定义
hashtable是一个类似于数组的数据结构,除了你使用键来存储一个值(或者对象),它是一个基本的键/值对存储.首先,我们来创建一个空的hashtable
$ageList = @{}
注意这里用的是花括号,而上面定义数组用的是小括号.
然后我们使得键来添加一些值:
$key = 'Kevin'
$value = 36
$ageList.add( $key, $value )
$ageList.add( 'Alex', 9 )
以上人名是键,而值是我们想存储的东西.
使用中括号访问元素
一旦你把值添加到hashtable,你可以使用添加时使用的键把值取出来(不像上面数组使得的是数字索引)
$ageList['Kevin']
$ageList['Alex']
当我想要获取Kevin
的年龄时,我使用他的名字来获取,我们也可以使用这种方法来添加或者更新hashtable里的值.这和上面使用add
方法效果是一样的
$ageList = @{}
$key = 'Kevin'
$value = 36
$ageList[$key] = $value
$ageList['Alex'] = 9
还有一种另外的语法来添加元素,我们后面会讲到,如果你是从其它语言转到powershell你会看到以上使用和你在其它语言的使用方法类似.
创建包含值的hashtable
截至目前我们创建的hashtable初始状态是一个空集合,我们在创建hashtable时也可以预先添加一些键值:
$ageList = @{
Kevin = 36
Alex = 9
}
作为一个查找表(原文为lookup table)
下面是一个例子:
$environments = @{
Prod = 'SrvProd05'
QA = 'SrvQA02'
Dev = 'SrvDev12'
}
$server = $environments[$env]
在这个例子中,你可以指定一个环境变量的值,然后就可以获取到正确的服务器(示例中的hashtable值是服务器名),当然你也可以使用switch($env){...}
这种方法,不过hashtable一种很好的替换
译者注,这个示例仅仅是伪代码,并不能运行通过,作者实际想要表述的是你可以把服务器的键存到环境变量量,然后就可以通过键索引取出来.比如说你定义了一个名为
ServerEnv
的环境变量,并赋值为Prod
,则可以通过
$server = $environments[$env:ServerEnv]来获取到hashtable对应的服务器名
获取多项
一般情况下,你认为hashtable是一个键值对集合,你提供一个键,获取一个值,实际上powershell允许提供一系列的键来获取多个值.
$environments[@('QA','DEV')]
$environments[('QA','DEV')]
$environments['QA','DEV']
在这个例子中我们使用上上面的查找表并且提供了三种不同风格的数组来获取匹配的项.这是powershell隐藏的未被多数人发掘的宝贝.
译者注,以上三种确为powerhsell数组的三种定义方式,是等价的,一般情况下数组定义使用
@()
这种形式,对于泛型数组类型或者几个离散元素通常使用第三种形式,例如$num=1..5
或者$num=1,2,3,5,5
,效果是一样的
遍历hashtable
由于hashtable是一系列的键值对,因此你不能像遍历数组或者普通列表一样来遍历它.
首先需要注意的是如果你使用管道来操作hashtable,则hashtable被视为一个整体对象
PS:\> $ageList | Measure-Object
count : 1
即便它的count
属性告诉了你它其实包含了多少个元素
PS:\> $ageList.count
2
译者注 以上就是说hashtable被视为一个整体对象,因此你使用
Measure-Object
来获取它的元素个数的时候,你将得不到正确结果.很多初识powershell的童鞋不知道如何获取集合元素的个数,其实一般是通过在管道下一级使用Measure-Object
来实现的
measure-object 展示信息中count属性即为集合元素的个数.如果你想要通过程序化的方式来拿到这个count属性也很简单,就是把以上操再加一级Select Count
管道
measure
是measure-object
命令的另名.命令的别名和命令本身是等效的.
如果你需要的仅仅是值,则可以通过.values
属性来获取值,这个问题就解决了.(实际上values获取的是一个数组,数组使用measure-object是可以正确获取到元素个数的)
PS:\> $ageList.values | Measure-Object -Average
Count : 2
Average : 22.5
译者注 Meausre-object是获取元素个数信息的好帮手,如果没有任何参数只有count属性,这里指定的
Average
,实际上还可以指定Max
,Min
,Sum
等参数来获取集合元素的统计信息
通常情况下遍历hashtable的键集合,然后通过键来获取值是很有用的.
PS:\> $ageList.keys | ForEach-Object{
$message = '{0} is {1} years old!' -f $_, $ageList[$_]
Write-Output $message
}
Kevin is 36 years old
Alex is 9 years old
以下代码使用foreach(){...}
循环,效果是一样的
foreach($key in $ageList.keys)
{
$message = '{0} is {1} years old' -f $key, $ageList[$key]
Write-Output $message
}
译者注 由于这是一篇全面讲解hashtable的文章,因此很多地方超出了基本范围,很多没有powershell基础的童鞋可能看一些语法感觉很费劲,上面
ForEach-Object
管理可能看起来不如下面foreach
循环更为直观,更符合编程语言语法
我们遍历hashtable里的每一个key,然后使用key来索引元素的值,这是我们遍历hashtable的惯用方法.
使用GetEnumerator()方法
我们也可以使用GetEnumerator()
来遍历hashtable
$ageList.GetEnumerator() | ForEach-Object{
$message = '{0} is {1} years old!' -f $_.key, $_.value
Write-Output $message
}
迭代器迭代出一个个的键值对,它是专为这种场景使用设计的.谢谢Mark Kraus
提醒我这种方法
译者注: 使用迭代器可能在一些语言中很常用,但是在powershell里并不是很常用,一般使用
foreach
循环就好了
遍历异常
一个非常重要的细节是在遍历hashtable的时候,你不能修改它.我们仍然使用上面的$environments
来举例
$environments = @{
Prod = 'SrvProd05'
QA = 'SrvQA02'
Dev = 'SrvDev12'
}
如果我们试图把所有的值都设置成一样,则会运行失败
$environments.Keys | ForEach-Object {
$environments[$_] = 'SrvDev03'
}
An error occurred while enumerating through a collection: Collection was modified; enumeration operation may not execute.
+ CategoryInfo : InvalidOperation: tableEnumerator:HashtableEnumerator) [], RuntimeException
+ FullyQualifiedErrorId : BadEnumeration
以下看起来没问题,实际上同样运行时会出错
foreach($key in $environments.keys) {
$environments[$key] = 'SrvDev03'
}
Collection was modified; enumeration operation may not execute.
+ CategoryInfo : OperationStopped: (:) [], InvalidOperationException
+ FullyQualifiedErrorId : System.InvalidOperationException
这里有个小伎俩我们在遍历前先把keys复制一份
$environments.Keys.Clone() | ForEach-Object {
$environments[$_] = 'SrvDev03'
}
hashtable作为属性集合
截至目前我们往hashtable里添加的都是同一种类型元素.在powershell里hashtable一个常用的用法主是用它来存储一系列的属性集合,把属性名作为键,把属性值作为值.
基于属性的访问
基于属性的访问改变了hashtable的动态属性和使用poweshell的使用方式.下面示例使用上面的例子使用键来作为属性
$ageList = @{}
$ageList.Kevin = 35
$ageList.Alex = 9
和前面的示例一样,如果key不在集合里则会被添加进去.
$person = @{
name = 'Kevin'
age = 36
}
我们也可以使用下面方法来访问$person
的属性
$person.city = 'Austin'
$person.state = 'TX'
突然之间hashtable看起来像个对象,实际上它仍然是一个集合,对以上所有示例仍然是有效的.我们仅仅是从不同的视角来看待.
检测键和值
通常情况下,你可能使用如下方法来检测值
if( $person.age ){...}
它非常简单但是却是产生很多bug的源头因为以上忽略了一个重要的逻辑.我们使用它来检测一个key是否存在,但是如果正好值是$false或者0,以上检测将返回意外地返回false
if( $person.age -ne $null ){...}
以上解决了前面的问题但是仍然解决不了值正好是$null的情况.大多数情况下你不需要区分这些这么严格但是确立有方法解决这一问题:
if( $person.ContainsKey('age') ){...}
hashtable里还有一个ContainsValue
在你不知道key的时候判断一个value是否存在,而不用遍历整个集合.
删除和清空键
你可以使用Remove
方法来删除一个键
$person.remove('age')
把键的值设置为$null仅仅留下一个空key(值为$null,并不能把键删除掉)
一个常用的把集合清空的方法是把它的值设置为一个空集合
$person = @{}
也可以使用clear()
方法
$person.clear()
在这些示例中,使用方法使得代码整洁,不言自明.
关于有序hashtable
默认情况下,hashtable是无序
的.在传统的上下文中,你使用键来获取值顺序往往无关紧要.但是你使用它来存储属性的时候,你可能希望属性存储的顺序和你定义它们时候的顺序是一致的.幸好,可以使用ordered
关键字来定义.
$person = [ordered]@{
name = 'Kevin'
age = 36
}
这时候你再遍历它,它将保持顺序
行内hashtable
你可以把hashtable定义在一行,不同的键值之间用分号;
隔开
$person = @{ name = 'kevin'; age = 36; }
如果你是在管道中创建hashtable这将非常有用
在常见的管道命令里使用自定义表达式
有少数命令支持使用hashtable来创建自定义或者计算属性,最为常见的是Select-Object
和Format-Table
,hashtable有一种特殊的形式展开形式如下:
$property = @{
name = 'totalSpaceGB'
expression = { ($_.used + $_.free) / 1GB }
}
名字是命令用来标识列的,expression
是一个代码块可以被执行,$_
是从管道传过来的值,以下脚本使用了上面定义:
PS:\> $drives = Get-PSDrive | Where Used
PS:\> $drives | Select-Object -Properties name, $property
Name totalSpaceGB
---- ------------
C 238.472652435303
我把它放在了一个变量量,实际上可以使用内联的方式定义,你也可以使用n
作为name
的缩写,使用'e'作为expression
的缩写
$drives | Select-Object -properties name, @{n='totalSpaceGB';e={($_.used + $_.free) / 1GB}}
自定义排序表达式
如果集合中有你想要按照它来排序的字段,排序是非常容易的,你可以把数据添加到对象里或者使用Sort-Object
来创建一个自定义排序表达式
Get-ADUser | Sort-Object -Parameter @{ e={ Get-TotalSales $_.Name } }
在这个示例中,我取出了用户集合并使用自定义命令获取额外信息用来排序.
排序hashtable列表
如果你有一个hashtable的列表(list)想来排序,你会发现Sort-Object
并不会把键作为属性.我们可以使用自定义排序表达式来解决这个问题
$data = @(
@{name='a'}
@{name='c'}
@{name='e'}
@{name='f'}
@{name='d'}
@{name='b'}
)
$data | Sort-Object -Property @{e={$_.name}}
在命令中把hashtable打散
这是我最为喜欢的一个功能,早些时候很多人并不知道.除了把所有的属性都在一行内提供,你可以首先把它们打包成一个hashtable.然后你可以通过特殊方式把hashtable传入函数作为参数.以下是使用普通方法来创建DHCP
Add-DhcpServerv4Scope -Name 'TestNetwork' -StartRange'10.0.0.2' -EndRange '10.0.0.254' -SubnetMask '255.255.255.0' -Description 'Network for testlab A' -LeaseDuration (New-TimeSpan -Days 8) -Type "Both"
在不使用打散方法前,所有的参数都在一行甚至会超出屏幕视觉范围或者折行,下面我们比较一下使用hashtable打散的方法传入参数
$DHCPScope = @{
Name = 'TestNetwork'
StartRange = '10.0.0.2'
EndRange = '10.0.0.254'
SubnetMask = '255.255.255.0'
Description = 'Network for testlab A'
LeaseDuration = (New-TimeSpan -Days 8)
Type = "Both"
}
Add-DhcpServerv4Scope @DHCPScope
使用@
符而不是$
来调用hashtable的打散功能.
我们停下来欣赏这下这段代码可读性是多么的高!同样的命令,同样的值.下面的代码比上面可读性和可维护性都提高很多.
当命令参数变得很长的 时候,我就地考虑使用hashtable打散.
参数打散在可选参数中使用
在日常工作中,一个最为常见的情况是用打散来处理可选参数,比如说我有一个封闭好的名字叫作Get-CIMInstance
的方法,方法调用时有一个可选参数叫作$Credential
$CIMParams = @{
ClassName = 'Win32_Bios'
ComputerName = $ComputerName
}
if($Credential)
{
$CIMParams.Credential = $Credential
}
Get-CIMInstance @CIMParams
从最基本的参数开始,然后我添加了$Credential
参数如果它存在的话,因为这里使用了参数打散,在代码里仅需要调用Get-CIMInstance
一次,这种模式非常简洁并且可以很容易地处理很多常见的可选参数
多项打散
你可以把多个hashtable打散到一个cmdlet命令里,我们来看下其初的一个示例
$Common = @{
SubnetMask = '255.255.255.0'
LeaseDuration = (New-TimeSpan -Days 8)
Type = "Both"
}
$DHCPScope = @{
Name = 'TestNetwork'
StartRange = '10.0.0.2'
EndRange = '10.0.0.254'
Description = 'Network for testlab A'
}
Add-DhcpServerv4Scope @DHCPScope @Common
如果有一些共同的参数需要传入到许多不同的命令,我经常使用这种方法
为了代码的整洁使用打散
如果为了代码整洁,即便只打散一个参数也是不为过的
$log = @{Path = '.\logfile.log'}
Add-Content "logging this command" @log
hashtable相加
hashtable支持额外的操作签把两个hashtable相加
$person += @{Zip = '78701'}
嵌套hashtable
我们可以把hashtable作为另一个hashtable的值
$person = @{
name = 'Kevin'
age = 36
}
$person.location = @{}
$person.location.city = 'Austin'
$person.location.state = 'TX'
这个hashtable初始包含两个键,然后添加了一个键为location
值为一个空hatable的条目.我们也可以以内联的方式声明:
$person = @{
name = 'Kevin'
age = 36
location = @{
city = 'Austin'
state = 'TX'
}
}
这和上面创建的hashtable是等效的,我们也可以使用同样的方法来访问它的属性:
PS:> $person.location.city
Austin
有许多方法可以获取到对象的结构,下面是另一种视角来看待这个问题:
$people = @{
Kevin = @{
age = 36
city = 'Austin'
}
Alex = @{
age = 9
city = 'Austin'
}
}
这里混合使用了hashtable是对象集合和属性集合的概念.不管你使用什么方法,获取嵌套对象仍然是很简单的.
PS:\> $people.kevin.age
36
PS:\> $people.kevin['city']
Austin
PS:\> $people['Alex'].age
9
PS:\> $people['Alex']['City']
Austin
对我而言,当我把它们看作属性时我倾向于使用点号方法.它们都是我在代码里静态定义的我很容易知道它们.如果我想遍历集合或者从程序中获取键时,我会使用中括号加上键名
foreach($name in $people.keys)
{
$person = $people[$name]
'{0}, age {1}, is in {2}' -f $name, $person.age, $person.city
}
hashtable可以嵌套带来了更多编程灵活性选择
查看嵌套hashtable
当你开始使用hashtable的时候,你需要一个简单的方式从控制台查看它们.如果我们在控制台查看上面的hashtable,它像下面一样层次非常深:
ps:\> $people
Name Value
---- -----
Kevin {age, city}
Alex {age, city}
这里可以使用ConvertTo-JSON
因为它非常简洁并且我经常使用它来做其它事情
PS:\> $people | ConvertTo-JSON
{
"Kevin": {
"age": 36,
"city": "Austin"
},
"Alex": {
"age": 9,
"city": "Austin"
}
}
即便你不知道json,你仍然可以看明白它.powershell有一个Format-Custom
命令来查看结构化的数据但是我仍然更倾向使用json查看
创建对象
有些时候你需要创建一个对象来完成仅仅使用hashtable来保存一些属性无法完成的工作.最为常见的是你想把键作为列名.使用pscustomobject
可以使这项工作变得非常简单
$person = [pscustomobject]@{
name = 'Kevin'
age = 36
year=2014
}
PS:\> $person
name age
---- ---
Kevin 36
译者注,很多童鞋如果仅仅是看文章而没动手的话可能一下子看不明白加了
pscustomobject
之后和之前有什么区别,其它自动动手看一下主知道.hashtable展示的是键作为一列,值作为一列.一共两列,而对象有多少个属性就会有多少列.
即便在初始的时候你没有创建pscustomobject
,你仍然可以在需要使用的时候转换成它
$person = @{
name = 'Kevin'
age = 36
}
PS:\> [pscustomobject]$person
name age
---- ---
Kevin 36
保存为csv
尝试着把上面提到的hashtable转为csv是一件非常挣扎的事.把hashtable转为pscustomobject
可以正确地保存csv.如果你在创建的时候就使用了pscustomobject
则可以保存创建的顺序.但是你也可以使用内联的方式转化为pscustomobject
$person | ForEach-Object{ [pscustomobject]$_ } | Export-CSV -Path $path
把嵌套对象保存到文件
如果我想要把嵌套hashtable保存到文件并且可以还原回来,我会使用json命令来做
$people | ConvertTo-JSON | Set-Content -Path $path
$people = Get-Content -Path $path -Raw | ConvertFrom-JSON
这里有两个重要的点.首先写入文件时json文件是多行的,因此我需要使用Raw
选项把它读到到单行.第二点是导入的对象不再是一个hashtable,而是一个pscustomobject
,并非可能会产生非预期的结果
如果在导入的时候你想要它是一个hashtable,这时候你需要使用Export-CliXml
和Import-CliXml
命令
键仅仅是字符串
键仅仅是字符串,我们可以给任何对象加上引号把它变成键
$person = @{
'full name' = 'Kevin Marquette'
'#' = 3978
}
$person['full name']
你甚至可以做一些你认为为可能的奇怪的事:
$person.'full name'
$key = 'full name'
$person.$key
虽然你可以这样做,但并不意味着你应该这样做.最后一行很容易产生bug和误解.
从技术上讲,键并不仅仅是字符串(可以是字符串外其它对象).但是如果你仅仅使用字符串你可以把它当作字符串.
PSBoundParameters
PSBoundParameters
是一个仅仅存在于函数上下文的自动对象.它包含了函数需要调用的所有参数,准确地讲它并不是一个hashtable但是你可以把它当作hashtable.
它包括的移除键和打散到其它函数.想进一步了解它,请查看微软官方文档以了解更多细节.
PSBoundParameters 问题
一件很重要的事是它仅仅包含了传入的参数.如果你不家其它默认参数但是没有被调用者传入进来,PSBoundParameters
不会包含这些值,这一点经常被忽略.
PSDefaultParameterValues
这个自动变量让你可以在不改变命令情况下给它指定默认值:
$PSDefaultParameterValues["Out-File:Encoding"] = "UTF8"
这添加了一个把Out-File
的-Encoding
参数值默认设置为UTF8
hashtable.这仅仅是对特定session有效的因此你需要把它添加到$profile
当需要经常键入一些命令的时候我经常预先赋一些值
$PSDefaultParameterValues[ "Connect-VIServer:Server" ] = 'VCENTER01.contoso.local'
它还接收通配符,因此你可以批量设置
$PSDefaultParameterValues[ "Get-*:Verbose" ] = $true
$PSDefaultParameterValues[ "*:Credential" ] = Get-Credental
正则匹配
当你使用-match
操作符,一个叫作$matches
的变量被创建作来保存结果,如果你的正则中有子表达式,这些子表达式的结果也被列出
$message = 'My SSN is 123-45-6789.'
$message -match 'My SSN is (.+)\.'
$Matches[0]
$Matches[1]
命名匹配
这是一个我非常喜欢的,很多人都不知道的特性.如果你使用的命名匹配,你可以使用名字来访问它
$message = 'My Name is Kevin and my SSN is 123-45-6789.'
if($message -match 'My Name is (?<Name>.+) and my SSN is (?<SSN>.+)\.')
{
$Matches.Name
$Matches.SSN
}
以上示例中,`(?<Name>.*)`是子表达式的名称.值被存储在`$Matches.Name`属性里
## Group-Object -AsHashtable
关于`Group-Object`一个鲜为人知的特性是:它可以把一些数据集转化为hashtable
Import-CSV $Path | Group-Object -AsHashtable -Property email
这会把每一行都添加到hashtable,使用指定的键来访问它.
## 拷贝hashtable
很重要的一点是hashtable是对象的集合.每一个变量都是对一个对象的引用,这就意味着想要拷贝一个hashtable会有更多的工作要做
### 赋值引用类型
当你有一个hashtable并且你把它赋值给一个变量,它们都批向同一个hashtable
PS> $orig = @{name='orig'}
PS> $copy = $orig
PS> $copy.name = 'copy'
PS> 'Copy: [{0}]' -f $copy.name
PS> 'Orig: [{0}]' -f $orig.name
Copy: [copy]
Orig: [copy]
这个示例表名它们是同一个对象因为任意的一个改变都会影响到另一个.把hashtable传入其它的函数也是如此,如果这个函数改变了hashtable的值,原始的hashtable也被改变
### 一级浅拷贝
如果我们的hashtable像上面示中那样非常简单,我们可以使用`.Clone()`做个浅拷贝
PS> $orig = @{name='orig'}
PS> $copy = $orig.Clone()
PS> $copy.name = 'copy'
PS> 'Copy: [{0}]' -f $copy.name
PS> 'Orig: [{0}]' -f $orig.name
Copy: [copy]
Orig: [orig]
这样我们改变其中一个对象就不会改变另一个.
### 嵌套浅拷贝
我之所以叫它浅拷贝因为它仅仅拷贝了基层属性.如果其中 一个属性是引用对象(比如说是一个hashtable),这时候嵌套对象之间仍然有互相引用关系.
PS> $orig = @{
person=@{
name='orig'
}
}
PS> $copy = $orig.Clone()
PS> $copy.person.name = 'copy'
PS> 'Copy: [{0}]' -f $copy.person.name
PS> 'Orig: [{0}]' -f $orig.person.name
Copy: [copy]
Orig: [copy]
你会 看到即便我克隆了hashtable,对person对象的引用并没有克隆,我们需要一个正真的深拷贝来使它们之间不再有关联
### 深拷贝
在写此篇文章的时候,我还没有找到一个更聪明的方法来对hashtable做深拷贝.下面是一个快速方法来实现深拷贝
function Get-DeepClone
{
[cmdletbinding()]
param(
$InputObject
)
process
{
if($InputObject -is [hashtable]) {
$clone = @{}
foreach($key in $InputObject.keys)
{
$clone[$key] = Get-DeepClone $InputObject[$key]
}
return $clone
} else {
return $InputObject
}
}
}
这并不能处理数组或其它的引用类型,但是它是一个好的开端
## 结语
我快速的讲述了一些基础知识.每当你看这篇文章的时候我希望你能从别处学到一些新的知识以便可以理好的理解.因为我涵盖了所有的范围,很多特征并不能马上对你有用.
原文链接:https://kevinmarquette.github.io/2016-11-06-powershell-hashtable-everything-you-wanted-to-know-about/#adding-hashtables
Powershell:关于hashtable你想知道的一切的更多相关文章
- Powershell:关于PSCustomObject你想知道的一切(译)
PSCustomObject是Powershell里非常重要的一个工具,我们先从基础开始然后再循序渐进讲到一些更高级的话题.PSCustomObject旨在于用简单的方法来创建结构化数据.下面的第一个 ...
- 【转】PowerShell入门(四):如何高效地使用交互式运行环境?
转至:http://www.cnblogs.com/ceachy/archive/2013/02/05/PowerShell_Interacting_Environment.html 在开始关于脚本. ...
- linux下的powershell,pash试用手记
------1 概述------ 1.1 简单来说linux,unix是非常依赖脚本的,而win不是.win中有很多图形程序+c库,效率不比脚本差.点几下鼠标照样能完成需求.当 然,图形和字符是两码事 ...
- 从零开始——PowerShell应用入门(全例子入门讲解)
学习一门技术,不止要会,还要善用,例子就是带你快速入门的最佳利器.本文就是要用例子,不,大量的例子来带你走进PowerShell应用世界. 本文主要介绍一些PowerShell入门的基础知识,对技术小 ...
- C#下Hashtable和Dictionary之间的差别
Hashtable和Dictionary都是.Net下的表示键值对的集合,那么我们在使用中该选择Hashtable还是Dictionary?下边我们看看他们之间的区别:1.Dictionary< ...
- C#中hashtable如何嵌套遍历
嵌套hashtable的遍历取值怎么做 hastable中嵌套了hashtable,想用递归的方式把所有hashtable中的key和value取出来 foreach (DictionaryEntry ...
- java-concurrent包
通常所说的concurrent包基本有3个package组成 java.util.concurrent:提供大部分关于并发的接口和类,如BlockingQueue,Callable,Concurren ...
- 集合类--最详细的面试宝典--看这篇就够用了(java 1.8)
看了一个星期源码,搜索上百篇博文,终于总结出了集合类的所有基础知识点,学集合,看这篇就够用了!!! 篇幅有点长, 如果你能全部理解,java最重要的集合就不怕了,秒过面试!!!(本篇素材来自网络,如有 ...
- [转]windows10 1703 鼠标右键打开命令提示符cmd
https://answers.microsoft.com/zh-hans/windows/forum/windows_10-performance/windows10-1703/8bdfdfea-4 ...
随机推荐
- java用jsoup解析HTML
步骤 1获取document对象 //方法一 Document doc = Jsoup.connect(网址).get() //方法二 Document doc = Jsoup.parse(html字 ...
- Fio测试工具参数
以随机读为例:fio -ioengine=libaio -group_reporting -direct=1 -name=testsda -numjobs=1 --time_based --runti ...
- 马昕璐/唐月晨 《面向对象程序设计(java)》第十一周学习总结
一:理论部分. 一般将数据结构分为两大类:线性数据结构和非线性数据结构 线性数据结构:线性表.栈.队列.串.数组和文件 非线性数据结构:树和图. 线性表:1.所有数据元素在同一个线性表中必须是相同的数 ...
- C# WinForm:DataTable中数据复制粘贴操作的实现
1. 需要实现类似于Excel的功能,就是在任意位置选中鼠标起点和终点所连对角线所在的矩形,进行复制粘贴. 2. 要实现这个功能,首先需要获取鼠标起点和终点点击的位置. 3. 所以通过GridView ...
- Dev_GridView:使用PopupContainerControl实现下拉树形列表
要使用 DevExpress 实现下拉列表树,需要使用三个控件结合才可以实现 PopupContainerEdit.PopupContainerControl.TreeList 设置控件 PopupC ...
- SEED实验——return-to-libc实验
实验概述 本实验的学习目标是让学生获得缓冲区溢出攻击的一种有趣变体——return-to-libc攻击实验的亲身体验.这种攻击可以绕过目前在主要linux操作系统中实现的现有保护方案.利用缓冲区溢出漏 ...
- HBuilder git使用-建立仓库,邀请用户
1.git环境配置好后,在Github上注册好帐号 2. 创建一个Respository(代码仓库) 3.邀请其他小组用户(必须的,要不别人提交不了修改) 4.把邀请链接要COPY给其他用户 5. 其 ...
- [Swift]LeetCode42. 接雨水 | Trapping Rain Water
Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...
- python 模拟豆瓣登录(豆瓣6.0)
最近在学习python爬虫,看到网上有很多关于模拟豆瓣登录的例子,随意找了一个试了下,发现不能运行,对比了一下代码和豆瓣网站,发现原来是豆瓣网站做了修改,增加了反爬措施. 首先看下要模拟登录的网站: ...
- Build Assimp library for Android
Build Assimp library for Android 首先各路教程中有推荐使用 NDK 或者 STANDALONE TOOLCHAIN 编译的,根据我的理解,这两种方式都是可以的,如果能直 ...