热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

华为OPS,自定义命令,动态执行命令

 OPS    开放可编程系统OPS(Open Programmability System)是指设备通过提供统一的应用程序接口API(Application Programmin

 OPS

    开放可编程系统OPS(Open Programmability System)是指设备通过提供统一的应用程序接口API(Application Programming Interface)来开放系统,使得系统具备可编程能力。

华为设备OPS的使用分为订阅和执行两个阶段,两者关系类似于触发器和active,在ops环境中两个阶段函数名固定为ops_condition,ops_execute两个函数下可以自定义订阅内容和执行语句,其中交换机内置一些环境变量,如用户输入,lldp邻居状态等,也支持用户自定义变量

应用场景

  使用OPS功能可以自定义系统命令,例如可以自定义health命令来执行查看cpu,内存,温度等一系列命令,获取设备状态

在割接时也可以自定义命令来执行一系列py脚本里预定义的配置

 

以S9300为例,列举设备支持的OPS API



















































































适用阶段


OPS API


订阅阶段


命令行事件订阅


定时器事件订阅


路由变更事件订阅


日志事件订阅


告警事件订阅


LLDP邻居变化事件订阅


单板状态变化事件订阅


端口统计事件订阅


多条件关系组合


组合事件触发器


执行阶段


打开命令行通道


执行命令行命令


关闭命令行通道


向终端打印提示信息


从终端读取用户输入


支持常驻脚本


返回事件执行结果


订阅阶段和执行阶段


获取环境变量


通过SNMP获取设备信息(get)


通过SNMP获取设备信息(getnext)


记录日志


保存脚本变量


恢复脚本变量


OPS API示例

 

命令行事件订阅

result1_value, result2_description = ops.cli.subscribe(tag, pattern, enter=False, sync=True, async_skip=False, sync_wait=30)

参数说明










































参数


参数说明


取值


tag


用于标识条件。


字符串形式,不区分大小写,长度范围是1~12,由字母、数字和下划线组成,以字母开头。tag不能为""、None、and、or以及andnot,不能包含\0。


pattern


指定匹配命令的正则表达式。


字符串形式,取值范围是1~128个字符,不能包含\0。


enter


指定匹配正则表达式的时间。


布尔型,取值如下:



  • True:表示按回车键后立刻匹配正则表达式。



  • False:表示命令中缩写的关键字以完整的形式进行匹配。



缺省值是False。


sync


指定命令行触发执行动作后,是否等待脚本执行结束。


布尔型,取值如下:



  • True:表示等待。



  • False:表示不等待。



缺省值是True。


async_skip


在sync取值为False时,指定是否跳过原有命令执行。


布尔型,取值如下:



  • True:表示跳过。



  • False:表示不跳过。



缺省值是False。


sync_wait


在sync取值为True时,指定命令行同步等待脚本执行的时间。


整数形式,取值范围是1~2147483647,单位是秒。缺省值是30秒。


 

路由变更事件订阅

result1_value, result2_description = ops.route.subscribe(tag, network, maskLen, minLen=None, maxLen=None, neLen=None, optype=all, protocol=all)

参数说明




















































参数


参数说明


取值


tag


用于标识条件。


字符串形式,不区分大小写,长度范围是1~12,由字母、数字和下划线组成,以字母开头。tag不能为""、None、and、or以及andnot,不能包含\0。


network


指定路由前缀。


点分十进制形式。


maskLen


指定掩码长度。


整数形式,取值范围是0~32。


minLen


指定掩码长度匹配范围的下限。


整数形式,必须大于等于maskLen的值。缺省值是None,表示掩码长度匹配范围的下限是0。


maxLen


指定掩码长度匹配范围的上限。


整数形式,必须大于等于minLen的值。缺省值是None,表示掩码长度匹配范围的上限是0。


neLen


指定不匹配的掩码长度。


整数形式,必须大于等于minLen的值,小于等于maxLen的值。缺省值是None,表示不匹配的掩码长度是0。


optype


指定路由事件变更类型。


枚举类型,取值如下:



  • add:新增路由。



  • delete:删除路由。



  • modify:修改路由。



  • all:全部变化。



缺省值是all。


protocol


指定路由协议属性。


字符串形式,缺省值为all,表示所有路由协议。



  • direct:直连路由



  • static:静态路由



  • ospf:OSPF路由



  • isis:IS-IS路由



  • bgp:BGP路由



  • rip:RIP路由



  • unr:用户网络路由




 

打开命令行通道

result1_handle, result2_description = ops.cli.open()

第一个返回值:命令行句柄。None表示错误,其他值为命令行句柄。第二个返回值:失败原因(仅当第一个返回值为None时返回)。

使用说明

脚本中打开的命令行通道,用户级别为15。

脚本中打开命令行通道后,才能向设备下发执行命令。

一个脚本中只能创建一个命令行通道,再创建第二个命令行通道时,将返回失败。

每打开一个命令行通道,消耗一个VTY资源。通过display users命令可以看到该VTY资源被Assistant: Name占用。当设备上剩余的VTY资源少于等于3个时,打开命令行通道失败。因此,脚本中,创建命令行通道并执行完命令后,需要通过关闭命令行通道接口(ops.cli.close(fd))及时关闭命令行通道,节省VTY资源。

执行命令行命令和关闭命令行通道接口使用打开命令行通道接口的第一个返回值作为输入参数。因此使用打开命令行通道接口时,必须指定返回值

 

OPS 脚本模板

1 # -*- coding: utf-8 -*- # 声明使用utf-8编码格式,可以在Python脚本中添加中文注释。
2
3 # 固定语句,导入ops模块。导入ops模块后,才能在脚本中使用设备支持的OPS API。详见OPS API列表。
4 import ops
5 # 固定语句,导入sys模块。sys模块负责程序与设备内置Python解释器的交互,提供了一系列的函数和变量。
6 # 导入sys模块后,可以使用这些函数和变量。函数和变量的相关信息,请参考官方Python文档。
7 import sys
8 # 固定语句,导入os模块。os模块负责程序与操作系统的交互,提供了访问操作系统底层的接口。
9 # 导入os模块后,可以使用这些接口。接口的相关信息,请参考官方Python文档。
10 import os
11
12 # 固定语句,定义订阅处理函数ops_condition。该函数在配置脚本助手的时候调用,用于订阅事件,由设备内置的框架脚本_frame.py调度执行。
13 # 函数ops_condition的输入参数是_frame.py中创建的ops对象,用户可以在该对象下进行数据访问。
14 def ops_condition(ops):
15 # 当前是订阅阶段,需要使用适用于订阅阶段的OPS API,详见设备支持的OPS API中的表6-1。以下以定时器事件订阅为例。
16 # 使用ops.timer.cron接口订阅一个定时器,以t1标识。其含义为在每周一06:00触发执行阶段指定的动作。可以根据实际需求修改该定时器。
17 # 当输入的参数值为字符串时,需要在字符串两端使用双引号。
18 # status和err_str为用户定义的脚本变量,分别表示ops.timer.cron接口的第一个返回值和第二个返回值。
19 # 通常在调试阶段,可以通过print语句将返回值打印出来,便于查看调试信息和定位问题。
20 # 对于OPS API,用户可以根据实际需求决定是否需要返回值。如需要返回值,则必须根据各OPS API接口原型指定返回值的个数。
21 # 返回值的含义因OPS API而异。详细描述请参见各OPS API。
22 # 对于ops.timer.cron接口,第一个返回值是数字时,0表示该API执行成功,1表示该API执行失败。
23 # 第二个返回值仅当第一个返回值为1时返回,为字符串形式,描述执行失败的原因。
24 status, err_str = ops.timer.cron("t1", "0 6 * * 1")
25 # 指定函数的返回值。函数的返回值可以作为处理结果,也可以通过result函数明确返回处理结果(详见返回事件执行结果)。
26 # 函数的返回值作为函数的输出,可以赋值给其他变量,作为其他函数的输入。
27 # 这里指定函数ops_condition的返回值为0,表示返回值为0时,ops_condition函数执行成功。
28 return 0
29
30 # 固定语句,定义执行处理函数ops_execute。该函数在脚本事件执行的时候调用,用于执行动作,由设备内置的框架脚本_frame.py调度执行。
31 # 函数ops_execute的输入参数是_frame.py中创建的ops对象,用户可以在该对象下进行数据访问。
32 def ops_execute(ops):
33 # 当前是执行阶段,需要使用适用于执行阶段的OPS API,详见设备支持的OPS API中的表6-1。
34 # 以下以打开命令行通道、执行命令行命令和关闭命令行通道为例。
35 # 打开命令行通道。只有打开命令行通道之后,才能执行命令行。执行完命令行之后,需要关闭命令行通道。
36 # handle和err_desp为用户定义的脚本变量,分别表示ops.cli.open接口的第一个返回值和第二个返回值。
37 # 通常在调试阶段,可以通过print语句将返回值打印出来,便于查看调试信息和定位问题。
38 # 执行命令行命令和关闭命令行通道接口使用打开命令行通道接口的第一个返回值作为输入参数。因此使用打开命令行通道接口时,必须指定返回值。
39 handle, err_desp = ops.cli.open()
40 # 执行命令display interface gigabitethernet 1/0/1。
41 # 返回值result为None时,表示命令行未能发送给CLI或者命令行执行超时,其他值为显示输出,即CLI中执行的命令行。
42 # 返回值n11为Next:0表示后续没有输出了,Next:1表示后续还有输出。返回值n12仅在返回值result为None时显示,表示命令行执行失败的原因。
43 result1, n11, n12 = ops.cli.execute(handle, "display interface gigabitethernet 1/0/1")
44 # 执行命令display current-configuration interface gigabitethernet 1/0/1。
45 result2, n21, n22 = ops.cli.execute(handle, "display current-configuration interface gigabitethernet 1/0/1")
46 # 命令行执行结束,关闭命令行通道。
47 result = ops.cli.close(handle)
48 # 将display interface gigabitethernet 1/0/1命令的显示结果记录到日志中,可以在日志文件中查看相应信息。
49 log1, descri_str1 = ops.syslog(result1, "informational", "syslog")
50 # 将display current-configuration interface gigabitethernet 1/0/1命令的显示结果记录到日志中,可以在日志文件中查看相应信息。
51 log2, descri_str2 = ops.syslog(result2, "informational", "syslog")
52 # 指定函数的返回值。函数的返回值可以作为处理结果,也可以通过result函数明确返回处理结果(详见返回事件执行结果)。
53 # 函数的返回值作为函数的输出,可以赋值给其他变量,作为其他函数的输入。
54 # 这里指定函数ops_execute的返回值为0,表示返回值为0时,ops_execute函数执行成功。
55 return 0

 

OPS 功能示例

  侦听LLDP邻居状态自动添加接口描述

  python脚本

1 # -*- coding: utf-8 -*-
2 import ops # 导入ops模块
3 import sys # 导入sys模块
4 import os # 导入os模块
5 import re # 导入re模块,正则表达式
6 # 订阅处理函数
7 def ops_condition (ops):
8 # 检测有新增邻居事件,这里仅订阅邻居是交换机和路由器类型的事件,如果需要订阅其他类型的事件,请按照下面格式补充
9 value1, err_str1 = ops.lldp.subscribe("add1", ops.lldp.LLDP_NEIGHBOR_EVENT_ADD, "INTERFACE_ALL", ops.lldp.LLDP_NEIGHBOR_TYPE_SWITCH)
10 value11, err_str11 = ops.lldp.subscribe("add2", ops.lldp.LLDP_NEIGHBOR_EVENT_ADD, "INTERFACE_ALL", ops.lldp.LLDP_NEIGHBOR_TYPE_ROUTER)
11
12 # 检测有删除邻居事件
13 value2, err_str2 = ops.lldp.subscribe("delete1", ops.lldp.LLDP_NEIGHBOR_EVENT_DEL, "INTERFACE_ALL", ops.lldp.LLDP_NEIGHBOR_TYPE_SWITCH)
14 value22, err_str21 = ops.lldp.subscribe("delete2", ops.lldp.LLDP_NEIGHBOR_EVENT_DEL, "INTERFACE_ALL", ops.lldp.LLDP_NEIGHBOR_TYPE_ROUTER)
15
16 # 组合事件,新增邻居或删除邻居,最多支持8个事件组合
17 value10, err_str10 = ops.correlate("add1 or add2 or delete1 or delete2")
18 return 0
19
20 # 工作处理函数
21 def ops_execute (ops):
22 # 获取系统环境变量_lldp_event,表示事件触发类型
23 key, value = ops.environment.get("_lldp_event")
24 inter, value = ops.environment.get("_lldp_interface")
25
26 if key == "OPR_TYPE_ADD":
27
28 # 打开命令行通道
29 handle, err_desp = ops.cli.open()
30 neighbor, n11, n21 = ops.cli.execute(handle,"display lldp neighbor interface " + inter)
31
32 resultsys = re.search(r'System[\s]+name[\s:]*\S*', neighbor).group()
33 sysname = re.split(':', resultsys)
34
35 resultport = re.search(r'Port\s+ID\s{2,}:*\S*', neighbor).group()
36 port = re.split(':', resultport)
37
38 # 进入系统视图
39 result, n11, n21 = ops.cli.execute(handle,"system-view")
40
41 # 进入接口视图
42 result, n11, n21 = ops.cli.execute(handle,"interface " + inter)
43
44 # 设置接口描述信息
45 result, n11, n21 = ops.cli.execute(handle,"description " + "To-" + sysname[1] + "-" + port[1])
46
47
48 # 关闭命令行通道
49 result = ops.cli.close(handle)
50
51
52 elif key == "OPR_TYPE_DEL":
53 handle, err_desp = ops.cli.open()
54
55 # 进入系统视图
56 result, n11, n21 = ops.cli.execute(handle,"system-view")
57
58 # 进入接口视图
59 result, n11, n21 = ops.cli.execute(handle,"interface " + inter)
60
61 # 设置接口描述信息
62 result, n11, n21 = ops.cli.execute(handle,"undo description")
63
64 # 关闭命令行通道
65 result = ops.cli.close(handle)
66
67 else:
68 return 1
69 return 0

交换机配置

#下载lldp.py文件
tftp 10.0.64.74 get ops/lldp.py
#ops 安装 lldp.py
ops install file lldp.py
#查看是否被安装
dir $_user/
Directory of flash:
/$_user/
Idx Attr Size(Byte) Date Time FileName
0 drw
- - Oct 15 2021 15:54:30 __pycache__
1 -rw- 2,603 Oct 14 2021 15:29:20 lldp.py
2 drw- - May 27 2020 11:35:19 huawei_pys
3 -rw- 612 Oct 14 2021 16:43:13 dangerouscli.py
4 -rw- 912 Oct 15 2021 11:47:06 ospfroute.py
5 -rw- 2,145 Oct 15 2021 15:54:20 20211015.py
6 -rw- 471 Oct 14 2021 15:25:17 portshutdown.py
#ops注册
[test]ops
[test
-ops] script-assistant python lldp.py
#设备开启lldp
[test]lldp enable
#查看接口是否自动配置描述信息
[test]dis cu int MEth 0/0/1
#
interface MEth0/0/1
description To
-CN-ZhZ01-SW-B-eth-0-10
ip address
10.0.3.105 255.255.255.0
#
#
禁用LLDP
[test]undo lldp enable
#查看接口描述信息是否被删除
Info: Global LLDP is disabled successfully.
[test]dis cu int me
[test]dis cu int MEth 0
/0/1
#
interface MEth0/0/1
ip address
10.0.3.105 255.255.255.0

 

 

阻止危险命令并发出告警

  python脚本,切记脚本名不要和ban掉的命令重名

import ops
def ops_condition (ops):
value1, descri_str1
= ops.cli.subscribe("cli1", "reboot", enter=False, sync=False,async_skip=True, sync_wait=60)
value2, descri_str2
= ops.cli.subscribe("cli2", "stp disable", enter=False, sync=False,async_skip=True, sync_wait=60)
value3, descri_str3
= ops.cli.subscribe("cli3", "stp enable", enter=False, sync=False,async_skip=True, sync_wait=60)
value10, err_str10
= ops.correlate("cli1 or cli2 or cli3")
return 0
def ops_execute (ops):
value, descri_str
= ops.terminal.write("Dangerous order, please contact the administrator to execute", vty="all")

验证

#加载ops略
#
执行关闭与开启stp和reboot命令
[test]stp enable
[test]
Dangerous order, please contact the administrator to execute
[test]undo stp enable
[test]
Dangerous order, please contact the administrator to execute
[test]q
reboot

Dangerous order, please contact the administrator to execute

 

路由状态联动接口状态

  脚本

import ops,sys
def ops_condition (ops):
#result1_value, result2_description = ops.route.subscribe(tag, network, maskLen, minLen=None, maxLen=None, neLen=None, optype=all, protocol=all)
#network可以自定义环境变量,在ops视图下使用environment ospf_routes 10.2.1.0设定值
#获取自定义环境变量值
slotid, errstr = ops.environment.get("ospf_routes")
value,descri_str
=ops.route.subscribe("route1", slotid, 24, minLen=None, maxLen=None, neLen=None, optype="all", protocol="ospf")
return 0
def ops_execute (ops):
key,values
= ops.environment.get("_routing_type")
if key == "Delete":
handle, err_desp
= ops.cli.open()
cli, n11, n21
= ops.cli.execute(handle,"sys")
cli, n11, n21
= ops.cli.execute(handle,"interface vlan 1588")
cli1, n12, n22
= ops.cli.execute(handle,"shutdown")
result
= ops.cli.close(handle)

  测试

#定义环境变量
[test-ops] environment ospf_routes 122.114.1.0
#加载ops脚本略
#
查看ospf路由
[test]dis ospf routing 122.114.1.0
OSPF Process
1 with Router ID 192.168.35.60
Destination :
122.114.1.0/24
AdverRouter :
5.5.5.5 Area : 0.0.0.0
Cost :
2 Type : Stub
NextHop :
10.35.0.133 Interface : Vlanif1588
Priority : Low Age : 22h42m42s
[test]
#删除接口ospf后查看vlanif接口是否自动down
interface Vlanif1588
ip address
10.35.0.134 255.255.255.252
ospf enable
1 area 0.0.0.0
#
return
[test
-Vlanif1588]undo ospf enable ar 0
[test
-Vlanif1588]dis this
#
interface Vlanif1588
shutdown
ip address
10.35.0.134 255.255.255.252
#
return
[test
-Vlanif1588]

 

 

割接,自定义三条命令,start开始做割接配置,rollback回滚配置,end删除ops脚本

  脚本

import ops,sys,os,re
def ops_condition (ops):
value, descri_str
= ops.cli.subscribe("cli1", "start", enter=True, sync=False,async_skip=True, sync_wait=60)
value1, descri_str1
= ops.cli.subscribe("cli2", "rollback", enter=True, sync=False,async_skip=True, sync_wait=60)
value2, descri_str2
= ops.cli.subscribe("cli3", "end", enter=True, sync=False,async_skip=True, sync_wait=60)
value10, err_str10
= ops.correlate("cli1 or cli2 or cli3")
return 0
def ops_execute (ops):
key,value
= ops.environment.get('_cli_command')
if key =="start":
#value, descri_str = ops.terminal.write(key, vty="all")
handle, err_desp = ops.cli.open()
ops.cli.execute(handle,
"system-view")
ops.cli.execute(handle,
"ospf")
ops.cli.execute(handle,
"ar 0")
ops.cli.execute(handle,
"vlan 1587")
ops.cli.execute(handle,
"interface vlan 1587")
ops.cli.execute(handle,
"ip address 10.35.0.33 30")
ops.cli.execute(handle,
"ospf enable area 0")
ops.cli.execute(handle,
"interface XGigabitEthernet 0/0/5")
ops.cli.execute(handle,
"port link-type trunk")
ops.cli.execute(handle,
"undo port trunk allow-pass vlan 1")
ops.cli.execute(handle,
"port trunk allow-pass vlan 1587")
ops.cli.execute(handle,
"quit")
result
= ops.cli.close(handle)
elif key =="rollback":
handle, err_desp
= ops.cli.open()
ops.cli.execute(handle,
"system-view")
ops.cli.execute(handle,
"undo interface vlan 1587")
ops.cli.execute(handle,
"undo vlan 1587")
ops.cli.execute(handle,
"interface XGigabitEthernet 0/0/5")
ops.cli.execute(handle,
"undo port trunk allow-pass vlan 1587")
ops.cli.execute(handle,
"undo port link-type")
ops.cli.execute(handle,
"quit")
result
= ops.cli.close(handle)
elif key =='end':
handle, err_desp
= ops.cli.open()
ops.cli.execute(handle,
"system-view")
ops.cli.execute(handle,
"ops")
ops.cli.execute(handle,
"undo script-assistant python 20211015.py")
ops.cli.execute(handle,
"quit")
ops.cli.execute(handle,
"quit")
ops.cli.execute(handle,
"ops uninstall file 20211015.py")
ops.cli.execute(handle,
"delete 20211015.py")
ops.cli.execute(handle,
"y")
result
= ops.cli.close(handle)

测试

[test]dis vlan 1587
Error: The VLAN does
not exist.
[test]start
[test]dis vlan
1587
--------------------------------------------------------------------------------
U: Up; D: Down; TG: Tagged; UT: Untagged;
MP: Vlan
-mapping; ST: Vlan-stacking;
#: ProtocolTransparent-vlan; *: Management-vlan;
--------------------------------------------------------------------------------
VID Type Ports
--------------------------------------------------------------------------------
1587 common TG:XGE0/0/5(D)
VID Status Property MAC
-LRN Statistics Description
--------------------------------------------------------------------------------
1587 enable default enable disable VLAN 1587
[test]dis cu int vlan
1587
#
interface Vlanif1587
ip address
10.35.0.33 255.255.255.252
ospf enable
1 area 0.0.0.0
#
return
[test]rollback
[test]dis vlan
1587
Error: The VLAN does
not exist.
[test]end
[test]dis ops assistant current
------------------------------------------------------------------
Assistant State Condition
------------------------------------------------------------------
lldp.py ready multi
dangerouscli.py ready multi
ospfroute.py ready URM
------------------------------------------------------------------

 华为ops核心思想

  调用OPS API配置侦听事件,编写事件所触发的执行脚本,命令行能实现的功能都可以写入脚本,也可以读取系统变量来动态执行命令

以驱魔为理想,为生计而奔波



推荐阅读
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • 本文比较了eBPF和WebAssembly作为云原生VM的特点和应用领域。eBPF作为运行在Linux内核中的轻量级代码执行沙箱,适用于网络或安全相关的任务;而WebAssembly作为图灵完备的语言,在商业应用中具有优势。同时,介绍了WebAssembly在Linux内核中运行的尝试以及基于LLVM的云原生WebAssembly编译器WasmEdge Runtime的案例,展示了WebAssembly作为原生应用程序的潜力。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 20211101CleverTap参与度和分析工具功能平台学习/实践
    1.应用场景主要用于学习CleverTap的使用,该平台主要用于客户保留与参与平台.为客户提供价值.这里接触到的原因,是目前公司用到该平台的服务~2.学习操作 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 使用在线工具jsonschema2pojo根据json生成java对象
    本文介绍了使用在线工具jsonschema2pojo根据json生成java对象的方法。通过该工具,用户只需将json字符串复制到输入框中,即可自动将其转换成java对象。该工具还能解析列表式的json数据,并将嵌套在内层的对象也解析出来。本文以请求github的api为例,展示了使用该工具的步骤和效果。 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 展开全部下面的代码是创建一个立方体Thisexamplescreatesanddisplaysasimplebox.#Thefirstlineloadstheinit_disp ... [详细]
  • 不同优化算法的比较分析及实验验证
    本文介绍了神经网络优化中常用的优化方法,包括学习率调整和梯度估计修正,并通过实验验证了不同优化算法的效果。实验结果表明,Adam算法在综合考虑学习率调整和梯度估计修正方面表现较好。该研究对于优化神经网络的训练过程具有指导意义。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
author-avatar
刘洁05_836
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有