自定义SQL Server数据访问层:打造专属数据交互之门

自定义SQL Server数据访问层:打造专属数据交互之门 在软件开发中,数据访问层(Data Access Layer, DAL)扮演着至关重要的角色,它作为应用程序与数据库之间的桥梁,负责所有的数据存取操作。SQL Server作为一个强大的关系型数据库管理系统,提供了多种机制来实现数据访问层。本文将指导你如何在SQL Server中构建一个高效、可维护的自定义数据访问层。 1. 数据访问层的重要性 数据访问层封装了所有对数据库的访问,确保数据操作的安全性、统一性和可维护性。一个良好的数据访问层设计可以提高应用的性能,降低维护成本。 2. 定义数据访问层的职责 执行SQL语句:包括查询(SELECT)、插入(INSERT)、更新(UPDATE)和删除(DELETE)操作。事务管理:确保数据的一致性和完整性。错误处理:统一处理数据访问过程中可能出现的异常。数据映射:将数据库中的数据转换为应用程序中的对象。 3. 设计数据访问层的架构 数据访问层可以采用多种设计模式,如Repository模式、Unit of Work模式等。 Repository模式:为数据模型定义一个集中的访问接口。Unit of Work模式:跟踪数据库操作,确保事务的一致性。 4. 使用ADO.NET实现数据访问 ADO.NET是.NET框架提供的数据访问技术,可以用来与SQL Server交互。 using (SqlConnection conn = new SqlConnection("YourConnectionString")) { conn.Open(); SqlCommand cmd = new SqlCommand("SELECT * FROM YourTable", conn); SqlDataReader reader = cmd.ExecuteReader(); while (reader.Read()) { // 处理每一行数据 } } 5. 实现数据访问层的基础类 创建一个基础数据访问类,封装常用的数据库操作。 public class DataAccessBase { protected readonly string _connectionString; public DataAccessBase(string connectionString) { _connectionString = connectionString; } protected SqlConnection CreateConnection() { return new SqlConnection(_connectionString); } protected void ExecuteNonQuery(string commandText) { using (var conn = CreateConnection()) { conn.

将本地的业务写成成可供RPC远程调用的方法

第一步:首先我们先定义proto文件,这些proto文件将会为远程调用者提供调用的方法,为login方法。 2.重写UserServiceRpc类中的Login方法。 在Login中做的操作主要是,得到requst里面的参数,然后调用本地的Login方法,调用结束之后将执行后调操作,将结果写入到response中。

Stable-Diffusion1.5

SD1.5权重:https://huggingface.co/runwayml/stable-diffusion-v1-5/tree/main SDXL权重:https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/tree/main diffusers库中的SD代码pipelines:https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/stable_diffusion diffusers库中的SDXL代码pipelines: https://github.com/huggingface/diffusers/tree/main/src/diffusers/pipelines/stable_diffusion_xl 参考:深入浅出完整解析Stable Diffusion(SD)核心基础知识 - 知乎 (zhihu.com) 目录 1.VAE 2.Unet 3.CLIP Text Encoder 4.SD训练过程: 5.SD推理 5.1文生图 5.2图生图 6.SD模型的加速方法参考: Stable Diffusion模型整体上是一个End-to-End模型,主要由VAE(变分自编码器,Variational Auto-Encoder),U-Net以及CLIP Text Encoder三个核心组件构成 1.VAE VAE(变分自编码器,Variational Auto-Encoder)是基于Encoder-Decoder架构的生成模型。VAE的Encoder(编码器)结构能将输入图像转换为低维Latent特征,并作为U-Net的输入。VAE的Decoder(解码器)结构能将低维Latent特征重建还原成像素级图像。 在Stable Diffusion中,VAE模型主要起到了图像压缩和图像重建的作用 当我们输入一个尺寸为 H×W×C 的数据,VAE的Encoder模块会将其编码为一个大小为h×w×c的低维Latent特征,其中f=H/h=W/w为VAE的下采样率(Downsampling Factor)。反之,VAE的Decoder模块有一个相同的上采样率(Upsampling Factor)将低维Latent特征重建成像素级别的图像 VAE Encoder 和VAE Decoder结构图 #VAE压缩与重建代码展示 import cv2 import torch import numpy as np from diffusers import AutoencoderKL # 加载VAE模型: VAE模型可以通过指定subfolder文件来单独加载。 # SD V1.5模型权重百度云网盘:关注Rocky的公众号WeThinkIn,后台回复:SD模型,即可获得资源链接 VAE = AutoencoderKL.from_pretrained("/本地路径/stable-diffusion-v1-5", subfolder="vae") VAE.to("cuda", dtype=torch.float16) # 用OpenCV读取和调整图像大小 raw_image = cv2.

Spring中使用Async进行异步功能开发实战-以大文件上传为例

目录 前言 一、场景再现 1、Event的同步机制 二、性能优化 1、异步支持配置 2、自定义处理线程池扩展 3、将线程池配置类绑定到异步方法 三、总结 前言 在之前的博客中,曾将讲了在SpringBoot中如何使用Event来进行大文件上传的解耦,原文地址:使用SpringEvent解决WebUploader大文件上传解耦问题,在这篇博客当中,我们使用Event机制成功的将大文件的上传和解析的功能进行分离,已经实现了解耦的需求。但是在真实项目中会存在一个问题,就是解耦是解耦了。但是我们期望程序能够做到异步,也就是将文件的上传和解析进行彻底的异步化。后台程序在接收前端请求的文件时,文件上传完成后就结束。而对于上传文件的处理和解析等操作则放到解析程序中。整个过程给人的感觉就是到上传就完成了,解析则可以在后台慢慢运行,等待执行完成即可。 这里我们仍然以大文件上传为例,首先讲解在未进行程序异步化的时候,程序的运行机制和表现。然后讲解如何进行异步化的改造,让程序进行异步执行。通过本文不仅能让你掌握如何进行Event的事件开发,同时还能掌握在Spring中如何进行异步开发,熟悉@Async的具体用法。 一、场景再现 为了能让大家对故事的场景有更加直观的认识,这里我们将场景进行再现,让大家看到具体的问题。带着问题,我们一起来寻找解决办法,这样对前因后果更加清楚。 1、Event的同步机制 首先我们来看一下原来的事件分离处理代码,关键代码如下: @EventListener public void fileUploadEventRegister(FileUploadEvent event){ try { sys_user_logger.info("当前处理线程名称:" + Thread.currentThread().getName()); FileEntity fileEntity = event.getFileEntity(); if(StringUtils.isNotEmpty(fileEntity.getTablename())){ FileUploadServiceRegisterEnum rigisterEnum = null; if(StringUtils.isNotBlank(fileEntity.getBizType())) {//业务类型不为空,则根据表名和业务名称来查找执行service rigisterEnum = FileUploadServiceRegisterEnum.getEnumByTableNameAndBizType(fileEntity.getTablename(), fileEntity.getBizType()); }else { rigisterEnum = FileUploadServiceRegisterEnum.getEnumByTableName(fileEntity.getTablename()); } if(null != rigisterEnum && StringUtils.isNotEmpty(rigisterEnum.getExecService())){ String execService = rigisterEnum.getExecService(); IFileUploadCallbackService service = SpringUtils.getBean(execService); service.process(fileEntity); }else{ sys_user_logger.info("未注册文件上传监听回调处理器."); } } } catch (Exception e) { sys_user_logger.

【杂谈】-MQTT与HTTP在物联网中的比较:为什么MQTT是更好的选择

MQTT与HTTP在物联网中的比较:为什么MQTT是更好的选择 文章目录 MQTT与HTTP在物联网中的比较:为什么MQTT是更好的选择1、什么是MQTT2、什么是HTTP3、MQTT和HTTP之间的差异 MQTT(消息队列遥测传输)和HTTP(超文本传输协议)是两种不同的通信协议,每种都有其自身的优缺点。选择MQTT还是HTTP取决于您的应用程序的具体需求。以下是在某些情况下MQTT可能比HTTP更好的一些原因: 在一个设备和计算机需要相互通信的世界中,我们有不同的方式让它们做到这一点。其中两种方式称为MQTT和HTTP。MQTT就像一个高效、快速且安静的信使。它非常适合在设备之间发送小更新,比如告诉一个温度传感器实时将数据发送到您的手机。另一方面,HTTP就像发送电子邮件或打电话。当你请求某事,比如加载网页,然后你得到回复时,它很有用。但对于快速且持续的更新,MQTT通常是更好的选择。本文将解释为什么。 1、什么是MQTT MQTT,即消息队列遥测传输协议,是一种轻量级且高效的通信协议,专为网络中设备之间的可靠通信而设计。它遵循发布-订阅模型,其中设备(或客户端)通过一个名为代理的中央服务器进行通信。 MQTT如何工作? 在MQTT中,设备可以是发布者、订阅者,或两者兼而有之。发布者将消息(或“发布”它们)发送到代理上的特定主题,而订阅者通过订阅这些主题来表达他们对特定主题的兴趣。当发布者向某个主题发送消息时,代理确保对该主题感兴趣的所有订阅者都能收到该消息。这种解耦的方法允许异步和实时通信,使MQTT非常适合需要设备快速交换信息的应用程序,例如在物联网(IoT)中。此外,MQTT提供不同的服务质量(QoS)级别,允许用户选择消息传递可靠性的级别,从“至多一次”(可能会丢失消息)到“恰好一次”(保证消息传递但开销更大)。这种灵活性使得MQTT能够适应各种通信场景,从低延迟传感器数据传输到更可靠的业务关键型应用程序。 2、什么是HTTP HTTP,即超文本传输协议,是互联网的基本协议,用于在网络浏览器和网络服务器之间传输和接收数据。它构成了万维网上信息交换的基础。HTTP采用请求-响应模型:当你在浏览器中输入一个网址并按下“回车”键时,你的浏览器会向远程网络服务器发送一个HTTP请求。这个请求通常指定所需的网页或资源,服务器则以HTTP响应形式回应,提供所请求的内容以及有关请求状态的信息。此响应可能包括文本、图像、视频或构成网页的任何其他数据。 HTTP旨在简单且可由人阅读,使用纯文本作为其通信媒介。它采用无状态架构,意味着每个请求都是独立的,不保留过去的交互信息,简化了服务器管理并促进了可扩展性。此外,HTTP的超链接使用连接了网页,使您能够通过简单地点击链接在互联网上无缝导航到不同页面。本质上,HTTP是网络通信的支柱,允许我们访问并与网络上大量信息和服务进行交互。 3、MQTT和HTTP之间的差异 以下是在某些情况下MQTT可能比HTTP更好的一些原因: 低开销:MQTT旨在实现低开销通信。它使用发布/订阅模型,这对于发送小数据包更加高效。另一方面,HTTP由于其请求/响应模型和头部信息,开销更大,对于频繁且小的数据更新效率较低。 实时和异步:MQTT非常适合实时和异步通信。它允许推送通知和在数据更改时的即时更新,使其适用于需要实时传输传感器数据的IoT(物联网)等应用程序。相比之下,HTTP通常是请求驱动的,这可能会引入延迟。 发布/订阅模型:MQTT的发布/订阅模型非常适合于多个客户端需要更新相同信息的场景。订阅者可以在不需要请求的情况下接收数据,这使得向多个消费者广播数据更加高效。 低带宽和高延迟环境:MQTT旨在在低带宽和高延迟环境中表现良好。它使用轻量级二进制协议来减少交换的数据量。在这些情况下,由于其文本性质和额外的头部信息,HTTP的效率可能较低。 减少电池和数据使用量:MQTT常用于IoT应用中,这些设备的电池寿命和数据计划可能有限。与HTTP相比,MQTT的效率有助于节省电力和减少数据使用量,HTTP可能需要更频繁和更大的数据传输。 可靠消息传递:MQTT支持服务质量(QoS)级别,允许您选择消息传递可靠性的级别,从最多一次到恰好一次。这在数据完整性至关重要的应用中可能是关键。 可扩展性:MQTT代理可以处理大量连接的客户端,使其成为具有许多设备或用户的应用程序的可扩展选择。HTTP虽然可扩展,但可能需要更多资源来处理相似数量的连接。 安全性:MQTT和HTTP都可以被保护,但MQTT的轻量级特性意味着它可以是受限环境下的好选择,其中通信的安全性很重要但需要最小的开销。 比较内容MQTTHTTP通信模型发布-订阅请求-响应效率低开销,适合物联网更多开销,适合网络浏览实时性支持实时和推送通常是请求驱动,非实时异步支持异步消息传递同步的请求-响应消息传递可靠性支持服务质量(QoS)级别以确保可靠性没有内置的QoS级别发布-订阅遵循发布-订阅模型,允许多个客户端接收相同的数据客户端-服务器模型,需要明确的请求可扩展性对大量客户端具有良好的可扩展性可以扩展,但可能需要更多资源来处理类似的负载数据类型适合轻量级数据传输,如传感器数据通常用于传输网络内容,包括文本、图像、视频等低带宽在低带宽和高延迟环境中效率高在这些环境中可能效率较低安全性可以通过认证和加密进行保护也可以通过认证和加密进行保护使用场景常用于物联网、机器对机器(M2M)和实时数据应用对于网络浏览、网络服务和人类与网站的互动是基础性的协议二进制协议,轻量级基于文本的协议,开销更大连接类型持久连接常见通常是无状态的,每个请求都有单独的连接

三十种未授权访问漏洞复现 合集( 四 )

未授权访问漏洞介绍 未授权访问可以理解为需要安全配置或权限认证的地址、授权页面存在缺陷,导致其他用户可以直接访问,从而引发重要权限可被操作、数据库、网站目录等敏感信息泄露。---->目录遍历 目前主要存在未授权访问漏洞的有:NFS服务,Samba服务,LDAP,Rsync,FTPGitLab, Jenkins,MongoDB, Redis, ZooKeeper, ElasticSearch, Memcache,CouchDB,Docker,Solr,Hadoop,Dubbo 等... 未授权访问漏洞的复现思路: 1.使用靶场进行漏洞复现:(1)vulhub(2)本地搭建靶场 2.使用漏洞扫描工具进行扫描(1)github-功能受限(2)Python-定制化的完成漏洞扫描的利用 目录 十六:JBoss未授权访问漏洞 十七:Ldap未授权访问漏洞 十八:Rsync未授权访问漏洞 十九:VNC未授权访问漏洞 二十:Dubbo未授权访问漏洞 十六:JBoss未授权访问漏洞 》》》漏洞简介《《《 JBoss是一个基于J2EE的开放源代码应用服务器,代码遵循LGPL许可,可以在任何商业应用中免费使用;JBoss也是一个管理EJB的容器和服务器,支持EJB 1.1、EJB 2.0和EJB3规范。,默认情况下访问 http://ip:8080/jmx-console 就可以浏览 JBoss 的部署管理的信息不需要输入用户名和密码可以直接部署上传木马有安全隐患。 》》》漏洞复现《《《 fofa搜索语句:title="'Welcome to JBoss" 拼接以下路径且无需认证直接进入控制页面.. #拼接路径 http://ip:port/jmx-console/ #eg http://177.67.128.116//jmx-console/ 》》》漏洞修复建议《《《 1.jboss.deployment部署shell 2.进行JMX Console 安全配置。 十七:Ldap未授权访问漏洞 》》》漏洞简介《《《 LDAP中文全称为:轻型目录访问协议(Lightweight DirectoryAccess Protocol),默认使用389, LDAP 底层一般使用 TCP 或 UDP 作为传输协议。目录服务是一个特殊的数据库,是一种以树状结构的目录数据库为基础。未对LDAP的访问进行密码验证,导致未授权访问。 》》》漏洞复现《《《 使用以下Fofa语法搜索使用Idap服务的产品.…..并通过Ldapadmin可视化工具做连接验证.. #fofa语法 port="389" #Ldapadmin工具 http://www.ldapadmin.org/download/index.html https://sourceforge.net/projects/ldapadmin/ 启动工具并测试存在未授权的LDAP服务..成功如下. 》》》漏洞修复建议《《《 1.修改ldap的acl,不允许匿名访问。 2.根据业务设置ldap访问白名单或黑名单 十八:Rsync未授权访问漏洞 》》》漏洞简介《《《 Rsync未授权访问带来的危害主要有两个 1.造成了严重的信息泄露; 2.上传脚本后门文件,远程命令执行; Rsync 是Linux/Unix下的一个远程数据同步工具,可通过LAN/WAN快速同步多台主机间的文件和目录,默认运行在873端口。由于配置不当,导致任何人可未授权访问rsync,上传本地文件,下载服务器文件。Rsync 默认允许匿名访问,如果在配置文件中没有相关的用户认证以及文件授权,就会触发隐患。Rsync的默认端口为837 且默认配置文件路径在/etc/rsync.

2024年华数杯全国大学生数学建模竞赛C题老外游中国思路代码分析

A题"机械臂关节角路径的优化设计":运动学逆解模型、多目标优化算法(如NSGA-II或MOEA/D)、路径规划算法(如RRT或A*算法)、动力学模型、人工势场法避障算法、启发式算法(如遗传算法或粒子群优化)等。 对于B题"VLSI电路单元的自动布局":线长估计模型(如修正HPWL模型)、密度评估模型、布线密度计算模型、多目标优化算法(如NSGA-II或SPEA2)、启发式算法(如模拟退火或遗传算法)、空间数据结构(如四叉树)、力导向算法等。 对于C题"老外游中国":多准则决策模型(如AHP或TOPSIS)、图论模型、旅行商问题(TSP)求解算法、多目标优化算法(如NSGA-II或MOEA/D)、启发式算法(如蚁群算法或遗传算法)、文本分析和自然语言处理模型等。 难度排序从高到低:B题 > A题 > C题。 B题涉及到复杂的VLSI布局问题,需要综合考虑多个目标和约束,技术难度较高;A题需要深入理解机械臂的运动学和动力学,同时涉及复杂的路径规划,难度仅次于B题;C题虽然也涉及复杂的优化问题,但更偏重于数据处理和决策分析,相对来说更容易入手。 2024华数杯数学建模竞赛ABC题完整成品文章和全部问题的解题代码更新如下:https://www.yuque.com/u42168770/qv6z0d/dcgf4vr5t7bdtb0o 2024年华数杯全国大学生数学建模竞赛题目C题老外游中国 最近,“city 不city”这一网络流行语在外国网红的推动下备受关注。随着我国过境免签政策的落实,越来越多外国游客来到中国,通过网络平台展示他们在华旅行的见闻,这不仅推动了中国旅游业的发展,更是在国际舞台上展现了一个真实而生动的中国,一举多得。 假设外国游客入境后能在中国境内逗留144 小时,且能从任一城市附近的机场出境。由于每个城市景点较多,为了便于外国游客能够游览到更多的城市,现假定“每个城市只选择一个评分最高的景点游玩”,称之为“城市最佳景点游览原则”。 现有一个包含中国(不含港澳台)352 个城市的旅游景点的数据集,每个城市的csv 文件中有100 个景点,每个景点的信息包含有景点名称、网址、地址、景点介绍、开放时间、图片网址、景点评分、建议游玩时长、建议游玩季节、门票信息、小贴士等。 请建立数学模型,回答下列问题:问题1 请问352 个城市中所有35200 个景点评分的最高分(Best Score,简称BS)是多少?全国有多少个景点获评了这个最高评分(BS)?获评了这个最高评分(BS)景点最多的城市有哪些?依据拥有最高评分(BS)景点数量的多少排序,列出前10 个城市。 问题2 假如外国游客遵循“城市最佳景点游览原则”,结合城市规模、环境环保、人文底蕴、交通便利,以及气候、美食等因素,请你对352 个城市进行综合评价,选出“最令外国游客向往的50 个城市”。 问题3 现有一名外国游客从广州入境,他想在144 小时以内游玩尽可能多的城市,同时要求综合游玩体验最好,请你规划他的游玩路线。需要结合游客的要求给出具体的游玩路线,包括总花费时间,门票和交通的总费用以及可以游玩的景点数量。他的要求有:① 遵循城市最佳景点游览原则;② 城市之间的交通方式只选择高铁;③ 只在“最令外国游客向往的50 个城市”中选择要游玩的城市。 问题4 如果将问题3 的游览目标改为:既要尽可能的游览更多的城市,又需要使门票和交通的总费用尽可能的少。请重新规划游玩路线,并给出门票和交通的总费用,总花费时间以及可以游玩的城市数量。 问题5 现有一名外国游客只想游览中国的山景,他乘飞机入境中国的城市不限。请你为他选择入境的机场和城市,并个性化定制他的144 小时旅游路线,既要尽可能的游览更多的山,又需要使门票和交通的总费用尽可能的少。需要结合游客的要求给出具体的游玩路线,包括总花费时间,门票和交通的总费用以及可以游玩的景点数量。他的要求有:① 每个城市只游玩一座评分最高的山;② 城市之间的交通方式只选择高铁;③ 旅游城市不局限于“最令外国游客向往的50 个城市”,游览范围拓展到352 个城市。 C题分析 整体分析 这道2024华数杯数学建模竞赛C题题目围绕外国游客在中国的旅游规划展开,涉及数据分析、多准则决策、路径优化等多个方面。题目设计由简单的数据统计分析逐步过渡到复杂的旅游路线规划,全面考察参赛者的数据处理能力、决策分析能力和算法设计能力。整体来看,题目聚焦于如何在有限时间内maximizing旅游体验,同时考虑多种约束条件。 问题1分析 2024华数杯数学建模竞赛问题1主要考察数据处理和基本统计分析能力。这个问题要求从大量数据中提取特定信息并进行简单的统计分析。首要任务是对352个城市的35200个景点数据进行处理和整理,可能需要使用Python等编程语言进行数据读取和清洗。在数据处理过程中,需要注意处理可能存在的异常值、缺失值等数据质量问题。对于最高评分的统计,可以使用简单的排序和计数方法。 在实现过程中,可以考虑使用pandas等数据处理库来提高效率。对于大量数据的处理,需要考虑内存使用和计算效率的问题,可能需要采用分批处理或并行计算的策略。在结果呈现方面,可以使用数据可视化技术,如柱状图或热力图,来直观地展示不同城市最高评分景点的分布情况。这个问题虽然看似简单,但实际上考察了参赛者对大规模数据的处理能力和基本统计分析能力,是后续复杂问题的基础。 问题2分析 问题2涉及多准则决策分析,需要综合考虑多个因素来评价城市对外国游客的吸引力。这是一个典型的多属性决策问题,可以考虑使用层次分析法(AHP)、TOPSIS方法或模糊综合评价法等多准则决策方法。首先需要确定评价指标体系,包括城市规模、环境环保、人文底蕴、交通便利、气候、美食等因素,并为每个指标设定合适的评分标准。 在数据收集和处理方面,需要注意数据的可获得性和可靠性。有些指标可能需要从多个数据源综合得出,例如可以使用城市GDP和人口数据来表示城市规模,使用空气质量指数来表示环境环保程度,使用历史遗迹数量和文化场所数量来表示人文底蕴等。对于难以量化的指标,可以考虑使用专家评分或问卷调查的方法。在模型构建过程中,需要考虑各个指标的权重设置,可以采用专家打分法或熵权法等方法确定权重。最后,需要对352个城市进行综合评分,并选出排名前50的城市。 问题3分析 问题3是一个复杂的旅游路线规划问题,涉及到路径优化和时间管理。这个问题可以看作是带有时间窗口约束的旅行商问题(TSP)的变体。需要在给定的时间范围内(144小时),在选定的城市集合中(问题2中选出的50个城市)规划一条最优路径,maximizing游览的城市数量和综合游玩体验。 在模型构建方面,需要考虑多个约束条件:时间限制、交通时间(高铁)、游玩时间、景点评分等。可以使用图论模型来表示城市之间的连接关系,其中节点代表城市,边代表高铁线路,边权可以表示交通时间或费用。对于解决方案,可以考虑使用启发式算法,如遗传算法、蚁群算法或模拟退火算法。这些算法能够在合理的计算时间内找到接近最优的解。在算法设计时,需要考虑如何有效地编码解、设计适应度函数、以及如何处理约束条件。另一个关键点是如何平衡游览城市数量和游玩体验之间的权衡,可能需要设计复合的评价指标。 问题4分析 问题4是对问题3的扩展,增加了minimizing费用的目标,形成了一个多目标优化问题。这种情况下,需要在maximizing游览城市数量、maximizing游玩体验和minimizing总费用之间找到平衡。可以考虑使用多目标优化算法,如NSGA-II(非支配排序遗传算法II)或MOEA/D(基于分解的多目标进化算法)。 在模型构建方面,需要重新设计目标函数,将费用因素纳入考虑。可以采用加权和法将多个目标组合成单一目标,或者使用帕累托最优的概念来处理多目标问题。在算法设计时,需要考虑如何有效地表示和评估解的质量,可能需要使用非支配排序或超体积指标等技术。另一个挑战是如何在优化过程中平衡不同目标,可能需要设计动态权重调整策略。此外,还需要考虑算法的计算效率,因为多目标优化通常需要更多的计算资源。 问题5分析 问题5进一步增加了问题的复杂性,要求为特定主题(山景)定制旅游路线,并且扩大了选择范围。这个问题综合了前面几个问题的元素,包括数据筛选、路径规划和多目标优化。首先需要从352个城市中筛选出包含山景的城市,并从每个城市中选择评分最高的山景景点。这涉及到文本分析和数据过滤技术,可能需要使用自然语言处理方法来识别山景相关的景点。 在路线规划方面,由于起点(入境城市)不固定,问题变成了一个开放式旅行商问题。需要考虑如何选择最佳的起始城市,可以尝试多个潜在的起点并比较结果。优化目标包括maximizing游览的山景数量和minimizing总费用,这是一个典型的多目标优化问题。可以考虑使用多目标进化算法,如NSGA-III或MOEA/D-DE等。在算法设计时,需要特别注意如何处理大规模问题(352个城市),可能需要采用问题分解或预处理技术来提高算法效率。结果的呈现需要清晰地展示旅游路线、时间安排、费用明细和景点列表,可以考虑使用地图可视化技术来直观展示路线。(后续完整内容见前文完整版本)

目标跟踪那些事

目标跟踪那些事 跟踪与检测的区别 目标跟踪和目标检测是计算机视觉中的两个重要概念,但它们的目的和方法是不同的。 目标检测(object Detection):是指在图像或视频帧中识别并定位一个或多个感兴趣的目标对象的过程 。 目标跟踪(object Tracking):是指在视频帧序列中连续地监测和定位一个或多个目标对象的位置的过程。 区别:跟踪与检测的区别 输入数据不同:目标检测通常处理单一的图像,而目标跟踪处理的是视频序列。 Input:视频序列 Output: The trajectory and a unique ID for each target. 目标和任务不同:目标检测关注于在单个图像或视频帧中确定和定位对象,而目标跟踪关注于在视频序列中跟踪对象的动态变化。 目标跟踪应用场景 常见的应用场景包括了: 自动驾驶车流人流的统计越界识别与监控 实时决策:在许多应用中,如无人驾驶车辆或安全监控,实时的目标跟踪能够提供必要的信息来做出快速决策。 自动化流程:目标跟踪可以自动化许多任务,如视频分析或医学诊断,从而减少人工干预。 提高准确性:与人工跟踪相比,自动自标跟踪通常更加准确和一致。 增强体验:在娱乐和游戏行业,目标跟踪提供了更沉浸式的体验,使用户感觉更真实。 目标跟踪的困难 困难一:Inter-Object Occlusion 物体之间的遮挡。 困难二:Obstacle Occlusion :障碍物的阻碍(导致跟踪后前后的物体被判断为两个对象)也就是导致id switch现象的发生。 目标跟踪的步骤 当前主流的目标跟踪:Tracking-by-detection的主要步骤 通过检测器做目标的定位进行特征的提取做数据的关联(匈牙利算法)轨迹的管理与状态的更新(卡尔曼滤波) 主流的目标跟踪算法 DeepSORT、ByteTrack和BoT-SORT都是当前较为主流的多目标跟踪算法,各有特点: DeepSORT:基于检测的跟踪框架,使用深度ReID网络提取目标特征,并结合卡尔曼滤波进行运动预测,性能稳定。 ByteTrack:端到端跟踪框架,直接在目标检测的基础上进行跟踪,可以没有独立的特征提取模块。速度快但不如DeepSORT鲁棒。 BoT-SORT:在ByteTrack基础上使用相机运动补偿和改进的具有更准确状态向量的卡尔曼滤波器。精度较高但速度较慢。 总体来说: 如果追求速度,可以首选ByteTrack。如果追求精度,BoT-SORT会更好。如果资源有限但要稳定跟踪,DeepSORT是不错的选择。 多目标跟踪任务 Multi-object tracking (MoT) is to locate each target at each frame, and draw their trajectories 包括两种常见的方式: Model-free-tracking (MFT):需要手动的初始化给出第一帧中目标对象的位置,在此基础上进行目标的跟踪。 Tracking-by-detection (TBD) :不需要初始化只需要一个检测器即可实现。 首先会做视频帧的分割Frames Separation送入神经网络的目标检测器(Object Detector Neural Network)进行检测MOT问题可以看作是数据关联问题,其目的是将视频序列中跨帧的检测关联起来。 多目标跟踪数据集 多目标跟踪(Multiple Object Tracking,MOT)数据集主要用于评估和比较不同的多目标跟踪算法。这些数据集包含带有标注的视频序列,其中的每一帧都标注了目标对象的位置(通常是用边界框表示)和ID。

OpenCV及rembg去除图像背景

OpenCV去除图像背景 去除图像背景,需要综合使用二值化(thresholding)、腐蚀(erosion)、膨胀(dilation)以及位运算(bitwise operations),代码如下: #include "opencv2/imgcodecs.hpp" #include "opencv2/highgui.hpp" #include "opencv2/imgproc.hpp" #include <iostream> using namespace cv; int main(int argc, char** argv) { CommandLineParser parser(argc, argv, "{@input | dog.jpg | input image}"); // Read an image Mat src = imread(samples::findFile(parser.get<String>("@input"))); if (src.empty()) { std::cout << "Could not open or find the image!\n" << std::endl; std::cout << "Usage: " << argv[0] << " <Input image>" << std::endl; return EXIT_FAILURE; } // Convert the image to grayscale Mat grayImg; cvtColor(src, grayImg, COLOR_BGR2GRAY); // Remove the background using a threshold // median filter is applied to reduce noise in the image // ksize is 5 Mat grayImgBlurred; medianBlur(grayImg, grayImgBlurred, 5); // A binary threshold is applied to the grayscale image using a threshold Mat binaryImg; double thresh = threshold(grayImgBlurred, binaryImg, 150, 255, THRESH_BINARY_INV); // Output the thresh std::cout << thresh << std::endl; // The binary image is eroded to remove small objects and fill in small gaps using erode Mat erodedMask; erode(binaryImg, erodedMask, getStructuringElement(MORPH_RECT, Size(3, 3)), Point(-1, 1), 2); // The binary image is dilated to expand the remaining foreground objects # and fill in gaps using dilate Mat mask; dilate(erodedMask, mask, getStructuringElement(MORPH_RECT, Size(3, 3)), Point(-1, 1), 2); // The original input image is combined with the binary mask using bitwise_and Mat backgroundRemovedImg; bitwise_and(src, src, backgroundRemovedImg, mask); // Display the processed images imshow("

Yarn:一个快速、可靠且安全的JavaScript包管理工具

(创作不易,感谢有你,你的支持,就是我前行的最大动力,如果看完对你有帮助,还请三连支持一波哇ヾ(@^∇^@)ノ) 目录 一、Yarn简介 二、Yarn的安装 1. 使用npm安装Yarn 2. 在macOS上使用Homebrew安装Yarn 3. 在Windows上使用Chocolatey安装Yarn 4. 在Linux上使用包管理器安装Yarn 三、Yarn的配置 1. 全局配置 2. 项目配置 四、Yarn的基本用法 1. 初始化新项目 2. 添加依赖 3. 升级依赖 4. 移除依赖 5. 安装依赖 6. 运行脚本 7. 查看依赖树 8. 清理缓存 一、Yarn简介 Yarn是一个快速、可靠且安全的JavaScript包管理工具。与npm类似,Yarn用于管理项目的依赖项,但在性能、安全性和一致性方面做了许多改进。Yarn通过并行化下载和本地缓存机制,大大提升了依赖安装的速度,并通过生成yarn.lock文件来确保不同环境中依赖版本的一致性。 Yarn的主要特点包括: 快速性能:通过并行下载和本地缓存,Yarn显著加快了包的安装速度。可靠性:通过严格的依赖管理和yarn.lock文件,Yarn确保了依赖项在不同环境中的一致性。安全性:Yarn会验证依赖项的来源和内容,以确保下载的内容与预期一致。语义化版本控制:支持指定依赖项的版本范围,以便在满足向后兼容的情况下自动更新。离线支持:通过本地缓存,Yarn支持在无网络连接的情况下安装包。自动解决依赖冲突:Yarn能够自动解决依赖冲突,确保项目中使用的每个依赖项都符合其他依赖项的要求。 二、Yarn的安装 Yarn的安装方法多种多样,以下是一些常见的安装方法: 1. 使用npm安装Yarn 这是最简单且推荐的方法。确保你的计算机上已经安装了Node.js,因为npm(Node Package Manager)是Node.js的包管理器。在命令行或终端中执行以下命令来全局安装Yarn: npm install -g yarn 安装完成后,你可以通过运行yarn --version来验证Yarn是否安装成功。 2. 在macOS上使用Homebrew安装Yarn 如果你使用的是macOS,可以通过Homebrew来安装Yarn。首先确保安装了Homebrew,然后在终端中执行以下命令: /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" brew install yarn 安装完成后,同样使用yarn --version来验证安装是否成功。 3. 在Windows上使用Chocolatey安装Yarn 在Windows上,你可以通过Chocolatey来安装Yarn。首先安装Chocolatey,然后在PowerShell中以管理员身份运行以下命令: Set-ExecutionPolicy Bypass -Scope Process -Force; [System.

Flink实时数仓(六)【DWD 层搭建(四)交易域、互动域、用户域实现】

前言 今天的任务是完成 DWD 层剩余的事实表;今年的秋招开得比往年早,所以要抓紧时间了,据了解,今年的 hc 还是不多,要是晚点投铁定寄中寄了; 今天还是个周末,不过记忆里我好像整个大学都没有好好放松过过一个周末,毕竟只有周末的空教室才是最多的,可以抢到带插座的位置;emm... 等一切尘埃落定一定好好放松放松~ 1、交易域下单事务事实表 昨天我们创建了订单与处理表(把订单明细、订单、订单明细活动、订单明细优惠券等订单相关和表和 MySQL lookup 字典表关联到了一起),就是为了之后做关于订单的事实表的时候不用再去频繁关联造成重复计算; 1.1、实现思路 从 Kafka dwd_trade_order_pre_process 主题读取订单预处理数据筛选下单明细数据:新增数据(type = 'insert')写入 Kafka 下单明细主题 1.2、代码实现 1.2.1、读取订单与处理表 这里只需要保留有用的数据,其它字段(比如 old 、order_status 这些字段这里完全没用,是给取消订单表用的)直接丢弃掉 // TODO 2. 读取订单预处理表 tableEnv.executeSql("create table dwd_trade_order_pre_process(" + "id ," + "order_id ," + "user_id ," + "sku_id ," + "sku_name ," + "province_id ," + "activity_id ," + "activity_rule_id ," + "coupon_id ," + "date_id ," + "create_time ," + "

个人主体的小程序可以变更为企业主体吗?

小程序迁移变更主体有什么作用? 长期以来,由于部分小程序在注册时,主体不准确的历史原因,或者小程序的主体发生合并、分立或业务调整等现实状况,在小程序登记主体不能对应实际运营人的情况下,导致账号在认证或年审时遇到不少麻烦,影响部分功能的正常使用,也不利于外界了解账号的运营情况。借助“小程序迁移变更主体”流程,就是为了解决这一问题。 小程序主体个人变更企业怎么弄? 若想进行小程序迁移变更主体,需先检查后台绑定的商户号,看是否绑定了服务商的商户号。要是绑定了,那不管怎样都无法变更主体。 这个前提满足后,其他的就是目标主体必须是企业主体,不能是个人主体,这样就可以进行变更了。 小程序迁移变更主体需要的材料是什么? 1. 原主体和目标主体的营业执照照片; 2. 原主体和新主体的法人身份照片; 3. 原主体的服务类目若涉及相关资质,新主体也需具备相应资质,否则可能导致小程序下架。 小程序账号迁移变更主体的流程步骤是怎样的? 小程序迁移变更主体需要多久? 大概需要 3 天左右,其中TX审核时间不确定,这是影响整体时间的主要因素。审核需要 1 天,但通过后还需等待 1 个自然日,确保商户号没有交易,才能解绑旧商户号。解绑并绑定新商户号后,小程序主体变更才算完成。 小程序迁移变更主体解绑商户号的问题 为了保障新旧主体的资金安全利益,涉及支付功能的小程序,需在提交主体变更申请且审核成功后,解绑原主体商户号,才能继续完成主体变更流程。 所以为了不影响支付功能,提交主体变更申请且审核成功后,建议先绑定目标主体商户号,再解绑原主体商户号。

二进制与进制转换与原码、反码、补码详解--内含许多超详细图片讲解!!!

前言 今天给大家分享一下C语言操作符的详解,但在此之前先铺垫一下二进制和进制转换与原码、反码、补码的知识点,都非常详细,也希望这篇文章能对大家有所帮助,大家多多支持呀! 操作符的内容我放在我的下一篇文章啦,大家一定要看哈!!! 目录 前言 目录 一、二进制和进制转换 1. 10进制转化为10进制 2. 2进制转化为10进制 2.1 10进制转化为2进制 3. 2进制转8进制和16进制 3.1 2进制转8进制 3.2 2进制转16进制 二、原码、反码、补码 为什么数据存放的是补码? 结尾 一、二进制和进制转换 我们所说的2进制、8进制、10进制、16进制就是数值的不同表现形式。 eg:13的2进制:1101 13的8进制:15 13的10进制:13 13的16进制:d 1. 10进制转化为10进制 eg:123 从个位开始,平方都是从0先开始 2. 2进制转化为10进制 2进制是由(0~1)的数字组成 10进制是由(0~9)的数字组成 eg:1101 相比十进制转化为十进制,这次的底数变为2了先分别算每一项,加在一起,别忘记乘上所在位数对应的数字 2.1 10进制转化为2进制 eg:125 所得出的余数从下往上写就是转化完的二进制,为01111101,即1111101。 大家动手操作一下将它再转化为10进制!!! 注意:当数字比较小时,可以使用下图所示方法 如果是22呢,就为10110啦 3. 2进制转8进制和16进制 8进制是由(0~7)的数字组成16进制较为特殊,是由(0~9)、(a~f)组成的 3.1 2进制转8进制 首先,将0~7的数字各自写成2进制,最多有3个二进制位,所以像2的二进制本身是0,需要将它写成010,这个换算方法在上一节标红的注意,很实用,望大家都能掌握,在上图我已经先列出来了,因为8进制的每一位是0~7的数字,所以只需列出7个即可。 然后从2进制序列中右边低位开始向左每3个2进制位会换算一个8进制位,剩余不够3个2进制位的直接换算。 如图是2进制的0110101,从最右边开始依次取三个 011:3 101:5 001:1 但是值得注意的是,换算后的153,需要写成0153,0开头,才会被当做8进制 , 大家可以上机调试一下,153与0153是不同的。 3.2 2进制转16进制 2进制转化为16进制与转化为8进制相同,是将0~9、a~f各自写成2进制,需要4个2进制位 eg:2进制的01101011 同时我也将二进制都列了出来,但是建议还是要动手算算。 所以转化为的结果为0x6b,相同的,16进制前要加上0x。 二、原码、反码、补码 整数的二进制形式有三种:原码、反码、补码。有符号整数的三种表示方法均有符号位和数值位两部分,二进制序列中,最高的一位被当做符号位,剩余的都是数值位。即正数最高位显示0,负数最高位显示1。整数分为正整数与负整数。在正整数中:原码=反码=补码。在负整数中: 直接将数值按照正负数的形式翻译成二进制得到的就是原码将原码的符号位不变,其他一次按位取反就是反码(1变成0,0变成1,符号位不变)反码+1得到补码 例:a=3与a=-3; 注意:逢二进一,如果反码尾数是101,则变成110

分布式服务架构[原理、设计与实践]学习笔记

地震是由不可抗力导致的,而事故与之不同,任何大的生产事故在发生之前都有迹可循,而且事故的发生并不是偶然的,我们应该善于从现象中总结规律,找到发现、止损和避免的方法 海恩法则 每一起严重事故的背后,必然有29次轻微事故和300起未遂先兆及1000起事故隐患。 事故的发生是量的积累的结果。再好的技术、再完美的规章,在实际操作层面也无法取代人自身的素质和责任心。 根据海恩法则,一起重大事故发生后,我们在处理事故和解决问题的同时,还要及时对同类问题的"事故征兆"和"事故苗头"进行排查处理,以防止类似问题重复发生,把问题解决在萌芽状态,这完全可以作为互联网企业线上应急的指导思想。在线上应急的过程中,不但要定位和解决问题,还要发现问题的根源,并找到发生事故之前的各种征兆,对征兆进行排查和分析,并做响应的报警处理。 墨菲定律 如果有两种或两种以上方式去做某件事情,而选择其中一种方式将导致灾难,则必定有人会做出这种选择。 任何事情都没有表面看起来那么简单。所有事情的发展都会比你预计的时间长。会出错的事情总会出错。如果你担心某种情况发生,那么它更有可能发生。 墨菲定律实际上是个心理学效应,如果你担心某种情况会发生,那么它更有可能发生,久而久之就一定会发生。这警示我们,在互联网公司里,对环境发生的任何怪异现象和问题都不要轻易忽视,对于其背后的原因一定要彻查。 同样,海恩法则也强调任何严重事故的背后都是多次小问题的积累,积累到一定的量级后会导致质变,严重的问题就会浮出水面。 对于任何现象都要秉承着"为什么发生?发生了怎么应对?怎么恢复?怎么避免?"的原则,对问题要彻查,不能因为问题的现象不明显而忽略。 6.2. 线上应急的目标、原则和方法 6.2.1. 应急目标 在生产环境发生故障时快速恢复服务,避免或减少故障造成的损失,避免或减少故障对客户的影响, 6.2.2 应急原则 恢复系统,快速止损,而不是彻底解决问题。有明显的资金损失时,升级问题快速止损。不影响用户体验的前提下,保留部分现场和数据。 6.2.3 线上应急的额方法和流程 有条不紊地进行,遇事胆大心细,该做决策的时候要毫不犹豫,该升级的时候要果断。 线上应急一般分为6个阶段:发现问题、定位问题、解决问题、消除影响、回顾问题、避免措施。 在应急过程中要记住,应急只有一个总体目标:尽快恢复问题,消除影响。 定位问题 问题系统最近是否进行了上线?依赖的基础平台和资源是否进行了上线或者升级?依赖的系统最近是否进行了上线?运营是否在系统里面做过运营变更?网络是否有波动?最近的业务量是否增加?服务的使用方是否有促销活动? 回顾问题 类似的问题还有哪些没有想到?做了哪些事情,这个事故就不会发生?做了哪些事情,这个事故即使发生了,也不会产生损失?做了哪些事情,这个事故即使发生了,也不会造成这么大的损失? 6.3 技术攻关的方法论 技术攻关的目标是解决问题,因此首先要从问题发生的环境和背景入手,首先考虑下面几个问题。 最近是否有变更、升级和上线?(回滚)之前是否遇到过类似的情况?(使用历史经验)是否有相关领域的专家?例如:安全、性能、数据库、大数据和业务等领域的专家(开启专家模式)【最小化复现→找到原因→提出解决方案→验证解决方案→线上实施】。 对于任何问题,我们必须收集发生这些问题的现象,考虑如下问题。 When:什么时候出的问题?What:什么出了问题?Who:谁在什么时间里发现了问题?问题影响了谁?Where:哪里出现了问题?哪里又没出现问题?Why:为什么出现了问题? 6.5高效的服务化治理脚本 6.5.1 show-busiest-java-threads 此命令是用来查找java进程内CPU利用率最高的线程,一般适用于服务器负载较高的场景,并需要快速定位负载过高的成因。 命令格式: ./show-busiest-java-threads -p 进程号 -c 显示条数 ./show-busiest-java-threads -h 脚本源码: #!/bin/bash PROG=`basename $0` usage()

【微服务】springboot 整合 SA-Token 使用详解

目录 一、前言 二、认证与授权介绍 2.1 什么是认证 2.1.1 认证的目的 2.1.2 认证基本步骤 2.2 什么是授权 2.2.1 常用的授权模型 三、微服务中常用的认证安全框架 3.1 Spring Security 3.1.1 Spring Security 特点 3.2 JWT (JSON Web Tokens) 3.2.1 JWT特点 3.3 其他认证安全框架 四、SA-Token介绍 4.1 SA-Token是什么 4.2 SA-Token特点 4.3 SA-Token使用场景 五、springboot集成SA-Token 5.1 数据准备 5.1.1 创建认证和授权使用相关的数据表 5.2 搭建springboot工程 5.2.1 导入基础依赖 5.2.2 添加配置文件 5.3 SA-Token 登录认证原理 5.3.1 SA-Token登录认证原理介绍 5.3.2 SA-Token登录登出核心API 5.4 SA-Token登录认证代码演示 5.4.1 增加token的配置类 5.4.2 增加全局异常处理类 5.4.3 登录登出接口 5.4.4 获取用户信息接口 5.4.5 接口测试与效果验证 5.4.6 集成redis管理登录会话

JavaScript 继承百花齐放:从原型链到 ES6 类

前言 📫 大家好,我是南木元元,热爱技术和分享,欢迎大家交流,一起学习进步! 🍅 个人主页:南木元元 在 JavaScript 中,继承是一个重要的知识点,上篇文章中我们已经了解了原型和原型链的概念,本文就来介绍一下js中实现继承的几种方式。 目录 继承 实现继承的方法 1.原型链继承 2.借用构造函数继承 3.组合继承 4.原型式继承 5.寄生式继承 6.寄生组合式继承 7.class继承 结语 继承 继承,简单来讲就是让子类能够访问到父类的属性和方法,继承的主要作用就是实现代码的重用。 在JavaScript中,主要通过原型链来实现继承。我们重温一下构造函数、原型和实例的关系: 每个构造函数都有一个原型对象,原型有一个属性指回构造函数,而实例有一个指针指向原型。 实现继承的方法 1.原型链继承 原型链继承的基本思想:让子类构造函数的原型指向父类的实例。 function Parent () { this.name = 'kevin'; } Parent.prototype.getName = function () { console.log(this.name); } function Child () {} //让子类原型指向父类实例 Child.prototype = new Parent(); var child1 = new Child(); console.log(child1.getName()) // kevin 缺点是引⽤类型的属性被所有实例共享,并且创建子类型实例时,不能向父类型传参。 2.借用构造函数继承 基本思想:在子类构造函数中调用父类构造函数,使用call将父对象的构造函数绑定在子对象上。 function Parent () { this.names = ['kevin', 'daisy']; } function Child () { // 调用父类构造函数 Parent.

[数据集][目标检测]肾结石检测数据集VOC+YOLO格式1299张1类别

数据集格式:Pascal VOC格式+YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):1299 标注数量(xml文件个数):1299 标注数量(txt文件个数):1299 标注类别数:1 标注类别名称:["stone"] 每个类别标注的框数: stone 框数 = 2827 总框数:2827 使用标注工具:labelImg 标注规则:对类别进行画矩形框 重要说明:暂无 特别声明:本数据集不对训练的模型或者权重文件精度作任何保证,数据集只提供准确且合理标注 图片示例: 标注示例: 下载地址:https://download.csdn.net/download/FL1623863129/89613323

电脑添加虚拟网卡与ensp互联,互访

一、按照过程 1、打开设备管理器 2、点击网络适配器,点击左上角操作,点击“添加过时硬件” 3、下一页 4、选择“安装我手动从列表选择的硬件”,下一页 5、下拉,选择“网络适配器”,下一页 6、厂商选择“Microsoft”,型号选择“Microsoft KM-TEST 环回适配器”,下一页 7、下一页 8、点击完成 9、此时,电脑网卡就多了一个环回适配器 10、重启电脑生效 11、给换回适配器添加一个ip地址 12、ensp上添加一个AR和一个云 13、双击云,在云上添加一个udp端口 14、绑定信息处选择电脑的环回适配器,添加一个新的端口 15、配置好端口映射,入端口编号选择“1”,出端口编号选择“2”,勾选上“双向通道”,点击增加 此时云上,一个接口接路由器,一个接口接电脑 16、给路由器互连接口配上同网段IP 17、测试联通性,此时电脑和路由器之间能够互相ping通

AekTs变量的存储与修改

目录 一.变量的存储 二、定义数组 三、函数 四、对象 五、联合类型 六、定义枚举 七、转数字类型 八、转字符串 九、赋值运算符 十、一元运算符 十一、比较运算符 十二、逻辑运算符 十三、运算符的优先级 十四、数组的操作 十五、if条件语句 十六、switch语句 十七、三元表达式 十八、页面的条件渲染 十九、while循环 二十、for循环 二十一、终止循环 二十二、遍历数组 二十三、数组对象 二十四、ForEach渲染控制 一.变量的存储 // 1.变量的存储与修改 //变量存储 let title:string ='巨无霸汉堡' console.log("字符串title",title); let age:number=18 console.log("数字类型age",age); let isLogin:boolean=false console.log("布尔类型",isLogin); // 2.变量的修改 age=40 console.log("age修改",age); // 3.常量,定义后不能被修改 const PI:number=3.1415926 const companyName:string='华为' console.log('常量',PI,companyName); // 4.命名规则 // 只能包含数字、字母、下划线、$。不能以数字开头 // ② 不能使用内置关键字或保留字 (比如 let、const) // ③ 严格区分大小写 二、定义数组 // 语法: // let 数组名: 类型[] = [数据1, 数据2, 数据3, .