一、安装和部署
1、上传并解压安装包
tar -zxvf kafka_2.12-3.3.1.tgz -C /opt/program/ 2、修改解压后的文件名称
cd /opt/program/ mv kafka_2.12-3.3.1/ kafka 3、进入到/opt/program/kafka 目录,修改配置文件
cd config/ vim server.properties 输入以下内容:
4、分发到slave1和slave2
scp -r /opt/program/kafka root@slave1:/opt/program/ scp -r /opt/program/kafka root@slave2:/opt/program/ 5、分别在 slave1和 slave2上修改配置文件
kafka/config/server.properties 中的 broker.id 及 advertised.listeners
注:broker.id 不得重复,整个集群中唯一。
vim kafka/config/server.properties 分别在slave1和slave2中进行以下修改: broker.id=1 #broker 对外暴露的 IP 和端口 (每个节点单独配置) advertised.listeners=PLAINTEXT://slave1:9092 broker.id=2 #broker 对外暴露的 IP 和端口 (每个节点单独配置) advertised.listeners=PLAINTEXT://slave2:9092 6、配置环境变量
vim /etc/profile 添加以下内容: #KAFKA_HOME export KAFKA_HOME=/opt/program/kafka export PATH=$PATH:$KAFKA_HOME/bin source /etc/profile 7、分发环境变量文件到其他节点,并 source。
目录 前言一、代理ip介绍以及面临的挑战二、获取AIGC前沿信息缺口1、最新AIGC前沿信息来源2、确定关键字3、可能涉及到的字段 三、使用代理ip抓取数据1、选择代理ip服务2、如何使用BrightData代理ip抓取数据(1)注册登录(2)代理IP服务(3)亮数据浏览器抓取数据(4)定制数据集 总结 如何使用代理ip服务高效采集最新AIGC前沿信息
前言 信息化时代,代理IP服务的重要性不仅体现在保护个人隐私和数据安全,绕过地理限制以访问受限内容,加强网络安全以及支持数据采集等方面,还有利于匿名访问和翻墙上网,帮助用户维护网络自由和个人权利,促进信息的自由流动和知识的共享,因此在当前信息化社会中,代理IP服务的作用愈发重要和不可或缺。
一、代理ip介绍以及面临的挑战 代理IP(Proxy IP)是由代理服务器提供的用于隐藏用户真实IP地址的IP地址。在互联网上,用户的IP地址是唯一标识其设备和位置的数字标签。使用代理IP可以实现一些特定的目的,例如保护用户隐私、绕过地理限制、访问被封锁的网站等。但是代理IP又面临着许多挑战:
1.封禁和封锁: 很多网站会检测到代理IP的使用,并采取措施将其封禁或封锁,因为代理IP容易被滥用,用于发起恶意攻击、进行大规模爬取等行为。网站为了保护自身安全和服务质量,会将代理IP列入黑名单,限制其访问网站内容或执行特定操作。
2.速度和稳定性: 代理IP可能会导致网络连接速度变慢或不稳定。这取决于代理服务器的负载情况、服务器位置与用户位置的距离,以及代理IP供应商的服务质量。使用速度较慢或不稳定的代理IP会影响用户体验,尤其是在需要大量数据传输或对实时性要求较高的情况下。
3.隐私和安全: 使用公共代理IP存在隐私和安全风险。一些免费的代理IP可能会记录用户的网络活动,甚至有可能被黑客攻击,导致用户的个人信息泄露或受到其他安全威胁。
4.合法性和可信度: 选择合法和可信的代理IP供应商至关重要。使用非法或不可信的代理IP服务可能会带来法律风险,并可能导致服务中断或不稳定性。
5.成本和效率: 购买高质量的代理IP服务通常需要一定的成本投入。而且,需要确保代理IP的使用是高效的,否则可能会浪费时间和资源。
解决这些挑战的方法包括选择信誉良好的代理IP供应商,定期检查和更新代理IP,遵守网站的使用规则和政策,加强网络安全措施,以及根据实际需求合理管理代理IP的使用。
二、获取AIGC前沿信息缺口 科技发展迅速,导致AIGC这一领域中存在的信息不足或缺乏前沿技术和研究的信息,包括对最新的人工智能生成内容技术、应用案例、道德和法律问题等方面了解不足。解决这个问题的方法包括积极跟踪最新研究、参与相关的学术和行业活动、与专业人士交流等。
1、最新AIGC前沿信息来源 (1)学术期刊和会议论文:在人工智能领域的学术期刊和会议上发表的论文是了解AIGC技术和研究进展的重要来源。例如,人工智能领域的顶级会议如NeurIPS、ICML、AAAI等经常涉及到AIGC相关的研究成果。
(2)专业网站和博客:许多专业网站和博客定期发布关于AIGC的最新进展、技术趋势和案例研究等内容。这些网站可能包括OpenAI的博客、DeepMind的博客、AI2的博客等。
(3)技术报告和白皮书:一些技术公司、研究机构或组织发布的技术报告和白皮书可能包含关于AIGC的详细信息,这些报告通常涵盖了最新的技术进展、应用案例和发展趋势等。
(4)社交媒体和论坛:在社交媒体平台上,如Twitter、Reddit等,以及专业论坛如GitHub、Stack Overflow等,人们经常分享关于AIGC的最新新闻、研究论文、项目案例等信息。
(5)行业报告和调研:一些专业机构和市场研究公司定期发布关于人工智能行业和AIGC市场的报告和调研,这些报告可能包含市场趋势、竞争格局、关键技术等方面的信息。
为了快速搜集数据,本文采用代理ip服务来帮助我们实现数据采集,并选取专业网站和博客作为获取最新AIGC前沿信息的数据来源,网页地址如下:
https://www.51cto.com/ai
https://www.51cto.com/
2、确定关键字 人工智能、AIGC、AI、大模型、多模态、ChatGPT
3、可能涉及到的字段 帖子类型、讨论的主题、用户兴趣、网址、关键词、评论、标签、内容、作者、标题、概括
三、使用代理ip抓取数据 1、选择代理ip服务 通过对市面上代理IP的封禁性、速度和稳定性、 隐私和安全、 合法性和可信度、 成本和效率进行比较,最终选择了呼声很高的BrightData的IP代理服务。
2、如何使用BrightData代理ip抓取数据 (1)注册登录 首先进入BrightData官网注册账号,需要填写姓名、邮箱、手机号即可注册完成
登录之后进入后台首页,有两个模块,一个是代理&爬虫基础设施,一个是网络数据收集和爬虫开发套件。
(2)代理IP服务 市面上的代理IP服务有很多类型,不同类型的代理服务适用于不同的使用场景和需求,用户可以根据自己的需要选择合适的代理IP服务类型。比如:
动态住宅代理: 这种代理IP是从普通家庭用户的网络中获取的,IP地址可能会随着时间和网络连接的变化而改变。
静态住宅代理: 与动态住宅代理相反,静态住宅代理的IP地址是固定不变的,通常由专门的提供商提供,这些IP地址通常属于真实的家庭网络,但被特定用户租用。
机房代理: 机房代理是指代理IP来自数据中心或云服务提供商的服务器,这些IP地址通常稳定可靠,带宽大,延迟低。
移动代理:指代理IP来自移动网络运营商的IP地址池。
数据中心代理:是指代理IP来自数据中心或云服务提供商的服务器。
这里选择代理&爬虫基础设施,可以根据自己需求,选择不同的代理服务,由下图可以看出BrightData代理ip服务包含了许多市面上常见的类型,并且还有提高抓取成功率的功率。
这里选择无线机房代理,它适合使用需求高的场景。
点击下面的确定按钮,则创建新的通道
然后我们选择“亮数据浏览器”,利用内置解锁功能和代理一体的爬虫浏览器,大规模轻易解锁网站,抓取数据。出现下面的页面,之后点击“添加”按钮。
接下来会生成主机、用户名、密码。我们可以用这些信息使用浏览器进行抓取。
(3)亮数据浏览器抓取数据 接下来到“Bright Data’s Scraping Solutions”(亮数据的抓取解决方案),选择“Scraping Browser”菜单下的“Configuration”,可以看到亮数据提供了三种语言(NodeJs、Python、C#)帮你抓取数据,真的太方便啦!
这里我们用NodeJS做一个示例,爬取“https://www.51cto.com/ai”网站人工智能的相关信息。
✊✊✊🌈大家好!本篇文章将较详细介绍一道考点为栈和KMP匹配的华为机试题目正则表达式切词。代码语言为:C++代码😇。
可以参考力扣题目和kmp算法博客:
394. 字符串解码(HOT100)
KMP算法详解及C++实现
🎡导航小助手🎡 394. 字符串解码🔒1、题目:☀️2、思路:🔑3、代码: 394. 字符串解码 🔒1、题目: 已知存在种字符串解析语法,其中的语法元素如下:
N:用于江配单个数字(0-9)
A:用于四配单个字母(a-z,A-Z)
n():用于表示一个分组,分组中至少有一个N语法元素或者A语法元素,n为个数值,表示匹配n次,1<=n<=200
输入给定的解析语法和字符串,要求从中找到第一个满足解析语法的字符串。
输入描述
输入两行数据,第一行是给定的解析语法,第二行是目标字符串。
输出描述
输出匹配的子字符串内容,如果没有匹配中任何字符串,输出!(英文感叹号)
🌲 示例 1🌲:
输入: 2(AN) BA3A3ABB 输出: A3A3 🌲 示例 2🌲:
输入: 2(A2(N)) A3322A33P20BB 输出: A33P20 ☀️2、思路: 首先需要将模式串展开,比如2(A2(N))需展开为ANNANN。
难点在于括号内嵌套括号,需要从内向外生成与拼接字符串,这与栈的先入后出特性对应。
定义num存放解码出来的倍数,st存放num和临时字符串的结果。遍历字符串s中每个字符c; 当 c为数字时,将字符转换为数值,赋给num;c为字母时,在res后面添加c;c 为(时,将倍数num和res入栈,然后分别置空置0(进入新的[,需要重新开始记录)c 为)时,将倍数num和res出栈,进行拼接。 之后利用KMP进行匹配。
KMP算法的核心思想:利用已匹配的信息来减少回溯的次数
首先next数组的第一个元素一定是0(因为只有一个字符的子串连前后缀都没有,更没有相同的前后缀了),那么我们得出一个前缀子串加上下一个字符后形成的前缀子串的最大前后缀长度的方法就是根据该前缀子串的最大前后缀长度来考虑,分为两种情况:
1、最简单的情况,当前前缀子串的下一个字符和该前缀子串的第n + 1位(n为当前前缀子串的最大前后缀子串的长度)相同,那么加上这个字符后形成的新的前缀子串的最大前后缀长度就是n + 1,例如(当前前缀子串为ABA(最大前后缀长度为1),下一个字符为B)
if(pattern[i] == pattern[j]) j++; 2、比较复杂,也是整个算法的难点,当前前缀子串的下一个字符和该前缀子串的第n + 1位(n为当前前缀子串的最大前后缀子串的长度)不相同,这时就要往回找,直到找到和新的字符能匹配的位置,而往回找的过程也是要遵循一个基本原则:不匹配字符之前的部分一定能保证匹配,而我们在之前找到的next部分数组恰好记录了前面所有子串的最大前后缀长度,那么我们就可以利用这点来进行往回找能与新字符匹配的字符而能遵循基本原则并且快速,举个例子:
while(j > 0 && pattern[i] != pattern[j]) { j = next[j - 1]; } 查询失配字符之前的前缀子串的最大前后缀长度(即失配字符的前一位对应的next数组的值)为n,然后将模式串的第n位匹配到失配字符之前的前缀子串的末位(在代码中的体现就是失配字符target[i]和第n+1个字符pattern[j]比对),翻译成代码如下:
个人主页: 深情秋刀鱼@-CSDN博客
数据结构专栏:数据结构与算法
无论多高大的树,那也是从小到大,由根到叶,一点点成长起来的。俗话说“十年树木。百年树人”,可一棵大树又何止是十年这样容易。 目录
一、树
1.树的结构
2.树的相关概念
3.树的实现
二、二叉树
1.二叉树的概念
2.特殊的二叉树
3.二叉树的结构及实现
一、树 1.树的结构 树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。把它叫做树是因 为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。 有一个特殊的结点,称为根结点,根结点没有前驱结点除根结点外,其余结点被分成M(M>0)个互不相交的集合T1、T2、……、Tm,其中每一个集合Ti(1<= i <= m)又是一棵结构与树类似的子树。每棵子树的根结点有且只有一个前驱,可以有0个或多个后继 因此,树是递归定义的。
在树形结构中,子树之间不能有任何的交集,否则就不是树形结构。
2.树的相关概念 结点的度:一个结点含有的子树的个数称为该结点的度; 如上图:A的为6叶结点或终端结点:度为0的结点称为叶结点; 如上图:B、C、H、I...等结点为叶结点非终端结点或分支结点:度不为0的结点; 如上图:D、E、F、G...等结点为分支结点双亲结点或父结点:若一个结点含有子结点,则这个结点称为其子结点的父结点; 如上图:A是B的父结点孩子结点或子结点:一个结点含有的子树的根结点称为该结点的子结点; 如上图:B是A的孩子结点兄弟结点:具有相同父结点的结点互称为兄弟结点; 如上图:B、C是兄弟结点树的度:一棵树中,最大的结点的度称为树的度; 如上图:树的度为6结点的层次:从根开始定义起,根为第1层,根的子结点为第2层,以此类推;树的高度或深度:树中结点的最大层次; 如上图:树的高度为4堂兄弟结点:双亲在同一层的结点互为堂兄弟;如上图:H、I互为兄弟结点结点的祖先:从根到该结点所经分支上的所有结点;如上图:A是所有结点的祖先子孙:以某结点为根的子树中任一结点都称为该结点的子孙。如上图:所有结点都是A的子孙森林:由m(m>0)棵互不相交的树的集合称为森林; 3.树的实现 树结构相对线性表就比较复杂了,要存储表示起来就比较麻烦了, 既然保存值域,也要保存结点和结点之间 的关系,实际中树有很多种表示方式如:双亲表示法,孩子表示法、孩子双亲表示法以及孩子兄弟表示法等。我们这里就简单的了解其中最常用的 孩子兄弟表示法。 typedef int DataType; struct Node { struct Node* firstChild1; // 第一个孩子结点 struct Node* pNextBrother; // 指向其下一个兄弟结点 DataType data; // 结点中的数据域 }; 二、二叉树 1.二叉树的概念 二叉树是一种特殊的树,从上图可以看出在二叉树中每个节点的度最大不超过2,而且左右子树的顺序不能颠倒,所以二叉树是有序的。
二叉树的特殊形式 2.特殊的二叉树 1. 满二叉树:一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。也就是说,如果一个二叉树的层数为K,且结点总数是2的k次方-1,则它就是满二叉树。 2. 完全二叉树:完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引出来的。对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树。 要注意的是满二叉树是一种特殊的完全二叉树。 完全二叉树就是这样一种特殊的非满二叉树:除了最后一层外其他每一层都是填满的,并且最后一层的节点都尽可能地靠左排列。 3.
男儿不展风云志,空负天生八尺躯。——《警世通言·卷四十》 🌈个人主页:是店小二呀
🌈C语言笔记专栏:C语言笔记
🌈C++笔记专栏: C++笔记
🌈喜欢的诗句:无人扶我青云志 我自踏雪至山巅
上篇回顾:上篇我们通过数组名为切入口引出数组与指针间的关系,本篇将介绍不同类型的指针变量在不同场景中的使用 文章目录 一、字符指针变量二、数组指针变量(指针数组,这里需要注意偏正)2.1 数组指针的初始化2.2 二维数组传参的本质 三、函数指针变量3.1 函数指针变量初始化 四、函数指针数组五、转移表六、typedef 关键字 一、字符指针变量 对于字符和字符串,C语言统一使用char类型来表达式。对此字符指针变量有两种表示方法:
第一种: char ch='a'; char *p=&ch;第二种: const char *pstr="Hellow world"; 问题:关于const char *pstr="Hellow world"是将整个字符串放到字符指针里面了吗?
解释:本质是字符串"Hellow world"首字符(H)的地址放到字符指针变量pstr中.
【面试题:剑指offer】:
int main() { char str1[] = "hellow world"; char str2[] = "hellow world"; const char *str3 = "hellow world"; const char *str4 = "hellow world"; if(str1 ==str2) printf("str1 and str2 are same\n"); else printf("str1 and str2 are not same\n"
目录
一.事务简介:
二.事务操作:
未控制事务:
事务的控制方法一:
事务的控制方法二:
三:事务的四大特性:
四.并发事务问题:
五.事务的隔离级别:
一.事务简介: 事务 是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系 统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败。
比如,银行转账的操作就是一个典型的事务问题,举个例子:张三给李四转账1000块钱,张三银行账户的钱减少1000,而李四银行账户的钱要增加 1000。 这一组操作就必须在一个事务的范围内,要么都成功,要么都失败。
正常情况: 转账这个操作, 需要分为以下这么三步来完成 , 三步完成之后, 张三减少1000, 而李四 增加1000, 转账成功 :
异常情况: 转账这个操作, 也是分为以下这么三步来完成 , 在执行第三步是报错了, 这样就导致张 三减少1000块钱, 而李四的金额没变, 这样就造成了数据的不一致, 就出现问题了:
为了解决上述的问题,就需要通过数据的事务来完成,我们只需要在业务逻辑执行之前开启事务,执行 完毕后提交事务。如果执行过程中报错,则回滚事务,把数据恢复到事务开始之前的状态:
注意: 默认MySQL的事务是自动提交的,也就是说,当执行完一条DML语句时,MySQL会立即隐式的提交事务。
由于MySQL的事务自动提交的这种特性,就要求我们将设置修改为手动事务,以此来发现问题并且解决问题。
二.事务操作: 未控制事务: 数据准备(这里我们根据上面的例子来说明问题): # 数据准备 drop table if exists account; create table account( id int primary key auto_increment comment 'ID', name varchar(10) comment'年龄', money double(10,2) comment '余额' )comment '账户表'; insert into account(name,money) values('张三',2000),('李四',2000); 1).
🔥引言
本篇将深度解析:动态内存管理的机制。为了更加灵活分配内存中的空间,库中为了我们提供了一些的函数,去动态开辟和释放堆上的空间。
🌈个人主页:是店小二呀
🌈C语言笔记专栏:C语言笔记
🌈C++笔记专栏: C++笔记
🌈喜欢的诗句:无人扶我青云志 我自踏雪至山巅
文章目录 【前文】【正文】一、动态内存开辟函数1.1 malloc1.2 calloc1.3 malloc和calloc区别1.4 realloc(动态内存扩容)1.4.1 关于realloc扩展空间的两种情况: 二、free(释放动态开辟内存)三、动态内存的常见错误四、柔性数组(flexible array)4.1 柔性数组的特点4.2 柔性数组的使用 五、C/C++中程序内存区域规划 【前文】 目前我们掌握申请内存的方式有两种: int a=0;//直接开辟空间 int arr[10]={0};//连续开辟空间 上面两种开辟空间的方式存在一些问题:
栈空间开辟的空间大小是固定的
数组在声明时,必须指定数组的长度(一定确定大小不能被调整)
以上不能够灵活地处理内存问题,有时候是需要的空间大小在程序运行时才能知道,那么数组在编译时开辟空间的方式就不能得到满足。
对此,为了更灵活地使用空间,C语言标准库提供了程序员在堆上申请和释放空间的函数
【正文】 C语言标准库提供申请和释放动态内存空间的库函数,声明在stdlib.h头文件中。
一、动态内存开辟函数 【温馨提示】:
以下三种动态内存开辟函数,都有可能会出现开辟失败的情况,对此返回值为空,通过判断指针是否为空,做出及时的处理。在OJ需要开辟空间时,一般不需要判断,一般不会开辟失败。
1.1 malloc #include <stdio.h> #include <stdlib.h> int main() { int *p=(int *)malloc(10*sizeof(int)) if(p==NULL) { perror("malloc fail!!!") return 1; } free(p) p=NULL; return 0; } 【说明】:
向内存申请空间不完成初始化,返回指向这块空间的大小malloc是void*类型,当我们申请空间时候,需要知道申请空间交给什么类型去维护如果参数size为0,malloc可能会报错(取决于编译器)同时申请空间有时候不一定会成功。如果失败的话,将会返回一个空指针,比如申请的空间太大,就会申请失败,这一点使用的时候要去注意。 1.2 calloc #include <stdio.h> #include <stdlib.h> int main() { int *p=(int *)calloc(10,sizeof(int)) if(p==NULL) { perror("
在现代的Web应用程序开发中,跨域资源共享(Cross-Origin Resource Sharing, CORS)问题是开发者经常遇到的一个挑战。特别是当前端和后端服务部署在不同的域名或端口时,CORS问题就会显得尤为突出。在这篇博客中,我们将深入探讨如何在 .NET WebService 中解决CORS问题,帮助开发者顺利实现跨域请求。
一、CORS问题描述 在Web应用中,浏览器安全机制通常会阻止来自不同域的请求,这被称为“同源策略”。同源策略允许同一来源(协议、主机和端口相同)的资源相互访问,但会阻止不同来源的资源访问。这种机制虽然提高了安全性,但在实际开发中,前端和后端通常会部署在不同的服务器上,这就引发了CORS问题。
举个例子,当你试图从 http://frontend.com 发送一个请求到 http://api.backend.com 时,浏览器会拦截这个请求并抛出一个CORS错误:
Access to XMLHttpRequest at 'http://api.backend.com/resource' from origin 'http://frontend.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. 对于 .NET WebService ,如果前端应用尝试从另一个域名访问服务,而服务端没有适当的CORS策略,那么浏览器会阻止这些请求并显示该跨域错误。
二、CORS问题代码示例 为了更好地理解CORS问题及其解决方案,让我们先创建一个简单的前后端交互的.NET WebService示例。
1. 后端WebService接口代码 首先,创建一个新的 .NET Framework 项目。你可以使用 Visual Studio 或者命令行工具(如 dotnet CLI )来创建项目。在项目中,我们定义一个 .asmx 文件,并在 .asmx.cs 文件里创建一个接口。
接口代码如下:
using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Data; using System.
🚀传送门 🚀文章引言🔒技术层面📕作战结构🌈替代决策选项🎬选项 1:超级战争(Hyperwar)🌠选项 2:超越OODA🌂选项 3:阻止其他人的决策 ⭐结论 🚀文章引言 空战既涉及技术,又受技术影响。所使用的技术限制了空军可能采取的行动,既授权又限制了部队的使用选择。鉴于此,新兴主要技术总是会吸引人们的极大兴趣,而今天的焦点是人工智能(AI)。
本文只讨论AI在决策中的作用,特别是在空战中的作用。本文首先讨论了这项技术,然后指出了作战结构,最后考虑了人工智能和机器学习辅助空战决策的三种替代方法。
🔒技术层面 现代人工智能已经发展到满足商业领域,尤其是消费者的需求。一个关键的进步是低成本图形处理单元 (GPU) 变得容易获取,主要是为了满足视频游戏的需求。凭借其大规模的并行处理,GPU 可以轻松运行机器学习软件。机器学习是一个较老的概念,但它需要结合GPU和对 "大数据 "库的访问,以使其在大规模的情况下变得实用和可负担。
在机器学习中,计算机算法,而不是外部人类计算机程序员,创建了人工智能用来解决问题的指令序列和规则。一般来说,用于训练算法的数据越多,设计的规则和指令就越好。鉴于此,具有机器学习功能的 AI 可能会在“工作中”自学,随着它不断获得更多经验,在某项任务中逐渐变得更好。
在许多情况下,这些数据来自一个由互连设备组成的大规模网络,这些设备从现场收集信息,然后通过无线“云”将其传输到远程人工智能计算机进行处理。在军事领域,战场物联网 (IoBT) 以固定和移动设备为特色,包括能够成群协作的无人机。这种 IoBT 网络允许遥感和控制,但会产生大量数据。解决此问题的一种方法是将网络连接到可以实时评估数据的边缘设备,将最重要的信息转发到云中并删除其余信息,从而节省存储和带宽。
现在大多数边缘计算都是使用人工智能芯片完成的。它们体积小、相对便宜、耗电少、热量少,因此可以很容易地集成到智能手机等手持设备和工业机器人等非消费设备中。即便如此,在许多应用程序中,人工智能以混合方式使用:一部分在设备上,一部分在远程融合中心,通过云访问。
📕作战结构 一些与未来空战相关的重要作战概念正在出现。作战正在从联合转变为现在的多域,即跨越陆地、海洋、空中、网络和空间。一个名为“融合”的概念的意图是,友军应该能够在任何领域内攻击敌方单位。例如,陆军现在将能够在海上与舰船交战,空军将能够在有争议的环境中同时攻击空间资产和无处不在的网络。
这种作战概念摒弃了传统的单域线性杀伤链,转而采用利用替代或多路径的多域杀伤链。新兴的“马赛克”结构设想跨大型 IoBT 领域的数据流创建一个杀伤链网络,其中实现任务的最佳路径被确定并近乎实时地使用。然后,IoBT 领域的使用是流动的并且不断变化,而不是像旧的杀伤链模型所暗示的那样是固定的数据流。结果是,马赛克概念提供了冗余节点和多个杀伤路径的高度弹性网络。这种跨领域思维现在正在进一步演变为“扩展机动”的概念。
在重大冲突期间,实现这些联锁作战概念以对抗同级对手的复杂性是显而易见的。为了使涉及收敛、镶嵌和扩展机动作战的多领域作战切实可行,需要使用带有机器学习的人工智能自动化系统。
在中短期内,人工智能对涉及此类复杂结构的决策的主要吸引力在于其能够快速识别模式并检测隐藏在 IoBT 收集的大型数据库中的任务。这样做的主要结果是,人工智能将更容易检测、定位和识别整个战场上的物体。隐藏将变得越来越困难,瞄准变得更加容易。另一方面,人工智能并不完美。众所周知,它存在容易被愚弄、脆弱、无法将在一项任务中获得的知识转移到另一项任务以及依赖数据的问题 。
AI 作战主要效用就变成了“发现和愚弄”。具有机器学习功能的 AI 在查找隐藏在高度杂乱背景中的物品方面非常出色,但是由于能够被愚弄,因此缺乏鲁棒性。
“发现”的出发点是将许多低成本的 IoBT 传感器放置在敌对势力可能经过的最佳陆地、海洋、空中、太空和网络位置。未来的战场空间可能包含数百甚至数千个中小型固定和移动人工智能监视和侦察系统,在所有领域运行。同时,可能有同等数量的支持人工智能的干扰和欺骗系统协同作用,试图在对手的脑海中制造一种虚假的、故意误导的战场印象。
🌈替代决策选项 人工智能和机器学习决策自选项将受到技术和所需作战概念的需求影响。这里讨论的替代方案是使用技术能够更快地对对手的行动做出反应,通过技术驱动先发制人抢在对手前面,或者显著减慢对手的决策速度。
🎬选项 1:超级战争(Hyperwar) 自AI 以机器速度提供战争愿景。John Allen 和 Amir Husain 认为 AI 可以实现超级战争,其中:“战争范围战术端的战斗速度将大大加快,将决策-行动周期缩短到几分之一秒,导致具有更多自主决策-行动并发性的一方获得决定性的优势。”
在空战决策的情况下,著名的观察-定向-决策-行动(OODA)模型提供了一个有用的框架来理解这个想法。该模型的设计师约翰博伊德主张更快地做出决策,以便进入对手的决策周期。这会扰乱敌方指挥官的思维,造成危险的局面,并阻碍他们适应现在瞬息万变的环境(Fadok 1997, p.364-368)。在“观察”功能中,人工智能将用于大多数 IoBT 设备的边缘计算,然后再次用于中央指挥中心,将传入的 IoBT 数据融合成一张综合图景。对于“定向”而言,人工智能将在战斗管理系统中发挥重要作用(Westwood 2020, 22)。人工智能不仅可以生成全面的近实时空中画面,还可以预测敌方空中机动路线。
下一个 AI 层处理“决策”以了解友方防空部队的可用性,将传递给人类指挥官以批准要交战的接近敌方空中目标的优先列表、采用的多域攻击的最佳类型、所涉及的时间以及任何消除冲突的考虑。人类将在必要时保持在环或在环控制,不仅是出于武装冲突法的原因,而且因为人工智能可能会犯错误,需要在做出任何不可逆转的决定之前进行检查。经人工批准后,“行动”人工智能层将自动向每个目标分配首选武器,并自动传递必要的目标数据,确保与友军解除冲突,确认目标何时被交战并可能下令重新补给武器。
🌠选项 2:超越OODA OODA 人工智能技术正在迅速扩散,这使得友方和敌方部队都可能同样具备超级战争的能力。OODA 决策模型可能需要改变。据此,在事件发生之前不能进行观察;该模型天生就会在时间上向后看。人工智能可以带来微妙的转变。将合适的环境数字模型和敌对力量与来自 IoBT 的高质量“发现”数据相结合,人工智能可以预测对手可能采取的未来行动范围,并据此预测友军可能采取最好的行动来应对这些。
你眼中的IT行业现状与未来趋势 文章目录 你眼中的IT行业现状与未来趋势强烈推荐引言优化技巧1. 数据库优化2. 代码优化3. 缓存机制4. 负载均衡5. 网络优化6. 日志和监控7. 服务器优化8. API设计优化9. 安全性 总结强烈推荐专栏集锦写在最后 强烈推荐 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站:人工智能
引言 在现代软件开发中,后端接口的性能优化是确保系统高效运行的关键因素之一。
随着用户数量的增加和数据量的增长,未优化的后端接口会导致响应时间变长,用户体验下降,甚至引发系统崩溃。
本文将探讨一些常见且有效的后端接口性能优化方法,并通过具体的Java代码实例来展示如何实施这些优化策略。
无论是数据库优化、代码优化、缓存机制、负载均衡、网络优化,还是日志监控和服务器优化,每一个环节的改善都能显著提升系统性能。
优化技巧 1. 数据库优化 索引:确保数据库表中的关键字段有适当的索引。
示例:在用户表(users)中,给email字段添加索引:
CREATE INDEX idx_email ON users(email); 查询优化:分析和优化SQL查询,避免全表扫描,使用连接(JOIN)时注意避免笛卡尔积。
示例:避免全表扫描,通过索引字段进行查询:
SELECT * FROM orders WHERE user_id = 12345; 缓存:使用缓存技术(如Redis、Memcached)来减少数据库查询次数。
示例:使用Redis缓存用户信息:
import redis.clients.jedis.Jedis; public class CacheExample { private Jedis jedis = new Jedis("localhost"); public String getUserInfo(int userId) { String key = "user:" + userId; String userInfo = jedis.get(key); if (userInfo == null) { userInfo = getUserInfoFromDb(userId); jedis.
文章目录 前言
背景
分布式仿真
使用方式
分析和应用
总结
参考资料
前言 见《【研发日记】Matlab/Simulink技能解锁(三)——在Stateflow编辑窗口Debug》
见《【研发日记】Matlab/Simulink技能解锁(四)——在Simulink Debugger窗口调试》
见《【研发日记】Matlab/Simulink技能解锁(五)——七个Simulink布线技巧》
见《【研发日记】Matlab/Simulink技能解锁(六)——六种Simulink模型架构》
见《【研发日记】Matlab/Simulink技能解锁(七)——两种复数移相算法》
背景 使用Simulink开发嵌入式软件,Contrl Model在进行仿真运行时,最常规的方法是搭建一个被控Plane Model,来配合为嵌入式软件开发的Contrl Model,在Simulink编辑窗口就就能仿真运行。这种仿真方式是一种纯虚拟的仿真,Contrl Model和Plane Model运行的平台是工程师的Computer。其中最关键的工作是搭建Plane Model,Plane Model的质量直接影响Contrl Model仿真的效果。
一个高质量Plane Model的搭建往往对需要投入非常专业的技术人员,并且耗费大量的工作时间。即便如此,Contrl Model在Computer上运行和在MCU上运行仍然存在一些差别,Plane Model在Computer上运行和在真实世界里的表现也存在差异。这种大投入和不完美因素,很多开发团队经常是无法接受的。在这种纯虚拟仿真的基础上跨出一步后,诞生了分布式仿真。其在MBD工作流中的地位如下图所示:
分布式仿真 分布式仿真,也称半实物仿真,Mathworks官方的说法是Connected I/O Simulation,顾名思义就是仿真模型的运行不全在Computer上。Contrl Model被分成两部分,纯算法的Model仍在Computer上运行,I/O之类的外设在外部MCU(I/O Server)上执行,Computer和外部MCU之间通过Serial协议进行连接。当仿真运行时,Model Block向IO Server发送命令和请求数据。Plane Model用真实世界中的物理实体替代,并受IO Server控制,整体框架示例如下:
使用方式 第一步,硬件连接
将USB串口线的两头,分别连接在MCU板子和Computer之间,确保Computer的设备管理器中能出现对应的COM资源。
Tips:MCU板子上的一个SCI module将会被占用,所以不能跟其他应用冲突。
第二步,配置Serial协议
打开Simulink Configuration Parameters窗口,在Hardware Implementation一栏的Target hardware resources中找到Connected I/O分组,配置串口通信资源,示例如下:
Tips:上述分布式仿真,依赖于Simulink和MCU之间的Serial协议和传输接口,以及MCU中的IO Server引擎,所以需要Simulink和MCU两边厂家的共同支持,不是每款MCU都支持这项功能。
第三步,连接I/O
在Simulink的Hardware工具页中, 点击Run on Board下拉按钮, 然后点击Connected I/O (inputs/outputs mode)按钮,示例如下:
第四步,加载Contrl Model
Contrl Model按照正常的方式搭建,不用做特殊修改,示例如下:
第五步,运行仿真
在Simulink的Hardware工具页中,点击Run with I/O按钮,即可利用Dashboard、Dispiay、Data lable和Data Inspect等工具查看信号,示例如下:
🎁个人主页:我们的五年
🔍系列专栏:初阶数据结构刷题
🎉欢迎大家点赞👍评论📝收藏⭐文章
🚗 1.问题描述: 题目中说了只能使用两个栈实现队列,并且只能使用基本的栈操作。比如:在栈顶进行入栈操作,在栈顶进行出栈,取栈顶元素,还有判空这些基本的栈操作函数。然后使用这些函数实现队列的基本操作,队列的特点就是在队尾插入数据,在队头删除数据,在对头取数据。
题中说使用两个栈实现,也给了我们提示。
🚗 2.问题分析: 假如先在一个栈中插入三元素1.2.3。
当使用StackPush函数在PushST进行三次插入以后,就变成了上面的情形,但是如果我们要进行队列取队头的数据,进行队列删除队头的数据,我们就要先把上面的3和2拿走。从而我们就想到了把左边栈里面的元素的放到右边去。
进行上面的操作以后,我们就调用栈的取栈顶的函数就可以拿到元素1,也可以进行取删除元素1,就可以达到和队列一样的性质:先进先出。
插入数据的时候,我们还是在PushST中插入数据,加入先插入4,5.
如果要进行删除操作,取元素操作也是可以直接在PopST栈中直接取。也是满足队列的要求的。但是当我们把PopST的元素都取完以后,我们就要再一次把PushST栈里面的元素导到PopST栈里面。
按照上面的步骤就可以实现队列的操作。
🚗 3.代码层面进行解析: 栈的函数接口 先给出栈的接口:
typedef int SLDataType;
typedef struct Stack{
SLDataType* a;
int top;
int capacity;
}Stack;
//对栈进行初始化
void StackInit(Stack* ptr);
//对栈进行销毁
void StackDestroy(Stack* ptr);
//在栈顶插入元素
void StackPush(Stack* ptr, SLDataType x);
//获取栈顶元素
SLDataType StackTop(Stack* ptr);
//对栈进行判断,如果为空,返回true,否则返回false
bool StackEmpty(Stack* ptr);
//销毁栈的栈顶元素
void StackPop(Stack* ptr);
用栈的函数实现队列 先定义我自己结构体的类型:
根据上面分析也是用两个栈实现队列,也就是说我的队列类型中保护了两个栈,并且我把这两个队列命名为PushST和PopST
typedef struct { Stack PushST; //把元素新的元素放在这个栈,也就是在这个栈里面实现插入操作 Stack PopST; //在这个栈中取数据,删除数据 } MyQueue; 创建队列,在堆区上申请一块空间,并且对队列里面的栈进行初始化
目录 一、数组的基本概念1. 为什么要使用数组2. 什么是数组3. 数组的创建及初始化3.1 数组的创建3.2 数组的初始化 4. 数组的使用4.1 数组中元素的访问4.2 遍历数组 二、数组是引用类型1. 初始JVM的内存分布2. 基本类型变量与引用类型变量的区别3. 认识 null 三、数组练习1. 数组转字符串2. 数组拷贝3. 查找数组中指定元素(二分查找)4. 数组排序(冒泡排序) 四、二维数组 一、数组的基本概念 1. 为什么要使用数组 假设现在要存5个学生的javaSE考试成绩,并对其进行输出,按照之前掌握的知识点,我们会写出如下代码:
public class TestStudent{ public static void main(String[] args){ int score1 = 70; int score2 = 80; int score3 = 85; int score4 = 60; int score5 = 90; System.out.println(score1); System.out.println(score2); System.out.println(score3); System.out.println(score4); System.out.println(score5); } } 上述代码没有任何问题,但不好的是:如果有20名同学成绩呢,需要创建20个变量吗?有100个学生的成绩那不得要创建100个变量。仔细观察这些学生成绩发现:所有成绩的类型都是相同的,那Java中存在可以存储相同类型多个数据的类型吗?这就是本文章要讲的数组。
2. 什么是数组 数组:可以看成是相同类型元素的一个集合。在内存中是一段连续的空间。比如现实中的车库:
在java中,包含6个整形类型元素的数组,就相当于上图中连在一起的6个车位,从上图中可以看到:
数组中存放的元素其类型相同。数组的空间是连在一起的。每个空间有自己的编号,起始位置的编号为0,即数组的下标。 那在程序中如何创建数组呢?
3. 数组的创建及初始化 3.
前言 目录
前言
栈的概念
栈的实现
1.实现方式选择
2.所需实现的函数列举(头文件)
3.实现栈的函数
初始化和销毁
入栈和出栈
获取栈顶元素、元素个数、栈判空
栈的OJ练习题讲解:
完整数据结构栈的代码:
后记
欢迎各位小伙伴来到小鸥的博客!让我们继续一起学习成长吧!
本篇专栏:数据结构_海盗猫鸥的博客-CSDN博客
欢迎大家到访,有任何意见想法店都可以评论或者私聊喔!
本期我们将继续数据结构的学习,有请本次“嘉宾”——栈!
栈的概念 栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端 称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。出栈:栈的删除操作叫做出栈。出数据也在栈顶。 入栈出栈图示:
栈的实现 1.实现方式选择 栈可以基于数组或者链表来实现,一般而言用用数组来实现更优,因为数组在尾部插入数据时的代价小一些
如果使用单链表结构来实现栈的话,就要将头节点作为栈顶,因为单链表的头插和头删的消耗更小,尾删和尾插都需要遍历链表才能进行。双链表则不需要在意这点。
(即便使用双链表来实现栈,节点至少也需要三个成员,耗费依然大于数组)
所以我们本篇采取使用动态顺序表的方式来实现栈。
2.所需实现的函数列举(头文件) 类比之前我们已经学习过的顺序表和链表
我们可以先得出一些需要的函数(接口):
入栈(插入数据)、出栈(删除数据)、初始化、销毁;
此外栈还需要:获取栈顶元素的函数、有效元素个数的函数、检测栈是否为空的函数。
所以我们可以先在头文件中声明所有的函数:
Stack.h
#pragma once #include <stdio.h> #include <stdlib.h> #include <assert.h> #include <stdbool.h> typedef int STDATATYPE; typedef struct Stakc { STDATATYPE* a; int top; int capacity; }ST; //初始化销毁 void STInit(ST* pst); void STDestroy(ST* pst); //入栈 出栈 void STPush(ST* pst, STDATATYPE x); void STPop(ST* pst); //获取栈顶元素 STDATATYPE STTop(ST* pst); //获取栈中的有效元素个数 int STSize(ST* pst); //检测是否为空 bool STEmpty(ST* pst); 注意:
在Python这样一门多用途的编程语言中,字符串是一种不可或缺的标准数据类型。无论是用于文本处理、数据分析还是 Web 开发,字符串在Python中扮演着重要角色。在本文中,我们将深入探讨Python中字符串的特性、操作以及一些实用技巧。
文章目录 什么是字符串字符串的特性常用字符串操作实例演示推荐书籍:《Python从入门到精通》内容简介获取方式 什么是字符串 在Python中,字符串是由单个字符组成的序列,可以是字母、数字、符号或空格。字符串可以用单引号 (') 或双引号 (") 括起来,例如:“Hello, World!”就是一个简单的字符串示例
字符串的特性 不可变性:字符串是不可变的,一旦创建就不能被修改。对字符串的任何操作都会创建一个新的字符串对象。
索引和切片:可以使用索引来访问字符串中的单个字符,也可以使用切片来获取子字符串。
字符串拼接:通过加号 (+) 可以将两个字符串连接起来。
字符串格式化:使用.format()方法或f字符串(f-strings)可以方便地插入变量值到字符串中。
常用字符串操作 字符串长度:可以使用len()函数获取字符串的长度。
字符串方法:Python提供了丰富的字符串方法,如upper()(将字符串转为大写)、lower()(将字符串转为小写)、strip()(去除字符串两端的空格)等。
字符串查找和替换:通过find()、index()、replace()等方法可以查找指定子串或替换字符串中的部分内容。
字符串拆分和连接:使用split()方法可以根据指定的分隔符将字符串拆分为列表,而join()方法可以将列表中的字符串连接起来。
实例演示 让我们来看一个简单的实例来展示字符串操作:
# 字符串长度len() message = "Hello, Python!" length = len(message) print(f"The length of the message is: {length}") # 字符串转为大写upper() upper_message = message.upper() print(f"Uppercase message: {upper_message}") # 字符串转为小写lower() lower_message = message.lower() print(f"Lowercase message: {lower_message}") # 去除字符串两端的空格strip() message_with_spaces = " Python Programming " stripped_message = message_with_spaces.strip() print(f"
1、概述 在Android中,config.xml文件用于配置各种系统设置和资源。对于屏幕亮度的配置,config.xml并不是直接用于设置屏幕亮度的地方,但它可以包含默认的系统设置和一些相关的参数。以下是如何在config.xml中配置一些与屏幕亮度相关的设置的详细步骤。
2、找到或创建config.xml 在Android系统源码中,config.xml通常位于以下路径:
frameworks/base/core/res/res/values/config.xml
如果项目中没有config.xml文件,可以在相应的路径下创建一个。
3、配置屏幕亮度相关参数 在config.xml中,可以定义与屏幕亮度相关的参数,例如默认亮度值、自动亮度调节参数等。以下是一个示例配置:
<?xml version="1.0" encoding="utf-8"?> <!-- /* ** Copyright 2009, The Android Open Source Project ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 ** ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "
目录
一、系统概述
二、开发环境
三、系统功能介绍
四、功能描述 五、工作流程 MES系统的应用场景广泛:
一、系统概述 MES系统,全称Manufacturing Execution System,中文常被称为“制造执行系统”。它是企业信息化管理系统的重要组成部分,介于计划层与控制层之间,主要起到承上启下的作用。MES系统从底层数据采集开始,涵盖了过程监测、在线管理以及成本相关数据管理,构成了一个完整的生产信息化体系。
二、开发环境 ❀技术架构:springboot + vue-element-plus-admin
❉开发语言:Java
❉开发工具:idea
❉前端框架:vue.js
❉后端框架:springboot
❉数 据 库:mysql
❉移 动 端:uniapp
三、系统功能介绍 (一)、基础设置
包括计量单位管理
(二)、产品管理
包括盘号、颜色、规格、分类、产品
(三)、设备管理
包括设备类型管理、设备状态管理、设备台账管理
(四)、车间管理
包括车间设置、工作站管理
(五)、工艺管理
包括工序设置、工艺流程
(六)、排班管理
包括班组类型、班组设置、排班计划、排班日历
(七)、生产管理
包括生产订单、生产排产、生产任务、生产报工、报工设备、工时管理、工时类型、临时工时
(八)、检验标准
包括检验器具、工序检验标准
(九)、工序检验
(十)、客户管理
(十一)、供应商管理
(十二)、销售订单
包括报价单-型号、客户报价单、物料价格、销售订单
(十三)、库存管理
包括生产领料、销售单统计、成品入库、半成品入库、销售出库
(十四)、采购订单
(十五)、采购入库
(十六)、客户退货
(十七)、采购退货
(十八)、仓库管理
(十九)、系统管理
包括租户管理、用户管理、角色管理、部门管理、岗位管理、字典管理
四、功能描述 用户管理 :用户是系统操作者,该功能主要完成系统用户配置 在线用户 :当前系统中活跃用户状态监控,支持手动踢下线 角色管理: 角色菜单权限分配、设置角色按机构进行数据范围权限划分 菜单管理:配置系统菜单、操作权限、按钮权限标识等,本地缓存提供性能 部门管理 :配置系统组织机构(公司、部门、小组),树结构展现支持数据权限 岗位管理: 配置系统用户所属担任职务 租户管理: 配置系统租户,支持 SaaS 场景下的多租户功能 租户套餐: 配置租户套餐,自定每个租户的菜单、操作、按钮的权限 字典管理: 对系统中经常使用的一些较为固定的数据进行维护 短信管理: 短信渠道、短息模板、短信日志,对接阿里云、腾讯云等主流短信平台 邮件管理: 邮箱账号、邮件模版、邮件发送日志,支持所有邮件平台 站内信息 :系统内的消息通知,提供站内信模版、站内信消息 操作日志 :系统正常操作日志记录和查询,集成 Swagger 生成日志内容 登录日志 :系统登录日志记录查询,包含登录异常 错误码管理: 系统所有错误码的管理,可在线修改错误提示,无需重启服务 通知公告 :系统通知公告信息发布维护 敏感词 :配置系统敏感词,支持标签分组 五、工作流程 流程模型: 配置工作流的流程模型,支持文件导入与在线设计流程图,提供 7 种任务分配规则 流程表单: 拖动表单元素生成相应的工作流表单,覆盖 Element UI 所有的表单组件 用户分组: 自定义用户分组,可用于工作流的审批分组 我的流程: 查看我发起的工作流程,支持新建、取消流程等操作,高亮流程图、审批时间线 待办任务: 查看自己【未】审批的工作任务,支持通过、不通过、转发、委派、退回等操作 已办任务: 查看自己【已】审批的工作任务
目录
关于内置 TreeView
两者的区别
准备数据源
范例运行环境
一些实用方法
获取数据进行呈现
获取所有的结点 小结
关于内置 TreeView 数据感应也即数据捆绑,是一种动态的,Web控件与数据源之间的交互,在我的前期文章《C# Web控件与数据感应之 TreeView 类》,对于 Microsoft.Web.UI.WebControls.TreeView 已做了详细介绍,本文则继续介绍 C# 实现 System.Web.UI.WebControls.TreeView 的一些实用方法。
两者的区别 Microsoft.Web.UI.WebControls.TreeView 属于微软的过去时控件,现在则升级为内置的 System.Web.UI.WebControls 集合,System.Web.UI.WebControls.TreeView 也已正式成为内置控件,并且属性方法均有一些变化。
准备数据源 我们在 MS SQL Server 创建 pub_area(区域表),其结构如下表:
序号字段名类型说明1acodenvarchar(10)区域代码,唯一键2anamenvarchar(50)区域名称3parent_acodenvarchar(10)父项所属区域代码 执行如下 创建表的 SQL 语句:
SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[pub_area]( [acode] [nvarchar](10) NOT NULL, [aname] [nvarchar](50) NOT NULL, [parent_acode] [nvarchar](10) NULL, CONSTRAINT [IX_pub_area] UNIQUE NONCLUSTERED ( [acode] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO 执行如下SQL语句,创建一些数据:
目录
关于 TreeView
一些区别
准备数据源
范例运行环境
一些实用方法
获取数据进行呈现
根据ID设置节点
获取所有结点的索引 小结
关于 TreeView 数据感应也即数据捆绑,是一种动态的,Web控件与数据源之间的交互,本文将继续介绍与数据库提取数据并捆绑到 TreeView 类控件。在我的前期文章《C# DataSet结合FlyTreeView显示树状模型数据》,对于 FlyTreeView 已做过介绍,本文则介绍C# 实现 Microsoft.Web.UI.WebControls.TreeView 和 System.Web.UI.WebControls.TreeView 的一些实用方法。
一些区别 Microsoft.Web.UI.WebControls.TreeView 、 System.Web.UI.WebControls.TreeView 和NineRays.WebControls.FlyTreeView 在使用和呈现上大同小异,关键的区别在于 FlyTreeView不是免费的,即使使用破解版本可能也存在部分问题,这个在使用中需要注意。而Microsoft.Web.UI.WebControls.TreeView 和 System.Web.UI.WebControls.TreeView 是微软提供的内置控件,前者是 TreeView 的早期版本,现在基本以 System.Web.UI.WebControls.TreeView 为准。本文将以 Microsoft.Web.UI.WebControls.TreeView 为举例。
准备数据源 我们在 MS SQL Server 创建 pub_area(区域表),其结构如下表:
序号字段名类型说明1acodenvarchar(10)区域代码,唯一键2anamenvarchar(50)区域名称3parent_acodenvarchar(10)父项所属区域代码 执行如下 创建表的 SQL 语句:
SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[pub_area]( [acode] [nvarchar](10) NOT NULL, [aname] [nvarchar](50) NOT NULL, [parent_acode] [nvarchar](10) NULL, CONSTRAINT [IX_pub_area] UNIQUE NONCLUSTERED ( [acode] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO 执行如下SQL语句,创建一些数据:
文章目录 接口(interface)基本介绍接口的定义方式接口继承空接口自定义类型序列排序接口与继承 多态基本介绍多态的实现 类型断言基本介绍类型断言的方式参数类型识别接口断言 接口(interface) 基本介绍 基本介绍
在Go中,接口(interface)是一种用于定义方法集合的抽象类型,接口中定义了一组方法的签名,而不包含方法的实现细节,其他类型可以通过实现接口中定义的方法来满足接口的要求。接口的实现是隐式的,类型不需要显式声明它实现了某个接口,只要类型提供了接口中定义的所有方法,就被视为实现了该接口。接口提供了一种灵活的方式来定义和使用抽象的行为,通过接口可以实现与类型无关的编程,提高代码的灵活性和可扩展性。 接口的定义方式 接口的定义方式
Go中接口的定义方式如下:
相关说明:
接口中定义的都是方法的签名,没有方法体,也不能有任何变量。接口本身不能创建实例,但可以指向一个实现了该接口的自定义类型的变量。一个自定义类型要实现某个接口,就必须将接口中定义的所有方法都实现。只要是自定义类型就可以实现接口,而不仅仅是结构体类型 例如,下面的代码中定义了一个Usb接口,并让自定义类型Phone和Camera实现了该接口。如下:
package main import "fmt" // 定义接口 type Usb interface { Start() Stop() } type Phone struct{} // Phone实现Usb接口的所有方法 func (p Phone) Start() { fmt.Println("phone start working...") } func (p Phone) Stop() { fmt.Println("phone stop working...") } type Camera struct{} // Camera实现Usb接口的所有方法 func (c Camera) Start() { fmt.Println("camera start working...") } func (c Camera) Stop() { fmt.