-
在规划系统搭建时,很多人会卡在 “选云部署还是本地部署” 这一步。有人觉得云部署灵活省心,也有人坚持本地部署更安全可控。其实两者没有绝对的好坏,只是适用场景不同。今天从前期投入、运维难度、安全性、灵活性、成本结构、适用场景六个核心维度,用大白话拆解它们的差异,帮你搞清楚哪种部署方式更适合自己的需求。 一、先搞懂:啥是云部署?啥是本地部署?在对比之前,先简单明确两个概念,避免后续理解偏差。云部署:简单说就是把系统、数据放在服务商提供的 “云端服务器” 上,你不用自己买硬件,通过网络就能访问和管理。比如你用在线文档、在线设计工具,背后的系统就是云部署模式 —— 服务商帮你维护服务器,你只管使用功能。本地部署:则是把系统、数据放在自己搭建的硬件设备上,这些设备通常放在公司的机房或指定场地。比如传统企业的财务系统、工厂的生产管理系统,很多会选择把服务器放在自己公司里,从硬件到软件都由自己团队维护。这两种模式的核心区别,本质是 “把服务器放在别人那里还是自己这里”,但由此延伸出的投入、运维、安全等差异,会直接影响业务运行。二、多维度对比:云部署和本地部署的 “优劣势”1. 前期投入:“轻启动” vs “重资产”前期投入主要看搭建系统时,在硬件、场地、基础配置上要花多少钱、花多少时间。云部署:前期投入极低,属于 “轻启动” 模式。不用买服务器、不用租专门的机房,甚至不用请专业的硬件维护人员。只要注册云服务商账号,根据需求选择服务器配置(比如内存、CPU、存储大小),几分钟就能完成基础搭建,然后把系统部署上去。对中小团队或创业公司来说,前期不用一次性砸钱在硬件上,能把资金集中在核心业务上。本地部署:前期投入高,属于 “重资产” 模式。首先得买服务器、交换机、防火墙等硬件设备,一台性能合格的服务器就要几万块,要是业务规模大,可能需要多台设备组成集群,硬件成本轻松过十万;其次要找专门的机房,得满足恒温、恒湿、防静电、防断电的要求 —— 要么租商用机房(按机柜或面积收费,每月几千到几万),要么自己改造场地(装修 + 设备投入更高);最后还得配置基础环境,比如安装操作系统、搭建网络架构,这些都需要专业技术人员,耗时可能要几周到几个月。通俗总结:想快速启动、前期少花钱,选云部署;有充足预算、想长期掌控硬件,选本地部署。2. 运维难度:“甩手掌柜” vs “全流程操心”运维指的是系统上线后,服务器的维护工作,比如硬件维修、系统升级、故障处理等。这部分的难度,直接关系到需要投入多少人力。云部署:运维难度低,基本能当 “甩手掌柜”。硬件维护不用管 —— 服务器坏了、硬盘故障了,都是云服务商负责维修或更换,不用你派人盯着;基础环境维护不用管 —— 操作系统更新、安全补丁修复、网络故障排查,服务商有专业团队 24 小时处理;甚至还能享受自动化工具,比如自动备份数据、自动扩容服务器,减少人工操作。一般小团队找 1-2 个懂云平台的技术人员,就能搞定运维。本地部署:运维难度高,得 “全流程操心”。硬件要自己修 —— 服务器出问题,得自己找技术人员排查,要是配件坏了,还得临时采购更换,遇到紧急故障(比如服务器宕机),可能要熬夜处理;基础环境要自己维护 —— 操作系统升级怕影响业务,安全补丁要手动安装,网络架构调整需要专业的网络工程师;数据备份也得自己做,得买额外的存储设备,制定备份策略,万一备份出问题,数据丢失风险很高。通常需要组建专门的运维团队(硬件、网络、系统至少 3 个角色),人力成本高。通俗总结:没精力搞运维、想减少人力投入,选云部署;有专业运维团队、想自己把控维护细节,选本地部署。3. 安全性:“专业防护” vs “物理可控”安全性是很多人纠结的重点,尤其是涉及敏感数据(比如用户信息、财务数据)时,总担心 “放云端不安全” 或 “放本地容易被偷”。其实两者的安全逻辑不同,各有防护优势。云部署:靠 “专业防护” 保障安全。云服务商有多层安全措施 —— 从物理安全(机房 24 小时监控、指纹识别进入),到网络安全(防火墙、DDoS 攻击防护、数据加密传输),再到数据安全(多地域备份、数据加密存储、权限严格管控),这些防护措施的专业度,很多中小企业自己根本搭建不出来;而且服务商要遵守行业安全规范(比如数据隐私法规),一旦出现安全问题,会承担相应责任。不过风险在于,数据毕竟不在自己手里,要是服务商出现漏洞(比如被黑客攻击),可能会波及你的系统。本地部署:靠 “物理可控” 保障安全。数据和服务器都在自己场地,不用依赖外部网络,能避免云端可能出现的 “第三方风险”;可以根据自己的需求定制安全措施,比如安装专属防火墙、限制物理设备访问(只有指定人员能进机房)、数据不联网存储,适合对安全有极致要求的场景(比如涉及国家机密、核心商业数据的系统)。但风险在于,中小企业的安全防护能力通常不如专业云服务商,比如防火墙配置不当、员工操作失误,都可能导致安全漏洞,而且一旦机房发生意外(比如火灾、断电),数据恢复难度大。通俗总结:没能力做高端安全防护、想靠专业团队保障,选云部署;数据极度敏感、必须物理可控,选本地部署。4. 灵活性:“随用随调” vs “固定配置”灵活性指的是系统能根据业务需求,快速调整服务器资源(比如增加内存、扩大存储、提升并发能力),这对业务波动大的场景很重要。云部署:灵活性极高,能 “随用随调”。业务高峰期(比如电商大促、活动推广),可以一键增加服务器数量或提升配置,避免系统卡顿;业务低谷期(比如平时的深夜时段),可以减少资源配置,降低成本;而且支持 “按需付费”,比如临时需要大量存储,不用买硬件,直接在云端扩容,用完再缩容。对业务增长快、需求多变的团队来说,这种灵活性能快速响应市场变化。本地部署:灵活性低,多是 “固定配置”。服务器的硬件配置是固定的,比如买了一台 8G 内存的服务器,要是业务需要 16G 内存,就得重新买硬件、安装调试,整个过程至少要几天;要是业务突然爆发,现有服务器扛不住,临时采购硬件根本来不及,很容易导致系统崩溃;而且硬件一旦买了,就算用不上,也不能退,会造成资源浪费。适合业务稳定、需求变化小的场景,比如传统企业的内部管理系统。通俗总结:业务波动大、需要快速调整资源,选云部署;业务稳定、需求长期不变,选本地部署。5. 成本结构:“按需付费” vs“一次性投入 + 持续消耗”成本不只是前期花的钱,还要看长期的支出,两者的成本结构差异很大。云部署:成本结构是 “按需付费”,前期少花钱,后期按使用量付费。没有一次性硬件投入,每月或每年根据使用的资源(比如服务器时长、存储容量、流量)缴费,用多少付多少;而且不用承担硬件折旧成本 —— 服务器用几年会老化,云端不用你管折旧,直接用新设备;但长期来看,如果业务规模一直扩大,资源用量持续增加,总费用可能会超过本地部署(比如用了 5-10 年,累计的云服务费可能比买硬件贵)。本地部署:成本结构是 “一次性投入 + 持续消耗”,前期花大钱,后期有固定支出。前期要一次性买硬件、装修机房,投入高;后期的消耗包括:机房租金(如果是租的)、电费(服务器 24 小时运行,电费不低)、硬件折旧(服务器一般用 3-5 年就要更换)、运维人员工资(长期人力成本)。如果业务稳定,长期使用的总成本可能比云部署低,但要是业务萎缩,硬件和人力成本还是要承担,浪费会更明显。通俗总结:短期使用、业务增长不确定,选云部署(成本可控);长期稳定使用、业务规模大,选本地部署(长期成本可能更低)。6. 适用场景:别 “乱搭”,看需求匹配最后落到实际场景,两种部署方式各有 “舒适区”,强行用错场景会很麻烦。云部署适合这些情况:中小团队 / 创业公司:前期预算少、没专业运维团队,想快速启动业务(比如做一个在线工具、小型电商网站);业务波动大的场景:比如电商大促、直播带货,需要临时扩容服务器,避免卡顿;跨地域协作场景:团队分散在不同城市,需要通过网络随时访问系统(比如远程办公的协作系统);试错型项目:比如开发一个新产品原型,不确定后续是否长期使用,用云部署能减少前期投入风险。本地部署适合这些情况:大型传统企业 / 特殊行业:比如银行、国企、政府机构,有敏感数据(如客户隐私、财务数据),需要物理可控的安全保障;业务长期稳定的场景:比如工厂的生产管理系统、企业的财务系统,需求几年不变,不用频繁调整资源;无网络或弱网络环境:比如偏远地区的工厂、野外作业系统,无法稳定连接云端,只能用本地服务器;有成熟运维团队的企业:能自己承担硬件维护、安全防护,不想依赖外部服务商。三、选部署方式的 3 个实用建议:别跟风,看自身情况别被 “潮流” 绑架:现在很多人说 “都 2025 年了还在用本地部署?”,但如果你的业务需要物理可控的安全、有成熟运维团队,本地部署反而更合适;反之,要是你是小团队,没精力搞运维,跟风选本地部署只会给自己添堵。算 “长期账” 而非 “短期账”:比如你要做一个长期使用的企业内部系统,前期云部署可能便宜,但用 5 年后,累计的云服务费可能比买硬件贵;要是你做一个短期项目(比如只运营 1 年的活动网站),本地部署的硬件投入就是浪费,云部署更划算。考虑 “业务扩展性”:如果你的业务处于快速增长期(比如用户量每月翻倍),云部署的灵活性能帮你快速应对;要是业务规模固定(比如只有 100 个员工用的内部系统),本地部署的固定配置就足够,不用花冤枉钱买云端的 “灵活性”。最后:没有 “绝对好”,只有 “更匹配”有人说 “云部署是未来,本地部署会被淘汰”,也有人说 “本地部署才安全,云部署都是坑”,其实这两种说法都太绝对。云部署的核心优势是灵活、省心、低前期投入,适合快速变化的业务;本地部署的核心优势是安全可控、长期成本可能更低,适合稳定、敏感的业务。选部署方式前,先想清楚自己的业务需求(是否敏感、是否波动大)、团队能力(有没有运维团队)、预算结构(前期想少花钱还是长期想省成本),比纠结 “哪种更先进” 有用得多。毕竟,能稳定支撑业务、符合自身情况的部署方式,才是最好的。
-
本文将展示如何使用华为云 CodeArts 完成一个完整的全栈项目开发,涵盖需求规划、代码开发、CI/CD 流水线到应用部署的全过程。一、项目概述:智能用户管理系统1. 项目架构 2. 技术栈前端:Vue 3 + Element Plus后端:Spring Boot 2.7 + MyBatis Plus数据库:MySQL 8.0 + Redis部署:Docker + 华为云ECS二、CodeArts 项目配置1. 创建项目与仓库在 CodeArts 控制台:新建项目 "SmartUserManager"启用代码仓库,自动生成 Git 地址配置成员权限2. 后端 Spring Boot 开发项目结构textuser-service/├── src/│ ├── main/│ │ ├── java/com/example/userservice/│ │ │ ├── controller/│ │ │ ├── service/│ │ │ ├── entity/│ │ │ └── config/│ │ └── resources/│ │ └── application.yml├── pom.xml└── Dockerfile核心代码实现用户实体类:java// User.javapackage com.example.userservice.entity;import com.baomidou.mybatisplus.annotation.*;import lombok.Data;import java.time.LocalDateTime;@Data@TableName("users")public class User { @TableId(type = IdType.AUTO) private Long id; private String username; private String email; private String phone; @TableField(fill = FieldFill.INSERT) private LocalDateTime createTime; @TableField(fill = FieldFill.INSERT_UPDATE) private LocalDateTime updateTime; private Integer status;}用户控制器:java// UserController.javapackage com.example.userservice.controller;import com.example.userservice.entity.User;import com.example.userservice.service.UserService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.*;import java.util.List;@RestController@RequestMapping("/api/users")@CrossOrigin(origins = "*")public class UserController { @Autowired private UserService userService; @GetMapping public List<User> listUsers(@RequestParam(defaultValue = "1") Integer page, @RequestParam(defaultValue = "10") Integer size) { return userService.listUsers(page, size); } @PostMapping public User createUser(@RequestBody User user) { return userService.createUser(user); } @PutMapping("/{id}") public User updateUser(@PathVariable Long id, @RequestBody User user) { user.setId(id); return userService.updateUser(user); } @DeleteMapping("/{id}") public void deleteUser(@PathVariable Long id) { userService.deleteUser(id); }}业务逻辑层:java// UserService.javapackage com.example.userservice.service;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;import com.baomidou.mybatisplus.extension.plugins.pagination.Page;import com.example.userservice.entity.User;import com.example.userservice.mapper.UserMapper;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.stereotype.Service;import java.util.concurrent.TimeUnit;@Servicepublic class UserService { @Autowired private UserMapper userMapper; @Autowired private RedisTemplate<String, Object> redisTemplate; private static final String USER_CACHE_KEY = "user:"; public List<User> listUsers(Integer page, Integer size) { String cacheKey = USER_CACHE_KEY + "list:" + page + ":" + size; // 尝试从Redis缓存获取 List<User> cachedUsers = (List<User>) redisTemplate.opsForValue().get(cacheKey); if (cachedUsers != null) { return cachedUsers; } // 查询数据库 Page<User> userPage = new Page<>(page, size); List<User> users = userMapper.selectPage(userPage, null).getRecords(); // 写入缓存,有效期5分钟 redisTemplate.opsForValue().set(cacheKey, users, 5, TimeUnit.MINUTES); return users; } public User createUser(User user) { userMapper.insert(user); // 清除相关的缓存 clearUserCache(); return user; } private void clearUserCache() { // 清除用户列表相关的所有缓存 redisTemplate.delete(redisTemplate.keys(USER_CACHE_KEY + "list:*")); }}数据库配置:yaml# application.ymlspring: datasource: url: jdbc:mysql://${MYSQL_HOST:localhost}:3306/user_db username: ${MYSQL_USER:root} password: ${MYSQL_PASSWORD:password} driver-class-name: com.mysql.cj.jdbc.Driver redis: host: ${REDIS_HOST:localhost} port: ${REDIS_PORT:6379} password: ${REDIS_PASSWORD:} database: 0mybatis-plus: configuration: map-underscore-to-camel-case: true log-impl: org.apache.ibatis.logging.stdout.StdOutImpl3. 前端 Vue.js 开发用户列表组件vue<!-- UserList.vue --><template> <div class="user-management"> <el-card> <template #header> <div class="card-header"> <span>用户管理</span> <el-button type="primary" @click="handleCreate">新增用户</el-button> </div> </template> <el-table :data="userList" v-loading="loading"> <el-table-column prop="id" label="ID" width="80"></el-table-column> <el-table-column prop="username" label="用户名"></el-table-column> <el-table-column prop="email" label="邮箱"></el-table-column> <el-table-column prop="phone" label="手机号"></el-table-column> <el-table-column prop="createTime" label="创建时间"> <template #default="scope"> {{ formatDate(scope.row.createTime) }} </template> </el-table-column> <el-table-column label="操作" width="200"> <template #default="scope"> <el-button size="small" @click="handleEdit(scope.row)">编辑</el-button> <el-button size="small" type="danger" @click="handleDelete(scope.row)">删除</el-button> </template> </el-table-column> </el-table> <el-pagination v-model:current-page="currentPage" v-model:page-size="pageSize" :total="total" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange" @current-change="handleCurrentChange" /> </el-card> <!-- 用户编辑对话框 --> <user-dialog v-model:visible="dialogVisible" :user="currentUser" @confirm="handleDialogConfirm" /> </div></template><script setup>import { ref, onMounted } from 'vue'import { ElMessage, ElMessageBox } from 'element-plus'import UserDialog from './UserDialog.vue'import { getUserList, deleteUser } from '@/api/user'const userList = ref([])const loading = ref(false)const currentPage = ref(1)const pageSize = ref(10)const total = ref(0)const dialogVisible = ref(false)const currentUser = ref(null)const loadUserList = async () => { loading.value = true try { const response = await getUserList(currentPage.value, pageSize.value) userList.value = response.data total.value = response.total } catch (error) { ElMessage.error('获取用户列表失败') } finally { loading.value = false }}const handleCreate = () => { currentUser.value = null dialogVisible.value = true}const handleEdit = (user) => { currentUser.value = { ...user } dialogVisible.value = true}const handleDelete = async (user) => { try { await ElMessageBox.confirm('确定删除该用户吗?', '提示', { type: 'warning' }) await deleteUser(user.id) ElMessage.success('删除成功') loadUserList() } catch (error) { // 用户取消删除 }}const handleDialogConfirm = () => { dialogVisible.value = false loadUserList()}const handleSizeChange = (newSize) => { pageSize.value = newSize loadUserList()}const handleCurrentChange = (newPage) => { currentPage.value = newPage loadUserList()}const formatDate = (dateString) => { return new Date(dateString).toLocaleString()}onMounted(() => { loadUserList()})</script>API 接口封装javascript// api/user.jsimport request from '@/utils/request'export function getUserList(page = 1, size = 10) { return request({ url: '/api/users', method: 'get', params: { page, size } })}export function createUser(userData) { return request({ url: '/api/users', method: 'post', data: userData })}export function updateUser(id, userData) { return request({ url: `/api/users/${id}`, method: 'put', data: userData })}export function deleteUser(id) { return request({ url: `/api/users/${id}`, method: 'delete' })}三、CodeArts CI/CD 流水线配置1. 构建配置yaml# codearts-pipeline.ymlversion: 2.0name: user-service-pipelinestages: - name: build steps: - name: backend_build action: Build@3.0 inputs: command: | mvn clean package -DskipTests build_type: maven - name: frontend_build action: Build@3.0 inputs: command: | npm install npm run build build_type: frontend - name: test steps: - name: unit_test action: Test@3.0 inputs: command: | mvn test coverage: true - name: deploy steps: - name: build_docker_image action: Build@3.0 inputs: build_type: build_container dockerfile_path: ./Dockerfile image_name: user-service image_tag: $BUILD_NUMBER - name: deploy_to_ecs action: Deploy@3.0 inputs: target_server: $ECS_SERVER deploy_path: /opt/apps/user-service2. Dockerfile 配置dockerfile# 后端DockerfileFROM openjdk:8-jre-slimWORKDIR /appCOPY target/user-service-1.0.0.jar app.jarEXPOSE 8080ENTRYPOINT ["java", "-jar", "app.jar"]# 前端Dockerfile FROM nginx:alpineCOPY dist/ /usr/share/nginx/html/COPY nginx.conf /etc/nginx/nginx.confEXPOSE 80四、数据库初始化脚本sql-- 创建数据库和用户表CREATE DATABASE IF NOT EXISTS user_db CHARACTER SET utf8mb4;USE user_db;CREATE TABLE users ( id BIGINT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) NOT NULL UNIQUE, email VARCHAR(100) NOT NULL UNIQUE, phone VARCHAR(20), create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, status TINYINT DEFAULT 1 COMMENT '1-正常, 0-禁用', INDEX idx_username (username), INDEX idx_email (email), INDEX idx_create_time (create_time)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;-- 插入测试数据INSERT INTO users (username, email, phone) VALUES('admin', 'admin@example.com', '13800138000'),('user1', 'user1@example.com', '13900139000'),('user2', 'user2@example.com', '13700137000');五、部署与监控1. 应用部署验证bash# 检查服务状态curl http://your-ecs-ip:8080/api/users# 查看容器日志docker logs user-service-container2. 性能监控配置在 CodeArts PerfTest 中配置性能测试:yamltest_type: performancescenario: - name: user_api_load_test requests: - name: list_users url: /api/users method: GET headers: Content-Type: application/json load: concurrent_users: 100 duration: 300六、项目成果与价值通过 CodeArts 完成本项目,实现了:开发效率提升:代码编写、测试、部署时间减少 60%质量保障:自动化测试覆盖率达到 85%部署效率:一键部署,发布时间从小时级降至分钟级可维护性:完整的 CI/CD 流水线,便于迭代更新这个实战案例展示了 CodeArts 在真实项目开发中的完整应用流程,为企业级应用开发提供了完整的解决方案模板。
-
一、SQL语句分类1. DDL - 数据定义语言(Data Definition Language)作用:定义和管理数据库对象(表、视图、索引等)命令 说明 示例CREATE 创建 CREATE TABLE 表名 (...)ALTER 修改 ALTER TABLE 表名 ADD (列名 类型)DROP 删除 DROP TABLE 表名TRUNCATE 清空 TRUNCATE TABLE 表名特点:DDL操作会自动提交(COMMIT)不能回滚(ROLLBACK)修改表结构时要特别小心2. DML - 数据操纵语言(Data Manipulation Language)作用:操作表中的数据命令 说明 示例SELECT 查询 SELECT * FROM 表名INSERT 插入 INSERT INTO 表名 VALUES (...)UPDATE 更新 UPDATE 表名 SET 列=值 WHERE 条件DELETE 删除 DELETE FROM 表名 WHERE 条件特点:DML操作需要手动COMMIT才能生效可以ROLLBACK撤销本实验主要是DML中的SELECT查询3. DCL - 数据控制语言(Data Control Language)作用:控制用户权限命令 说明 示例GRANT 授权 GRANT SELECT ON 表名 TO 用户REVOKE 撤销 REVOKE SELECT ON 表名 FROM 用户二、SELECT语句完整语法基本结构SELECT [DISTINCT] 列名FROM 表名[WHERE 条件][GROUP BY 列名][HAVING 条件][ORDER BY 列名 [ASC|DESC]]AI写代码sql执行顺序(重要!)1. FROM --> 确定查询哪个表2. WHERE --> 过滤行(分组前)3. GROUP BY --> 分组4. HAVING --> 过滤组(分组后)5. SELECT --> 选择显示的列6. ORDER BY --> 排序7. DISTINCT --> 去重AI写代码sql为什么顺序重要?WHERE在GROUP BY之前,所以不能使用聚合函数HAVING在GROUP BY之后,可以使用聚合函数SELECT的别名在ORDER BY中可用,但在WHERE中不可用示例理解:SELECT 出版单位, AVG(单价) AS 平均单价FROM 书目WHERE 单价 > 20 -- ✅ 可以:WHERE在SELECT前执行-- WHERE 平均单价 > 30 -- ❌ 错误:平均单价别名还不存在GROUP BY 出版单位HAVING AVG(单价) > 30 -- ✅ 可以:HAVING在GROUP BY后ORDER BY 平均单价 DESC; -- ✅ 可以:ORDER BY在SELECT后,别名已存在AI写代码sql三、基础语法详解1. SELECT - 选择列-- 选择所有列SELECT * FROM 书目;-- 选择指定列SELECT 书名, 作者 FROM 书目;-- 使用别名SELECT 书名 AS 图书名称, 作者 AS 作者姓名 FROM 书目;-- AS可以省略SELECT 书名 图书名称, 作者 作者姓名 FROM 书目;-- 计算列SELECT 书名, 单价, 单价 * 0.8 AS 折扣价 FROM 书目;AI写代码sqlDISTINCT去重:-- 查询所有不同的出版单位SELECT DISTINCT 出版单位 FROM 书目;-- 查询所有不同的(出版单位, 图书分类号)组合SELECT DISTINCT 出版单位, 图书分类号 FROM 书目;AI写代码sql2. FROM - 指定表-- 单表FROM 书目-- 表别名FROM 书目 s -- s是别名FROM 书目 AS s -- AS可加可不加AI写代码sql为什么要用表别名?简化书写:s.书名 比 书目.书名 简洁多表查询时必需:区分同名列自连接时必需:同一个表要用不同别名3. WHERE - 过滤行基本比较运算符:运算符 说明 示例= 等于 WHERE 单价 = 30!= 或 <> 不等于 WHERE 单价 <> 30> 大于 WHERE 单价 > 30>= 大于等于 WHERE 单价 >= 30< 小于 WHERE 单价 < 30<= 小于等于 WHERE 单价 <= 30逻辑运算符:运算符 说明 示例AND 且(都要满足) WHERE 单价 > 20 AND 单价 < 40OR 或(满足一个即可) WHERE 出版单位='人民出版社' OR 出版单位='作家出版社'NOT 非(取反) WHERE NOT 出版单位='人民出版社'范围查询:-- BETWEEN...AND... (包含边界值)WHERE 单价 BETWEEN 20 AND 40-- 等价于WHERE 单价 >= 20 AND 单价 <= 40-- IN (...) 在列表中WHERE 出版单位 IN ('人民出版社', '作家出版社')-- 等价于WHERE 出版单位='人民出版社' OR 出版单位='作家出版社'AI写代码sql模糊查询:-- LIKE 模糊匹配-- % : 匹配任意长度的任意字符(包括0个)-- _ : 匹配单个任意字符WHERE 书名 LIKE '红%' -- 以"红"开头WHERE 书名 LIKE '%梦' -- 以"梦"结尾WHERE 书名 LIKE '%数据库%' -- 包含"数据库"WHERE 书名 LIKE '红_梦' -- "红"和"梦"之间有一个字符WHERE 书名 LIKE '__' -- 恰好两个字符的书名AI写代码sqlNULL值判断:-- 判断是否为NULLWHERE 归还日期 IS NULL -- ✅ 正确WHERE 归还日期 = NULL -- ❌ 错误(永远为FALSE) -- 判断是否不为NULLWHERE 归还日期 IS NOT NULL -- ✅ 正确WHERE 归还日期 != NULL -- ❌ 错误(永远为FALSE)AI写代码sql为什么不能用 = NULL?NULL表示"未知""未知"不等于任何值,包括"未知"本身NULL = NULL 的结果是NULL(不是TRUE也不是FALSE)只有IS NULL能正确判断NULL4. ORDER BY - 排序-- 单列排序ORDER BY 单价 ASC -- 升序(从小到大),ASC可省略ORDER BY 单价 DESC -- 降序(从大到小)ORDER BY 单价 -- 默认升序 -- 多列排序ORDER BY 单价 DESC, 书名 ASC-- 先按单价降序,单价相同再按书名升序 -- 使用列的位置(不推荐,可读性差)SELECT 书名, 单价 FROM 书目ORDER BY 2 DESC; -- 按第2列(单价)降序 -- 使用别名SELECT 书名, 单价 AS 价格 FROM 书目ORDER BY 价格 DESC; -- 使用别名排序AI写代码sqlNULL值的排序:ORDER BY 归还日期 -- NULL值排在最前面ORDER BY 归还日期 NULLS LAST -- NULL值排在最后面AI写代码sql5. 聚合函数五大聚合函数:-- COUNT(*) : 统计行数(包括NULL)SELECT COUNT(*) FROM 借阅; -- 总借阅次数 -- COUNT(列) : 统计非NULL值的数量SELECT COUNT(归还日期) FROM 借阅; -- 已归还的次数 -- SUM(列) : 求和SELECT SUM(单价) FROM 书目; -- 所有书的单价总和 -- AVG(列) : 平均值SELECT AVG(单价) FROM 书目; -- 平均单价 -- MAX(列) : 最大值SELECT MAX(单价) FROM 书目; -- 最贵的书价格 -- MIN(列) : 最小值SELECT MIN(单价) FROM 书目; -- 最便宜的书价格AI写代码sqlCOUNT(*)和COUNT(列)的区别:-- 假设表中有5行,其中2行的归还日期为NULL SELECT COUNT(*) FROM 借阅; -- 结果:5(包括NULL)SELECT COUNT(归还日期) FROM 借阅; -- 结果:3(只统计非NULL)SELECT COUNT(DISTINCT 借书证号) FROM 借阅; -- 统计不同的借书证号数量AI写代码sql注意事项:聚合函数忽略NULL值(COUNT(*)除外)聚合函数不能用在WHERE中(要用HAVING)SELECT中有聚合函数时,其他列要么也是聚合函数,要么在GROUP BY中6. GROUP BY - 分组基本语法:SELECT 分组列, 聚合函数(列)FROM 表名GROUP BY 分组列;AI写代码sql示例:-- 统计每个出版社的书目数量SELECT 出版单位, COUNT(*) AS 书目数量FROM 书目GROUP BY 出版单位; -- 统计每个出版社的书目数量和平均单价SELECT 出版单位, COUNT(*) AS 书目数量, AVG(单价) AS 平均单价FROM 书目GROUP BY 出版单位;AI写代码sqlGROUP BY的规则:规则1:SELECT中非聚合列必须在GROUP BY中-- ❌ 错误:书名不在GROUP BY中SELECT 出版单位, 书名, COUNT(*) FROM 书目GROUP BY 出版单位; -- ✅ 正确:书名加入GROUP BYSELECT 出版单位, 书名, COUNT(*) FROM 书目GROUP BY 出版单位, 书名;AI写代码sql为什么?GROUP BY将数据分组,每组返回一行如果书名不在GROUP BY中,数据库不知道该显示该组的哪个书名规则2:GROUP BY中的列可以不在SELECT中-- ✅ 正确:按出版单位分组,但不显示出版单位SELECT COUNT(*) AS 总数量FROM 书目GROUP BY 出版单位;AI写代码sql7. HAVING - 过滤分组HAVING vs WHERE:特性 WHERE HAVING作用对象 行(原始数据) 组(分组后的结果)执行时机 GROUP BY之前 GROUP BY之后能否使用聚合函数 否 是示例对比:-- 查询单价>20的书,按出版社分组,显示平均单价>30的出版社 SELECT 出版单位, AVG(单价) AS 平均单价FROM 书目WHERE 单价 > 20 -- WHERE: 过滤行(分组前)GROUP BY 出版单位HAVING AVG(单价) > 30 -- HAVING: 过滤组(分组后)ORDER BY 平均单价 DESC; -- 执行流程:-- 1. FROM 书目-- 2. WHERE 单价 > 20 (先过滤掉单价<=20的书)-- 3. GROUP BY 出版单位 (对剩余的书按出版社分组)-- 4. HAVING AVG(单价) > 30 (过滤掉平均单价<=30的组)-- 5. SELECT-- 6. ORDER BYAI写代码sql常见错误:-- ❌ 错误:WHERE中不能用聚合函数SELECT 出版单位, AVG(单价)FROM 书目WHERE AVG(单价) > 30 -- 错误!WHERE不能用AVGGROUP BY 出版单位; -- ✅ 正确:应该用HAVINGSELECT 出版单位, AVG(单价)FROM 书目GROUP BY 出版单位HAVING AVG(单价) > 30;AI写代码sql四、JOIN连接查询1. 内连接(INNER JOIN)语法:SELECT 列名FROM 表1INNER JOIN 表2 ON 连接条件;-- INNER可以省略,直接写JOINAI写代码sql特点:只返回两表都有匹配的记录相当于两表的交集示例:-- 查询借阅信息(只显示有借阅记录的读者)SELECT d.姓名, s.书名, j.借书日期FROM 借阅 jINNER JOIN 读者 d ON j.借书证号 = d.借书证号INNER JOIN 图书 t ON j.图书编号 = t.图书编号INNER JOIN 书目 s ON t.ISBN = s.ISBN;AI写代码sql2. 左外连接(LEFT JOIN)语法:SELECT 列名FROM 表1LEFT JOIN 表2 ON 连接条件;AI写代码sql特点:返回左表所有记录右表没有匹配时显示NULL示例:-- 查询所有读者的借阅次数(包括没借过书的)SELECT d.姓名, COUNT(j.借阅流水号) AS 借阅次数FROM 读者 dLEFT JOIN 借阅 j ON d.借书证号 = j.借书证号GROUP BY d.姓名; -- 结果会包括借阅次数为0的读者AI写代码sqlLEFT JOIN vs INNER JOIN:-- INNER JOIN:只显示有借阅记录的读者FROM 读者 dINNER JOIN 借阅 j ON d.借书证号 = j.借书证号-- 结果:只有借过书的读者 -- LEFT JOIN:显示所有读者FROM 读者 dLEFT JOIN 借阅 j ON d.借书证号 = j.借书证号-- 结果:所有读者,没借过书的借阅次数显示为0或NULLAI写代码sql3. 右外连接(RIGHT JOIN)语法:SELECT 列名FROM 表1RIGHT JOIN 表2 ON 连接条件;AI写代码sql特点:返回右表所有记录左表没有匹配时显示NULL不常用(可以调换表顺序用LEFT JOIN替代)4. 全外连接(FULL JOIN)语法:SELECT 列名FROM 表1FULL JOIN 表2 ON 连接条件;AI写代码sql特点:返回两表所有记录相当于LEFT JOIN + RIGHT JOINOracle支持,MySQL不支持五、子查询1. 标量子查询(返回单个值)-- 查询单价最高的图书SELECT * FROM 书目WHERE 单价 = (SELECT MAX(单价) FROM 书目); -- 子查询返回一个值:最高单价AI写代码sql2. 列子查询(返回一列值)-- 查询借过书的读者SELECT * FROM 读者WHERE 借书证号 IN (SELECT DISTINCT 借书证号 FROM 借阅); -- 子查询返回一列值:所有借过书的借书证号AI写代码sqlIN vs EXISTS:-- 使用INWHERE 借书证号 IN (SELECT 借书证号 FROM 借阅) -- 使用EXISTS(性能通常更好)WHERE EXISTS (SELECT 1 FROM 借阅 j WHERE j.借书证号 = d.借书证号)AI写代码sql3. 表子查询(返回一个表)-- 查询借阅次数>2的读者SELECT * FROM ( SELECT 借书证号, COUNT(*) AS 借阅次数 FROM 借阅 GROUP BY 借书证号) WHERE 借阅次数 > 2; -- 子查询返回一个临时表AI写代码sql六、常用函数1. 字符串函数-- 连接字符串SELECT 书名 || '(' || 作者 || ')' AS 完整信息 FROM 书目; -- 转换大小写SELECT UPPER(书名), LOWER(书名) FROM 书目; -- 截取字符串SELECT SUBSTR(书名, 1, 2) FROM 书目; -- 截取前2个字符 -- 字符串长度SELECT LENGTH(书名) FROM 书目;AI写代码sql2. 数值函数-- 四舍五入SELECT ROUND(单价, 1) FROM 书目; -- 保留1位小数 -- 向上取整SELECT CEIL(单价) FROM 书目; -- 向下取整SELECT FLOOR(单价) FROM 书目; -- 截断小数SELECT TRUNC(单价, 1) FROM 书目; -- 保留1位小数,不四舍五入AI写代码sql3. 日期函数-- 当前日期时间SELECT SYSDATE FROM DUAL; -- 日期相减(结果是天数)SELECT SYSDATE - 借书日期 AS 已借天数 FROM 借阅; -- 日期加减天数SELECT 借书日期 + 30 AS 应还日期 FROM 借阅; -- 加减月份SELECT ADD_MONTHS(借书日期, 1) AS 一个月后 FROM 借阅; -- 提取年月日SELECT EXTRACT(YEAR FROM 借书日期) AS 年份, EXTRACT(MONTH FROM 借书日期) AS 月份, EXTRACT(DAY FROM 借书日期) AS 日期FROM 借阅; -- 日期格式化SELECT TO_CHAR(借书日期, 'YYYY-MM-DD') AS 格式化日期 FROM 借阅;AI写代码sql4. NULL处理函数-- NVL(值1, 值2) : 如果值1为NULL,返回值2SELECT NVL(罚金, 0) AS 罚金 FROM 罚款分类; -- NVL2(值1, 值2, 值3) : 如果值1非NULL返回值2,否则返回值3SELECT NVL2(归还日期, '已还', '未还') AS 状态 FROM 借阅; -- COALESCE(值1, 值2, 值3, ...) : 返回第一个非NULL值SELECT COALESCE(归还日期, 借书日期, SYSDATE) FROM 借阅;AI写代码sql5. CASE表达式-- 简单CASESELECT 书名, CASE 是否借出 WHEN '是' THEN '已借出' WHEN '否' THEN '可借' ELSE '未知' END AS 状态FROM 图书; -- 搜索CASE(更常用)SELECT 书名, 单价, CASE WHEN 单价 < 20 THEN '低价' WHEN 单价 < 40 THEN '中价' ELSE '高价' END AS 价格等级FROM 书目;AI写代码sql七、常见错误及解决错误1:SELECT的列不在GROUP BY中-- ❌ 错误SELECT 出版单位, 书名, COUNT(*)FROM 书目GROUP BY 出版单位; -- 错误信息:ORA-00979: not a GROUP BY expression -- ✅ 解决:把书名加入GROUP BYSELECT 出版单位, 书名, COUNT(*)FROM 书目GROUP BY 出版单位, 书名;AI写代码sql错误2:WHERE中使用聚合函数-- ❌ 错误SELECT 出版单位, AVG(单价)FROM 书目WHERE AVG(单价) > 30GROUP BY 出版单位; -- 错误信息:ORA-00934: group function is not allowed here -- ✅ 解决:用HAVING代替WHERESELECT 出版单位, AVG(单价)FROM 书目GROUP BY 出版单位HAVING AVG(单价) > 30;AI写代码sql错误3:NULL值判断错误-- ❌ 错误SELECT * FROM 借阅WHERE 归还日期 = NULL; -- 查不到任何结果(因为NULL=NULL的结果是NULL,不是TRUE) -- ✅ 解决:用IS NULLSELECT * FROM 借阅WHERE 归还日期 IS NULL;AI写代码sql错误4:字符串忘记加引号-- ❌ 错误SELECT * FROM 书目WHERE 书名 = 红楼梦; -- 错误信息:ORA-00904: "红楼梦": invalid identifier -- ✅ 解决:字符串要用单引号SELECT * FROM 书目WHERE 书名 = '红楼梦';AI写代码sql错误5:日期格式错误-- ❌ 错误INSERT INTO 借阅 VALUES (1, '20051001', '2001231', '2010-09-19', NULL, NULL, NULL); -- 可能报错或插入错误的日期 -- ✅ 解决:使用TO_DATE函数INSERT INTO 借阅 VALUES ( 1, '20051001', '2001231', TO_DATE('2010-09-19', 'YYYY-MM-DD'), NULL, NULL, NULL);AI写代码sql八、学习建议1. 从简单到复杂第一步:单表查询(SELECT、WHERE、ORDER BY)第二步:聚合统计(COUNT、SUM、AVG、GROUP BY)第三步:多表连接(JOIN)第四步:子查询第五步:复杂综合查询2. 多练习、多思考不要只看代码,要动手写理解为什么这么写尝试用不同方法解决同一个问题3. 理解执行流程记住SELECT语句的执行顺序理解每个子句的作用知道为什么有些语法不能用4. 善用注释在复杂查询中添加注释说明查询的目的和逻辑方便日后维护九、快速参考SQL关键字速查关键字 作用 位置SELECT 选择列 开头FROM 指定表 SELECT后WHERE 过滤行 FROM后GROUP BY 分组 WHERE后HAVING 过滤组 GROUP BY后ORDER BY 排序 最后JOIN 连接表 FROM中AND/OR 逻辑运算 WHERE/HAVING中IN 在列表中 WHERE中LIKE 模糊查询 WHERE中IS NULL 判断NULL WHERE中运算符优先级括号 ()比较运算 =, !=, >, <, >=, <=NOTANDOR建议:使用括号明确优先级,提高可读性————————————————版权声明:本文为CSDN博主「万事大吉CC」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/2302_79277225/article/details/154410258
-
一、基本介绍Docker 是一个开源的应用容器引擎,参考链接:【docker使用安装教程】Redis 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 的 NoSQL 数据库,并提供多种语言的 API。本文将介绍docker上安装redis容器的详细过程。二、前期准备安装docker,参考链接:不同操作系统的docker方式我的是centos操作系统,直接执行命令:curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun安装即可三、docker安装redis参考链接:Docker 安装 Redis - 菜鸟教程史上最详细Docker安装Redis (含每一步的图解)实战3.1 redis镜像拉取查看可用的redis版本,执行命令:docker search redis拉取Redis镜像:从Docker Hub上获取Redis官方镜像,执行命令:docker pull <镜像名称>:<版本号>示例-默认拉取官方的最新版本的镜像docker pull redis3. 查看本地redis镜像,执行命令: docker images3.2 Docker挂载redis配置文件将redis的配置文件进行挂载,以配置文件方式启动redis容器挂载:将宿主机的文件和容器内部目录相关联,相互绑定,在宿主机内修改文件的话也随之修改容器内部文件挂载文件的位置可以自己随便选择1. 挂载redis的配置文件:redis.conf(1) 建立配置文件放置目录,执行命令:mkdir 目录/redis/conf/(2) 生成配置文件,执行命令:touch redis.conf(3) 写入内容:redis.conf的标准文件在redis官网也可以找到文件内容:# bind 192.168.1.100 10.0.0.1# bind 127.0.0.1 ::1#bind 127.0.0.1protected-mode noport 6379tcp-backlog 511requirepass 000415timeout 0tcp-keepalive 300daemonize nosupervised nopidfile /var/run/redis_6379.pidloglevel noticelogfile ""databases 30always-show-logo yessave 900 1save 300 10save 60 10000stop-writes-on-bgsave-error yesrdbcompression yesrdbchecksum yesdbfilename dump.rdbdir ./replica-serve-stale-data yesreplica-read-only yesrepl-diskless-sync norepl-disable-tcp-nodelay noreplica-priority 100lazyfree-lazy-eviction nolazyfree-lazy-expire nolazyfree-lazy-server-del noreplica-lazy-flush noappendonly yesappendfilename "appendonly.aof"no-appendfsync-on-rewrite noauto-aof-rewrite-percentage 100auto-aof-rewrite-min-size 64mbaof-load-truncated yesaof-use-rdb-preamble yeslua-time-limit 5000slowlog-max-len 128notify-keyspace-events ""hash-max-ziplist-entries 512hash-max-ziplist-value 64list-max-ziplist-size -2list-compress-depth 0set-max-intset-entries 512zset-max-ziplist-entries 128zset-max-ziplist-value 64hll-sparse-max-bytes 3000stream-node-max-bytes 4096stream-node-max-entries 100activerehashing yeshz 10dynamic-hz yesaof-rewrite-incremental-fsync yesrdb-save-incremental-fsync yes2. 挂载redis的持久化文件建立数据文件放置目录,执行命令:mkdir 目录/redis/data/3.3 启动redis容器docker run -p 6379:6379 --restart=always AI写代码1–log-opt max-size=100m–log-opt max-file=2–name myredis-v /root/redis/conf/redis.conf:/etc/redis/redis.conf-v /root/redis/data:/data-d redis redis-server /etc/redis/redis.conf–appendonly yes --requirepass 123456参数说明:1.-restart=always 总是开机启动2.-log 记录日志3.-p 端口映射4.-name 容器名5.-v 数据卷挂载6.-d redis 后台启动redis7.redis-server /etc/redis/redis.conf 以配置文件启动redis,加载容器内的conf文件,最终找到的是挂载的目录 /etc/redis/redis.conf,也就是linux下的 /home/redis/myredis/myredis.conf8.-appendonly yes 开启持久化9.-requirepass 123456 设置密码 简单的启动命令示例:docker run --name myredis -p 6379:6379 -d redis关闭容器命令:docker stop <容器名>示例:docker stop myredis3.4 验证Redis容器是否正常运行查看容器的运行信息,验证Redis容器是否正常运行:docker ps查看指定容器状态:docker ps -a | grep myredis查看容器运行日志:docker logs --since 30m <容器名>此处 --since 30m 为查看此容器30分钟之内的日志情况执行:docker logs --since 30m myredis容器内部连接测试:docker exec -it <容器名> /bin/bash#示例docker exec -it myredis redis-cli 四、Docker删除Redis容器查看所有在运行的容器:docker ps -a关闭容器:docker stop <容器名>删除容器:docker rm <容器名>五、Docker删除Redis镜像查看全部镜像 命令:docker images删除镜像 命令 :docker rmi <容器 id>————————————————版权声明:本文为CSDN博主「q***6532」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/2509_93929907/article/details/154388140
-
发送和接收的“对称”RS485使用差分信号来传输数据,它依赖于两根线A和B之间的电压差,而不是它们对地的绝对电压。关键在于,驱动器(发送器)和接收器是面对面的两个设备,它们的“视角”是相反的。可以用一个简单的比喻来理解:想象两个人面对面站着(一个人是驱动器,一个人是接收器)。当驱动器举起右手时,在接收器看来,举起的是对着它的那只手——也就是接收器的左手。详细分情况解析1. 驱动器 - Driver (发送数据的一端)驱动器的任务是在线路A和B之间产生一个电压差。当要发送逻辑 ‘1’ (Mark, 空闲状态) 时:驱动器会拉高A线电压,拉低B线电压。结果是:A线电压 > B线电压。产生的差分电压 VAB = VA - VB 为 +2V 至 +6V。结论:对于驱动器,逻辑1 = A > B。当要发送逻辑 ‘0’ (Space) 时:驱动器会拉低A线电压,拉高B线电压。结果是:B线电压 > A线电压,即 A线电压 < B线电压。产生的差分电压 VAB = VA - VB 为 -2V 至 -6V。结论:对于驱动器,逻辑0 = A < B。驱动器视角总结表:逻辑状态 电压关系 差分电压 VAB1 A > B +2V ~ +6V0 A < B -2V ~ -6V2. 接收器 - Receiver (接收数据的一端)接收器的任务是检测A和B线之间的电压差,并判断逻辑电平。当接收器检测到逻辑 ‘1’ 时:它测量的是 VBA = VB - VA。如果驱动器发送了逻辑1(A > B),那么对于接收器来说,就是 B < A,所以 VBA 是一个负电压。但接收器的判定标准是:只要 VBA < -0.2V (即 VA - VB > +0.2V),就判定为逻辑1。从关系上看,VBA < -0.2V 等价于 B - A < -0.2V,即 A - B > +0.2V,也就是 A > B + 0.2V。但接收器芯片内部是以B和A为输入引脚进行判定的,所以它的“视角”是:当B相对于A的电压足够低时(负差分电压),就是逻辑1。为了方便记忆,可以说:对于接收器,逻辑1 = B < A。当接收器检测到逻辑 ‘0’ 时:它同样测量 VBA = VB - VA。如果驱动器发送了逻辑0(A < B),那么对于接收器来说,就是 B > A,所以 VBA 是一个正电压。接收器的判定标准是:只要 VBA > +0.2V (即 VB - VA > +0.2V),就判定为逻辑0。从关系上看,这等价于 B > A + 0.2V。为了方便记忆,可以说:对于接收器,逻辑0 = B > A。接收器视角总结表:逻辑状态 电压关系 差分电压 VBA 判定条件1 B < A < -200mV VBA <= -200mV0 B > A > +200mV VBA >= +200mV为什么会有这种“视角”转换?电气对称性: RS485总线是挂接多个设备的,任何一个设备都可能作为发送方或接收方。将驱动器和接收器的定义做成一种“对称”或“互补”的关系,使得无论哪个设备在发送,信号在总线上的物理表现都是一致的。例如,设备1发送逻辑1(A>B),这个信号在总线上传播。设备2作为接收器,通过判断“B<A”来收到逻辑1。如果设备2要回复逻辑1,它同样会驱动自己的A>B。这样,总线上的电平定义就统一了。抗共模干扰: 差分信号的核心是抵抗共模噪声。这种定义方式确保了信号在长距离传输后,即使A和B线都叠加了相同的噪声,它们之间的相对电压差的极性依然是正确的,接收器总能根据 VBA 的正负来正确解译逻辑。总结驱动器 (发送) 接收器 (接收)逻辑 1 A > B (+2~+6V) B < A (VBA < -200mV)逻辑 0 A < B (-2~-6V) B > A (VBA > +200mV)简单方法:站在发送方的角度去定义总线状态。发送逻辑1 : 让 A 线为 正,B线为负(A > B)。发送逻辑0 : 让 B 线为 正,A线为负(A < B)。而接收器只是一个“裁判”,它只关心A和B谁电压高,并根据这个来输出对应的逻辑电平。由于芯片设计,这个“裁判”的内部电路约定好了:当B脚电压低于A脚电压时,它就输出逻辑1。参考:https://www.analog.com/cn/resources/app-notes/an-960.html————————————————版权声明:本文为CSDN博主「嵌入式学习和实践」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/weixin_46158019/article/details/154342931
-
接口描述了类的行为和功能,而不需要完成类的特定实现。C++ 接口是使用抽象类来实现的,抽象类与数据抽象互不混淆,数据抽象是一个把实现细节与相关的数据分离开的概念。如果类中至少有一个函数被声明为纯虚函数,则这个类就是抽象类。纯虚函数是通过在声明中使用 "= 0" 来指定的,如下所示:class Box { public: // 纯虚函数 virtual double getVolume() = 0; private: double length; // 长度 double breadth; // 宽度 double height; // 高度 };设计抽象类(通常称为 ABC)的目的,是为了给其他类提供一个可以继承的适当的基类。抽象类不能被用于实例化对象,它只能作为接口使用。如果试图实例化一个抽象类的对象,会导致编译错误。因此,如果一个 ABC 的子类需要被实例化,则必须实现每个纯虚函数,这也意味着 C++ 支持使用 ABC 声明接口。如果没有在派生类中重写纯虚函数,就尝试实例化该类的对象,会导致编译错误。可用于实例化对象的类被称为具体类。抽象类的实例请看下面的实例,基类 Shape 提供了一个接口 getArea(),在两个派生类 Rectangle 和 Triangle 中分别实现了 getArea():实例#include <iostream> using namespace std; // 基类 class Shape { public: // 提供接口框架的纯虚函数 virtual int getArea() = 0; void setWidth(int w) { width = w; } void setHeight(int h) { height = h; } protected: int width; int height; }; // 派生类 class Rectangle: public Shape { public: int getArea() { return (width * height); } }; class Triangle: public Shape { public: int getArea() { return (width * height)/2; } }; int main(void) { Rectangle Rect; Triangle Tri; Rect.setWidth(5); Rect.setHeight(7); // 输出对象的面积 cout << "Total Rectangle area: " << Rect.getArea() << endl; Tri.setWidth(5); Tri.setHeight(7); // 输出对象的面积 cout << "Total Triangle area: " << Tri.getArea() << endl; return 0; }当上面的代码被编译和执行时,它会产生下列结果:Total Rectangle area: 35Total Triangle area: 17从上面的实例中,我们可以看到一个抽象类是如何定义一个接口 getArea(),两个派生类是如何通过不同的计算面积的算法来实现这个相同的函数。设计策略面向对象的系统可能会使用一个抽象基类为所有的外部应用程序提供一个适当的、通用的、标准化的接口。然后,派生类通过继承抽象基类,就把所有类似的操作都继承下来。c++算法h5.h0a.kyakp44.info量子区分c++c++算法h5.g9z.kyakp22.info量子区分c++c++算法h5.u2l.kyakp44.info量子区分c++c++算法h5.b2z.kyakp55.info量子区分c++c++算法h5.j6b.kyakp66.info量子区分c++c++算法h5.a4b.kyakp77.info量子区分c++c++算法h5.m1p.kyakp88.info量子区分c++c++算法h5.g2a.kyakp99.info量子区分c++c++算法h5.v5i.kyakp11.info量子区分c++c++算法h5.p6u.kyakp33.info量子区分c++c++算法h5.h7b.kyakp00.info量子区分c++c++算法h5.l5a.kyakp22.info量子区分c++c++算法h5.w5s.kyakp44.info量子区分c++c++算法h5.e0k.kyakp55.info量子区分c++c++算法h5.a3j.kyakp99.info量子区分c++c++算法h5.d3r.kyakp77.info量子区分c++c++算法h5.b6x.kyakp66.info量子区分c++c++算法h5.l3q.kyakp88.info量子区分c++c++算法h5.b6p.kyakp99.info量子区分c++c++算法h5.z0f.kyakp11.info量子区分c++c++算法h5.j4p.kyakp55.info量子区分c++c++算法h5.g6j.kyakp22.info量子区分c++c++算法h5.g5e.kyakp33.info量子区分c++c++算法h5.l5j.kyakp55.info量子区分c++c++算法h5.q5c.kyakp44.info量子区分c++c++算法h5.c7x.kyakp66.info量子区分c++c++算法h5.n0y.kyakp77.info量子区分c++c++算法h5.p7v.kyakp99.info量子区分c++c++算法h5.c0k.kyakp44.info量子区分c++c++算法h5.m4n.kyakp22.info量子区分c++c++算法h5.v8e.kyakp33.info量子区分c++c++算法h5.g4u.kyakp44.info量子区分c++c++算法h5.t9g.kyakp55.info量子区分c++c++算法h5.y3j.kyakp66.info量子区分c++c++算法h5.w2x.kyakp11.info量子区分c++c++算法h5.w4q.kyakp88.info量子区分c++c++算法h5.y0y.kyakp99.info量子区分c++c++算法h5.l6e.kyakp00.info量子区分c++c++算法h5.l4b.kyakp11.info量子区分c++c++算法h5.y6b.kyakp22.info量子区分c++c++算法h5.i9w.kyakp77.info量子区分c++c++算法h5.k8b.kyakp33.info量子区分c++c++算法h5.i1a.kyakp55.info量子区分c++c++算法h5.m3v.kyakp66.info量子区分c++c++算法h5.u6v.kyakp77.info量子区分c++c++算法h5.z3n.kyakp44.info量子区分c++c++算法h5.t0w.kyakp11.info量子区分c++c++算法h5.q3o.kyakp99.info量子区分c++c++算法h5.n3f.kyakp88.info量子区分c++c++算法h5.y8p.kyakp11.info量子区分c++c++算法h5.y9w.kyakp00.info量子区分c++c++算法h5.s6i.kyakp33.info量子区分c++c++算法h5.k1u.kyakp44.info量子区分c++c++算法h5.t8l.kyakp55.info量子区分c++c++算法h5.j2l.kyakp77.info量子区分c++c++算法h5.w1r.kyakp66.info量子区分c++c++算法h5.r4a.kyakp77.info量子区分c++c++算法h5.m8a.kyakp99.info量子区分c++c++算法h5.u2r.kyakp88.info量子区分c++c++算法h5.e7r.kyakp00.info量子区分c++c++算法h5.x4p.kyakp11.info量子区分c++c++算法h5.y0j.kyakp33.info量子区分c++c++算法h5.f5p.kyakp66.info量子区分c++c++算法h5.k9p.kyakp55.info量子区分c++c++算法h5.c3m.kyakp55.info量子区分c++c++算法h5.r9j.kyakp77.info量子区分c++c++算法h5.h6e.kyakp00.info量子区分c++c++算法h5.r4d.kyakp33.info量子区分c++c++算法h5.z5t.kyakp00.info量子区分c++c++算法h5.p3x.kyakp99.info量子区分c++c++算法h5.t9i.kyakp66.info量子区分c++c++算法h5.m9w.kyakp11.info量子区分c++c++算法h5.c3e.kyakp00.info量子区分c++c++算法h5.q9r.kyakp77.info量子区分c++c++算法h5.z1p.kyakp66.info量子区分c++c++算法h5.a9n.kyakp22.info量子区分c++c++算法h5.t9g.kyakp77.info量子区分c++c++算法h5.y3s.kyakp22.info量子区分c++c++算法h5.h0x.kyakp99.info量子区分c++c++算法h5.c7r.kyakp99.info量子区分c++c++算法h5.w2y.kyakp00.info量子区分c++c++算法h5.c4m.kyakp44.info量子区分c++c++算法h5.m0i.kyakp55.info量子区分c++c++算法h5.q6z.kyakp44.info量子区分c++c++算法h5.e4e.kyakp66.info量子区分c++c++算法h5.q5u.kyakp33.info量子区分c++c++算法h5.j9w.kyakp99.info量子区分c++c++算法h5.f6x.kyakp11.info量子区分c++c++算法h5.f8c.kyakp44.info量子区分c++c++算法h5.d4q.kyakp44.info量子区分c++c++算法h5.c4c.kyakp88.info量子区分c++c++算法h5.x5u.kyakp33.info量子区分c++c++算法h5.d0p.kyakp00.info量子区分c++c++算法h5.p5a.kyakp66.info量子区分c++c++算法h5.w9f.kyakp22.info量子区分c++c++算法h5.h1z.kyakp55.info量子区分c++c++算法h5.d8f.kyakp33.info量子区分c++c++算法h5.s3k.kyakp55.info量子区分c++c++算法h5.x2y.kyakp88.info量子区分c++c++算法h5.k0u.kyakp33.info量子区分c++c++算法h5.q4k.kyakp22.info量子区分c++c++算法h5.y1l.kyakp33.info量子区分c++c++算法h5.t4m.kyakp88.info量子区分c++c++算法h5.h2u.kyakp44.info量子区分c++c++算法h5.d9e.kyakp33.info量子区分c++c++算法h5.j8l.kyakp00.info量子区分c++c++算法h5.d0m.kyakp99.info量子区分c++c++算法h5.k5x.kyakp55.info量子区分c++c++算法h5.x3i.kyakp22.info量子区分c++c++算法h5.u1a.kyakp77.info量子区分c++c++算法h5.a7y.kyakp11.info量子区分c++c++算法h5.b7b.kyakp00.info量子区分c++c++算法h5.c9w.kyakp00.info量子区分c++c++算法h5.v0g.kyakp88.info量子区分c++c++算法h5.d1w.kyakp99.info量子区分c++c++算法h5.h7c.kyakp55.info量子区分c++c++算法h5.o0i.kyakp44.info量子区分c++c++算法h5.z4s.kyakp88.info量子区分c++c++算法h5.e2f.kyakp88.info量子区分c++c++算法h5.v7e.kyakp33.info量子区分c++c++算法h5.w3g.kyakp00.info量子区分c++c++算法h5.o8e.kyakp99.info量子区分c++c++算法h5.v8b.kyakp22.info量子区分c++c++算法h5.n0l.kyakp11.info量子区分c++c++算法h5.a7n.kyakp66.info量子区分c++c++算法h5.m6y.kyakp88.info量子区分c++c++算法h5.y5p.kyakp66.info量子区分c++c++算法h5.u8v.kyakp11.info量子区分c++c++算法h5.r3j.kyakp88.info量子区分c++c++算法h5.f4e.kyakp99.info量子区分c++c++算法h5.w1u.kyakp22.info量子区分c++c++算法h5.j7x.kyakp11.info量子区分c++c++算法h5.m4n.kyakp00.info量子区分c++c++算法h5.t1f.kyakp66.info量子区分c++c++算法h5.q3t.kyakp22.info量子区分c++c++算法h5.j0e.kyakp99.info量子区分c++c++算法h5.u2r.kyakp22.info量子区分c++c++算法h5.m7z.kyakp00.info量子区分c++c++算法h5.z8t.kyakp77.info量子区分c++c++算法h5.z4a.kyakp88.info量子区分c++c++算法h5.o9m.kyakp66.info量子区分c++c++算法h5.f3p.kyakp55.info量子区分c++c++算法h5.z0h.kyakp00.info量子区分c++c++算法h5.y3b.kyakp88.info量子区分c++c++算法h5.u7z.kyakp88.info量子区分c++c++算法h5.h9l.kyakp55.info量子区分c++c++算法h5.a6k.kyakp77.info量子区分c++c++算法h5.t7u.kyakp22.info量子区分c++c++算法h5.c8o.kyakp44.info量子区分c++c++算法h5.a3a.kyakp33.info量子区分c++c++算法h5.t4w.kyakp88.info量子区分c++c++算法h5.v5y.kyakp44.info量子区分c++c++算法h5.u1i.kyakp33.info量子区分c++c++算法h5.h1i.kyakp88.info量子区分c++c++算法h5.u6y.kyakp11.info量子区分c++c++算法h5.a1a.kyakp33.info量子区分c++c++算法h5.i0s.kyakp99.info量子区分c++c++算法h5.z5j.kyakp11.info量子区分c++c++算法h5.d2e.kyakp44.info量子区分c++c++算法h5.v7i.kyakp99.info量子区分c++c++算法h5.n8g.kyakp33.info量子区分c++c++算法h5.c1k.kyakp22.info量子区分c++c++算法h5.z2m.kyakp44.info量子区分c++c++算法h5.l2m.kyakp99.info量子区分c++c++算法h5.l0s.kyakp22.info量子区分c++c++算法h5.n0r.kyakp22.info量子区分c++c++算法h5.g6n.kyakp77.info量子区分c++c++算法h5.d9j.kyakp11.info量子区分c++c++算法h5.q9i.kyakp88.info量子区分c++c++算法h5.m5s.kyakp11.info量子区分c++c++算法h5.o9p.kyakp88.info量子区分c++c++算法h5.l6j.kyakp44.info量子区分c++c++算法h5.p4p.kyakp00.info量子区分c++c++算法h5.p8l.kyakp44.info量子区分c++c++算法h5.o4m.kyakp55.info量子区分c++c++算法h5.w4i.kyakp33.info量子区分c++c++算法h5.f5m.kyakp44.info量子区分c++c++算法h5.c2m.kyakp99.info量子区分c++c++算法h5.n2w.kyakp77.info量子区分c++c++算法h5.p7b.kyakp22.info量子区分c++c++算法h5.y0c.kyakp99.info量子区分c++c++算法h5.j6d.kyakp66.info量子区分c++c++算法h5.x7y.kyakp33.info量子区分c++c++算法h5.a6l.kyakp55.info量子区分c++c++算法h5.m2d.kyakp88.info量子区分c++c++算法h5.f6a.kyakp00.info量子区分c++c++算法h5.d6m.kyakp11.info量子区分c++c++算法h5.n6c.kyakp77.info量子区分c++c++算法h5.v7c.kyakp44.info量子区分c++c++算法h5.p9v.kyakp22.info量子区分c++c++算法h5.m1n.kyakp00.info量子区分c++c++算法h5.u3n.kyakp22.info量子区分c++c++算法h5.b9u.kyakp88.info量子区分c++c++算法h5.z5e.kyakp00.info量子区分c++c++算法h5.s4y.kyakp55.info量子区分c++c++算法h5.w1p.kyakp22.info量子区分c++c++算法h5.y4i.kyakp44.info量子区分c++c++算法h5.e8b.kyakp55.info量子区分c++c++算法h5.k2g.kyakp99.info量子区分c++c++算法h5.h9u.kyakp88.info量子区分c++c++算法h5.j9k.kyakp88.info量子区分c++c++算法h5.z7k.kyakp22.info量子区分c++c++算法h5.z8v.kyakp00.info量子区分c++c++算法h5.f5y.kyakp99.info量子区分c++c++算法h5.g6y.kyakp88.info量子区分c++c++算法h5.t9v.kyakp77.info量子区分c++c++算法h5.m5q.kyakp11.info量子区分c++c++算法h5.e2t.kyakp11.info量子区分c++c++算法h5.c6n.kyakp44.info量子区分c++c++算法h5.c7r.kyakp00.info量子区分c++c++算法h5.h8u.kyakp22.info量子区分c++c++算法h5.k6k.kyakp99.info量子区分c++c++算法h5.a2h.kyakp77.info量子区分c++c++算法h5.e1b.kyakp99.info量子区分c++c++算法h5.j2e.kyakp66.info量子区分c++c++算法h5.t2e.kyakp33.info量子区分c++c++算法h5.s3b.kyakp33.info量子区分c++c++算法h5.t9g.kyakp77.info量子区分c++c++算法h5.j7j.kyakp00.info量子区分c++c++算法h5.h1w.kyakp44.info量子区分c++c++算法h5.m9x.kyakp66.info量子区分c++c++算法h5.f7y.kyakp33.info量子区分c++c++算法h5.t4z.kyakp66.info量子区分c++c++算法h5.t4d.kyakp33.info量子区分c++c++算法h5.u4j.kyakp55.info量子区分c++c++算法h5.z4g.kyakp77.info量子区分c++c++算法h5.c2u.kyakp77.info量子区分c++c++算法h5.j5s.kyakp22.info量子区分c++c++算法h5.s5t.kyakp00.info量子区分c++c++算法h5.w7r.kyakp77.info量子区分c++c++算法h5.o7w.kyakp88.info量子区分c++c++算法h5.o3t.kyakp33.info量子区分c++c++算法h5.i8u.kyakp11.info量子区分c++c++算法h5.a4a.kyakp44.info量子区分c++c++算法h5.c4r.kyakp00.info量子区分c++c++算法h5.w4n.kyakp33.info量子区分c++c++算法h5.i1a.kyakp22.info量子区分c++c++算法h5.b3s.kyakp77.info量子区分c++c++算法h5.f3w.kyakp55.info量子区分c++c++算法h5.s5p.kyakp00.info量子区分c++c++算法h5.m2b.kyakp33.info量子区分c++c++算法h5.e5e.kyakp00.info量子区分c++c++算法h5.z8m.kyakp22.info量子区分c++c++算法h5.s7f.kyakp99.info量子区分c++c++算法h5.f2t.kyakp88.info量子区分c++c++算法h5.h0g.kyakp99.info量子区分c++c++算法h5.r4t.kyakp44.info量子区分c++c++算法h5.b8w.kyakp22.info量子区分c++c++算法h5.n9s.kyakp44.info量子区分c++c++算法h5.g1n.kyakp11.info量子区分c++c++算法h5.f3x.kyakp11.info量子区分c++c++算法h5.w2k.kyakp99.info量子区分c++c++算法h5.s8h.kyakp22.info量子区分c++c++算法h5.z7b.kyakp22.info量子区分c++c++算法h5.s8f.kyakp44.info量子区分c++c++算法h5.q4g.kyakp77.info量子区分c++c++算法h5.e4i.kyakp55.info量子区分c++c++算法h5.a1c.kyakp99.info量子区分c++c++算法h5.i7w.kyakp22.info量子区分c++c++算法h5.o1c.kyakp99.info量子区分c++c++算法h5.t6z.kyakp44.info量子区分c++c++算法h5.d0i.kyakp66.info量子区分c++c++算法h5.m1b.kyakp00.info量子区分c++c++算法h5.n5h.kyakp55.info量子区分c++c++算法h5.j6n.kyakp11.info量子区分c++c++算法h5.q8x.kyakp11.info量子区分c++c++算法h5.a7g.kyakp99.info量子区分c++c++算法h5.f3b.kyakp55.info量子区分c++c++算法h5.e3k.kyakp88.info量子区分c++c++算法h5.h4n.kyakp66.info量子区分c++c++算法h5.b8i.kyakp55.info量子区分c++c++算法h5.e6n.kyakp66.info量子区分c++c++算法h5.q4x.kyakp55.info量子区分c++c++算法h5.p2a.kyakp33.info量子区分c++c++算法h5.k4i.kyakp88.info量子区分c++c++算法h5.o8o.kyakp00.info量子区分c++c++算法h5.m5n.kyakp77.info量子区分c++c++算法h5.l1u.kyakp33.info量子区分c++c++算法h5.y7r.kyakp11.info量子区分c++c++算法h5.b3h.kyakp66.info量子区分c++c++算法h5.b7t.kyakp44.info量子区分c++c++算法h5.k0o.kyakp77.info量子区分c++c++算法h5.a2s.kyakp55.info量子区分c++c++算法h5.n0w.kyakp22.info量子区分c++c++算法h5.d3l.kyakp66.info量子区分c++c++算法h5.m3m.kyakp55.info量子区分c++c++算法h5.c8j.kyakp00.info量子区分c++c++算法h5.g0v.kyakp55.info量子区分c++c++算法h5.f8k.kyakp99.info量子区分c++c++算法h5.b6g.kyakp33.info量子区分c++c++算法h5.k2b.kyakp22.info量子区分c++c++算法h5.v1v.kyakp55.info量子区分c++c++算法h5.h1y.kyakp77.info量子区分c++c++算法h5.r2u.kyakp44.info量子区分c++c++算法h5.c2f.kyakp88.info量子区分c++c++算法h5.e3k.kyakp00.info量子区分c++c++算法h5.n1k.kyakp88.info量子区分c++c++算法h5.j4y.kyakp99.info量子区分c++c++算法h5.t9u.kyakp11.info量子区分c++c++算法h5.v8i.kyakp88.info量子区分c++c++算法h5.c4c.kyakp99.info量子区分c++c++算法h5.q3d.kyakp55.info量子区分c++c++算法h5.x5w.kyakp33.info量子区分c++c++算法h5.x4i.kyakp66.info量子区分c++c++算法h5.k4u.kyakp88.info量子区分c++c++算法h5.d6r.kyakp99.info量子区分c++c++算法h5.q0j.kyakp00.info量子区分c++c++算法h5.p4a.kyakp00.info量子区分c++c++算法h5.j6e.kyakp66.info量子区分c++c++算法h5.s3k.kyakp55.info量子区分c++c++算法h5.b6y.kyakp11.info量子区分c++c++算法h5.k7d.kyakp22.info量子区分c++c++算法h5.r9o.kyakp11.info量子区分c++c++算法h5.f2o.kyakp33.info量子区分c++c++算法h5.d0t.kyakp99.info量子区分c++c++算法h5.c4j.kyakp77.info量子区分c++c++算法h5.g1j.kyakp00.info量子区分c++c++算法h5.h3u.kyakp99.info量子区分c++c++算法h5.i0j.kyakp55.info量子区分c++c++算法h5.l2k.kyakp44.info量子区分c++c++算法h5.n1g.kyakp22.info量子区分c++c++算法h5.p4z.kyakp66.info量子区分c++c++算法h5.t1g.kyakp44.info量子区分c++c++算法h5.m0a.kyakp66.info量子区分c++c++算法h5.n6i.kyakp44.info量子区分c++c++算法h5.s9c.kyakp99.info量子区分c++c++算法h5.d1y.kyakp00.info量子区分c++c++算法h5.d1f.kyakp66.info量子区分c++c++算法h5.n0r.kyakp66.info量子区分c++c++算法h5.w1p.kyakp55.info量子区分c++c++算法h5.i5w.kyakp33.info量子区分c++c++算法h5.v6p.kyakp22.info量子区分c++c++算法h5.g7t.kyakp44.info量子区分c++c++算法h5.e7n.kyakp00.info量子区分c++c++算法h5.e6p.kyakp22.info量子区分c++c++算法h5.j3h.kyakp66.info量子区分c++c++算法h5.w1v.kyakp66.info量子区分c++c++算法h5.n3r.kyakp00.info量子区分c++c++算法h5.t0a.kyakp33.info量子区分c++c++算法h5.v3k.kyakp88.info量子区分c++c++算法h5.e2s.kyakp55.info量子区分c++c++算法h5.r0k.kyakp66.info量子区分c++c++算法h5.x1s.kyakp88.info量子区分c++c++算法h5.u5q.kyakp77.info量子区分c++c++算法h5.f0i.kyakp44.info量子区分c++c++算法h5.b0g.kyakp88.info量子区分c++c++算法h5.e8i.kyakp44.info量子区分c++c++算法h5.p2x.kyakp44.info量子区分c++c++算法h5.e4p.kyakp00.info量子区分c++c++算法h5.l0x.kyakp55.info量子区分c++c++算法h5.y4z.kyakp88.info量子区分c++c++算法h5.y0t.kyakp44.info量子区分c++c++算法h5.q8a.kyakp88.info量子区分c++c++算法h5.m8a.kyakp77.info量子区分c++c++算法h5.s3x.kyakp99.info量子区分c++c++算法h5.m1i.kyakp55.info量子区分c++c++算法h5.v5i.kyakp00.info量子区分c++c++算法h5.g2f.kyakp66.info量子区分c++c++算法h5.z5u.kyakp33.info量子区分c++c++算法h5.u2s.kyakp55.info量子区分c++c++算法h5.u0e.kyakp77.info量子区分c++c++算法h5.z3y.kyakp88.info量子区分c++c++算法h5.a4j.kyakp99.info量子区分c++c++算法h5.t6x.kyakp00.info量子区分c++c++算法h5.o9b.kyakp22.info量子区分c++c++算法h5.y1c.kyakp11.info量子区分c++c++算法h5.k3e.kyakp33.info量子区分c++c++算法h5.l5f.kyakp44.info量子区分c++c++算法h5.g6u.kyakp55.info量子区分c++c++算法h5.a0p.kyakp66.info量子区分c++c++算法h5.i8p.kyakp66.info量子区分c++c++算法h5.f4n.kyakp11.info量子区分c++c++算法h5.r8s.kyakp77.info量子区分c++c++算法h5.m0v.kyakp00.info量子区分c++c++算法h5.l3w.kyakp99.info量子区分c++c++算法h5.u4r.kyakp11.info量子区分c++c++算法h5.p3e.kyakp22.info量子区分c++c++算法h5.l2g.kyakp33.info量子区分c++c++算法h5.j1r.kyakp33.info量子区分c++c++算法h5.w8n.kyakp55.info量子区分c++c++算法h5.e2t.kyakp00.info量子区分c++c++算法h5.w1w.kyakp66.info量子区分c++c++算法h5.z5c.kyakp77.info量子区分c++c++算法h5.u0b.kyakp88.info量子区分c++c++算法h5.a4y.kyakp00.info量子区分c++c++算法h5.w9x.kyakp11.info量子区分c++c++算法h5.a2s.kyakp22.info量子区分c++c++算法h5.f5u.kyakp33.info量子区分c++c++算法h5.e7d.kyakp44.info量子区分c++c++算法h5.w4k.kyakp00.info量子区分c++c++算法h5.r4n.kyakp55.info量子区分c++c++算法h5.r3w.kyakp22.info量子区分c++c++算法h5.i3q.kyakp77.info量子区分c++c++算法h5.k9j.kyakp88.info量子区分c++c++算法h5.s2x.kyakp99.info量子区分c++c++算法h5.v8f.kyakp11.info量子区分c++c++算法h5.z0v.kyakp00.info量子区分c++c++算法h5.r7f.kyakp33.info量子区分c++c++算法h5.x0s.kyakp22.info量子区分c++c++算法h5.f0e.kyakp55.info量子区分c++c++算法h5.d1j.kyakp44.info量子区分c++c++算法h5.s8y.kyakp66.info量子区分c++c++算法h5.q1n.kyakp77.info量子区分c++c++算法h5.e8e.kyakp00.info量子区分c++c++算法h5.y9c.kyakp11.info量子区分c++c++算法h5.b5o.kyakp77.info量子区分c++c++算法h5.r7v.kyakp22.info量子区分c++c++算法h5.t0r.kyakp44.info量子区分c++c++算法h5.h0q.kyakp33.info量子区分c++c++算法h5.z9l.kyakp44.info量子区分c++c++算法h5.r3m.kyakp55.info量子区分c++c++算法h5.q1k.kyakp66.info量子区分c++c++算法h5.r8m.kyakp77.info量子区分c++c++算法h5.y2z.kyakp22.info量子区分c++c++算法h5.z9i.kyakp99.info量子区分c++c++算法h5.t3a.kyakp00.info量子区分c++c++算法h5.n3k.kyakp55.info量子区分c++c++算法h5.z1w.kyakp11.info量子区分c++c++算法h5.g8j.kyakp33.info量子区分c++c++算法h5.k8p.kyakp44.info量子区分c++c++算法h5.o1p.kyakp55.info量子区分c++c++算法h5.u1u.kyakp66.info量子区分c++c++算法h5.s8p.kyakp77.info量子区分c++c++算法h5.k4z.kyakp00.info量子区分c++c++算法h5.k3d.kyakp99.info量子区分c++c++算法h5.g1w.kyakp99.info量子区分c++c++算法h5.y7u.kyakp22.info量子区分c++c++算法h5.j4p.kyakp88.info量子区分c++c++算法h5.g3s.kyakp77.info量子区分c++c++算法h5.v8x.kyakp44.info量子区分c++c++算法h5.u4j.kyakp55.info量子区分c++c++算法h5.f2e.kyakp66.info量子区分c++c++算法h5.w2q.kyakp77.info量子区分c++c++算法h5.u1y.kyakp11.info量子区分c++c++算法h5.a7c.kyakp66.info量子区分c++c++算法h5.k3n.kyakp99.info量子区分c++c++算法h5.j0d.kyakp33.info量子区分c++c++算法h5.k2k.kyakp55.info量子区分c++c++算法h5.y5j.kyakp77.info量子区分c++c++算法h5.t7q.kyakp33.info量子区分c++c++算法h5.b1e.kyakp33.info量子区分c++c++算法h5.k6b.kyakp11.info量子区分c++c++算法h5.y5i.kyakp88.info量子区分c++c++算法h5.p8x.kyakp99.info量子区分c++c++算法h5.j0e.kyakp88.info量子区分c++c++算法h5.c6m.kyakp00.info量子区分c++c++算法h5.o1t.kyakp00.info量子区分c++c++算法h5.k6n.kyakp00.info量子区分c++c++算法h5.j1z.kyakp99.info量子区分c++c++算法h5.k5o.kyakp11.info量子区分c++c++算法h5.x7r.kyakp22.info量子区分c++c++算法h5.j1j.kyakp11.info量子区分c++c++算法h5.j6o.kyakp11.info量子区分c++c++算法h5.l3e.kyakp33.info量子区分c++c++算法h5.v7y.kyakp00.info量子区分c++c++算法h5.r5s.kyakp77.info量子区分c++c++算法h5.h6w.kyakp77.info量子区分c++c++算法h5.x0o.kyakp99.info量子区分c++c++算法h5.b9w.kyakp88.info量子区分c++c++算法h5.y2v.kyakp22.info量子区分c++c++算法h5.f8m.kyakp11.info量子区分c++c++算法h5.x1x.kyakp66.info量子区分c++c++算法h5.y8d.kyakp33.info量子区分c++c++算法h5.h7v.kyakp99.info量子区分c++c++算法h5.x0g.kyakp66.info量子区分c++c++算法h5.o6x.kyakp99.info量子区分c++c++算法h5.h9v.kyakp22.info量子区分c++c++算法h5.p6u.kyakp99.info量子区分c++c++算法h5.e1s.kyakp77.info量子区分c++c++算法h5.s3x.kyakp44.info量子区分c++c++算法h5.v8l.kyakp44.info量子区分c++c++算法h5.p8u.kyakp66.info量子区分c++c++算法h5.w3k.kyakp44.info量子区分c++c++算法h5.l1j.kyakp88.info量子区分c++c++算法h5.w5i.kyakp00.info量子区分c++c++算法h5.e6u.kyakp00.info量子区分c++c++算法h5.g8q.kyakp33.info量子区分c++c++算法h5.w5l.kyakp33.info量子区分c++c++算法h5.e6p.kyakp11.info量子区分c++c++算法h5.v5n.kyakp11.info量子区分c++c++算法h5.o6g.kyakp11.info量子区分c++c++算法h5.y0u.kyakp11.info量子区分c++c++算法h5.w0a.kyakp55.info量子区分c++c++算法h5.h0p.kyakp55.info量子区分c++c++算法h5.y3b.kyakp55.info量子区分c++c++算法h5.y1z.kyakp99.info量子区分c++c++算法h5.z1m.kyakp00.info量子区分c++c++算法h5.l6p.kyakp77.info量子区分c++c++算法h5.g4c.kyakp33.info量子区分c++c++算法h5.l1f.kyakp88.info量子区分c++c++算法h5.u2r.kyakp11.info量子区分c++c++算法h5.i3n.kyakp22.info量子区分c++c++算法h5.v7k.kyakp22.info量子区分c++c++算法h5.n5c.kyakp88.info量子区分c++c++算法h5.a3e.kyakp99.info量子区分c++c++算法h5.d8n.kyakp33.info量子区分c++c++算法h5.l1j.kyakp77.info量子区分c++c++算法h5.j4t.kyakp00.info量子区分c++c++算法h5.d3b.kyakp33.info量子区分c++ 外部应用程序提供的功能(即公有函数)在抽象基类中是以纯虚函数的形式存在的。这些纯虚函数在相应的派生类中被实现。这个架构也使得新的应用程序可以很容易地被添加到系统中,即使是在系统被定义之后依然可以如此。————————————————版权声明:本文为CSDN博主「2501_94141583」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/2501_94141583/article/details/154576668
-
概述本部分介绍Linux系统中用于查看、编辑和处理文件内容的命令。这些命令是文本处理、日志分析和文件操作的核心工具,掌握它们对于系统管理和开发工作至关重要。cat - 显示文件内容命令语法cat [选项] [文件…]AI写代码bash1功能说明连接文件并显示内容到标准输出。常用参数-n: 显示行号-b: 只对非空行显示行号-s: 压缩连续的空行-A: 显示所有控制字符-T: 显示制表符为^I实际案例显示文件内容cat file.txt显示行号cat -n file.txt显示多个文件cat file1.txt file2.txt显示所有字符cat -A file.txt压缩空行cat -s file.txtAI写代码bash1234567891011121314执行结果$ cat -n file.txt1 Hello World2 This is line 23 This is line 3AI写代码bash1234详细解析cat命令是最基础的文件查看命令,适合查看小文件。对于大文件建议使用less或more命令。tac - 反向显示文件命令语法tac [选项] [文件…]AI写代码bash1功能说明反向显示文件内容(cat的反向)。常用参数-b: 在行前添加分隔符-r: 将分隔符作为正则表达式-s: 使用指定字符串作为分隔符实际案例反向显示文件tac file.txt反向显示多个文件tac file1.txt file2.txt使用分隔符tac -s “—” file.txtAI写代码bash12345678执行结果$ tac file.txtThis is line 3This is line 2Hello WorldAI写代码bash1234详细解析tac命令将文件内容按行反向显示,常用于查看日志文件的最后几行。less - 分页查看文件命令语法less [选项] [文件…]AI写代码bash1功能说明分页显示文件内容,支持向前向后浏览。常用参数-N: 显示行号-S: 不换行显示长行-i: 忽略大小写搜索-F: 如果文件只有一屏则直接退出实际案例分页查看文件less file.txt显示行号less -N file.txt不换行显示less -S file.txt忽略大小写搜索less -i file.txtAI写代码bash1234567891011执行结果$ less file.txtHello WorldThis is line 2This is line 3(END)AI写代码bash12345详细解析less命令是查看大文件的最佳选择,支持搜索、跳转等操作。常用快捷键:空格键:向下翻页b:向上翻页/:搜索q:退出4. more - 分页查看文件命令语法more [选项] [文件…]AI写代码bash1功能说明分页显示文件内容,只能向前浏览。常用参数-d: 显示帮助信息-f: 不折叠长行-l: 不暂停在换页符-p: 清屏后显示实际案例分页查看文件more file.txt显示帮助信息more -d file.txt不折叠长行more -f file.txt清屏显示more -p file.txtAI写代码bash1234567891011执行结果$ more file.txtHello WorldThis is line 2This is line 3–More–(25%)AI写代码bash12345详细解析more命令比less简单,但功能较少。现在更推荐使用less命令。head - 查看文件开头命令语法head [选项] [文件…]AI写代码bash1功能说明显示文件的前几行。常用参数-n: 指定显示行数-c: 指定显示字节数-q: 不显示文件名-v: 显示文件名实际案例显示前10行head file.txt显示前5行head -n 5 file.txt显示前100字节head -c 100 file.txt显示多个文件head file1.txt file2.txtAI写代码bash1234567891011执行结果$ head -n 3 file.txtHello WorldThis is line 2This is line 3AI写代码bash1234详细解析head命令默认显示前10行,常用于查看文件的开头部分。tail - 查看文件结尾命令语法tail [选项] [文件…]AI写代码bash1功能说明显示文件的最后几行。常用参数-n: 指定显示行数-c: 指定显示字节数-f: 实时跟踪文件变化-F: 跟踪文件变化,文件被删除后重新打开实际案例显示最后10行tail file.txt显示最后5行tail -n 5 file.txt实时跟踪日志tail -f /var/log/syslog跟踪文件变化tail -F logfile.txtAI写代码bash1234567891011执行结果$ tail -n 3 file.txtThis is line 8This is line 9This is line 10AI写代码bash1234详细解析tail命令是查看日志文件的常用工具,-f参数可以实时监控文件变化。grep - 文本搜索命令语法grep [选项] 模式 [文件…]AI写代码bash1功能说明在文件中搜索匹配的文本行。常用参数-i: 忽略大小写-v: 显示不匹配的行-n: 显示行号-r: 递归搜索目录-l: 只显示文件名-c: 只显示匹配行数实际案例搜索文本grep “hello” file.txt忽略大小写搜索grep -i “HELLO” file.txt显示行号grep -n “hello” file.txt递归搜索grep -r “hello” /home/user/显示不匹配的行grep -v “hello” file.txtAI写代码bash1234567891011121314执行结果$ grep -n “hello” file.txt1:Hello World5:hello thereAI写代码bash123详细解析grep是Linux中最强大的文本搜索工具,支持正则表达式,是日志分析和文本处理的核心命令。egrep - 扩展grep命令语法egrep [选项] 模式 [文件…]AI写代码bash1功能说明使用扩展正则表达式的grep。常用参数与grep相同,但支持扩展正则表达式。实际案例使用扩展正则表达式egrep “hello|world” file.txt搜索多个模式egrep “(error|warning)” logfile.txt使用量词egrep “go{2,4}d” file.txtAI写代码bash12345678执行结果$ egrep “hello|world” file.txtHello Worldhello thereAI写代码bash123详细解析egrep等同于grep -E,支持扩展正则表达式,包括|、+、?、{}等元字符。fgrep - 固定字符串grep命令语法fgrep [选项] 字符串 [文件…]AI写代码bash1功能说明搜索固定字符串,不解释正则表达式。常用参数与grep相同,但将模式作为固定字符串处理。实际案例搜索固定字符串fgrep “hello.world” file.txt搜索特殊字符fgrep “*.txt” file.txtAI写代码bash12345执行结果$ fgrep “hello.world” file.txthello.world is a domainAI写代码bash12详细解析fgrep等同于grep -F,将搜索模式作为固定字符串处理,不解释正则表达式。rgrep - 递归grep命令语法rgrep [选项] 模式 [目录…]AI写代码bash1功能说明递归搜索目录中的文件。常用参数与grep相同,但默认递归搜索。实际案例递归搜索rgrep “hello” /home/user/递归搜索并显示行号rgrep -n “hello” /home/user/AI写代码bash12345执行结果$ rgrep “hello” /home/user//home/user/file1.txt:Hello World/home/user/documents/file2.txt:hello thereAI写代码bash123详细解析rgrep等同于grep -r,递归搜索指定目录及其子目录中的文件。sed - 流编辑器命令语法sed [选项] 命令 [文件…]AI写代码bash1功能说明流编辑器,用于文本替换、删除、插入等操作。常用参数-i: 直接修改文件-n: 只显示处理后的行-e: 执行多个命令-f: 从文件读取命令实际案例替换文本sed ‘s/old/new/g’ file.txt删除行sed ‘2d’ file.txt插入行sed ‘2i\New line’ file.txt直接修改文件sed -i ‘s/old/new/g’ file.txt执行多个命令sed -e ‘s/old/new/g’ -e ‘2d’ file.txtAI写代码bash1234567891011121314执行结果$ sed ‘s/old/new/g’ file.txtHello new WorldThis is new lineAI写代码bash123详细解析sed是强大的流编辑器,支持复杂的文本处理操作,常用于批量文本替换。awk - 文本处理工具命令语法awk [选项] ‘程序’ [文件…]AI写代码bash1功能说明强大的文本处理和数据提取工具。常用参数-F: 指定字段分隔符-v: 定义变量-f: 从文件读取程序实际案例打印第一列awk ‘{print $1}’ file.txt使用逗号分隔符awk -F’,’ ‘{print $1, $3}’ file.txt条件过滤awk ‘$3 > 100 {print $1, $3}’ file.txt计算总和awk ‘{sum += $1} END {print sum}’ file.txt使用变量awk -v var=10 ‘{print $1 + var}’ file.txtAI写代码bash1234567891011121314执行结果$ awk ‘{print $1}’ file.txtHelloThisAnotherAI写代码bash1234详细解析awk是强大的文本处理工具,支持字段操作、条件判断、循环等,是数据分析的重要工具。gawk - GNU awk命令语法gawk [选项] ‘程序’ [文件…]AI写代码bash1功能说明GNU版本的awk,功能更强大。常用参数与awk相同,但支持更多功能。实际案例使用GNU扩展功能gawk ‘{print length($0)}’ file.txt使用内置函数gawk ‘{print toupper($1)}’ file.txt使用数组gawk '{count[1]++} END {for (i in count) print i, count[i]}' file.txt AI写代码 bash 1 2 3 4 5 6 7 8 执行结果 gawk ‘{print length($0)}’ file.txt111512AI写代码bash1234详细解析gawk是awk的GNU实现,支持更多内置函数和扩展功能。mawk - 快速awk命令语法mawk [选项] ‘程序’ [文件…]AI写代码bash1功能说明快速版本的awk实现。常用参数与awk相同,但执行速度更快。实际案例快速处理大文件mawk ‘{print $1}’ largefile.txt快速计算mawk '{sum += 1} END {print sum}' data.txt AI写代码 bash 1 2 3 4 5 执行结果 mawk ‘{print $1}’ file.txtHelloThisAnotherAI写代码bash1234详细解析mawk是awk的快速实现,适合处理大文件,但功能相对较少。nano - 简单文本编辑器命令语法nano [选项] [文件…]AI写代码bash1功能说明简单易用的文本编辑器。常用参数-w: 不自动换行-T: 设置制表符宽度-c: 显示行号实际案例编辑文件nano file.txt不自动换行nano -w file.txt显示行号nano -c file.txt设置制表符宽度nano -T 4 file.txtAI写代码bash1234567891011执行结果$ nano file.txt打开nano编辑器界面AI写代码bash12详细解析nano是初学者友好的文本编辑器,界面简单,快捷键显示在底部。vi - 文本编辑器命令语法vi [选项] [文件…]AI写代码bash1功能说明经典的文本编辑器。常用参数+: 启动时执行命令-R: 只读模式-c: 启动时执行命令实际案例编辑文件vi file.txt只读模式vi -R file.txt启动时跳转到指定行vi +10 file.txt启动时执行命令vi -c “set number” file.txtAI写代码bash1234567891011执行结果$ vi file.txt打开vi编辑器界面AI写代码bash12详细解析vi是经典的文本编辑器,有两种模式:命令模式和插入模式。vim - 改进的vi命令语法vim [选项] [文件…]AI写代码bash1功能说明vi的改进版本,功能更强大。常用参数+: 启动时执行命令-R: 只读模式-c: 启动时执行命令-o: 水平分割窗口-O: 垂直分割窗口实际案例编辑文件vim file.txt水平分割编辑多个文件vim -o file1.txt file2.txt垂直分割编辑多个文件vim -O file1.txt file2.txt启动时跳转到指定行vim +10 file.txtAI写代码bash1234567891011执行结果$ vim file.txt打开vim编辑器界面AI写代码bash12详细解析vim是vi的改进版本,支持语法高亮、多窗口、插件等高级功能。emacs - 文本编辑器命令语法emacs [选项] [文件…]AI写代码bash1功能说明功能强大的文本编辑器。常用参数-nw: 不使用图形界面-q: 不加载初始化文件-batch: 批处理模式实际案例编辑文件emacs file.txt不使用图形界面emacs -nw file.txt不加载初始化文件emacs -q file.txt批处理模式emacs -batch -l script.elAI写代码bash1234567891011执行结果$ emacs file.txt打开emacs编辑器界面AI写代码bash12详细解析emacs是功能强大的文本编辑器,支持Lisp扩展,可以配置成IDE。ed - 行编辑器命令语法ed [选项] [文件…]AI写代码bash1功能说明经典的行编辑器。常用参数-p: 设置提示符-s: 静默模式-v: 详细模式实际案例编辑文件ed file.txt设置提示符ed -p "> " file.txt静默模式ed -s file.txtAI写代码bash12345678执行结果$ ed file.txt打开ed编辑器界面AI写代码bash12详细解析ed是最早的行编辑器,现在很少使用,但了解它有助于理解vi的历史。ex - 行编辑器命令语法ex [选项] [文件…]AI写代码bash1功能说明vi的前身,行编辑器。常用参数与vi相同。实际案例编辑文件ex file.txt只读模式ex -R file.txtAI写代码bash12345执行结果$ ex file.txt打开ex编辑器界面AI写代码bash12详细解析ex是vi的前身,现在很少直接使用,但vi的命令模式就是基于ex的。rev - 反转行内容命令语法rev [文件…]AI写代码bash1功能说明反转每行字符的顺序。常用参数无特殊参数。实际案例反转文件内容rev file.txt反转多个文件rev file1.txt file2.txtAI写代码bash12345执行结果$ rev file.txtdlroW olleH2 enil si sihT3 enil si sihTAI写代码bash1234详细解析rev命令将每行的字符顺序反转,常用于文本处理。column - 格式化列输出命令语法column [选项] [文件…]AI写代码bash1功能说明将输入格式化为列输出。常用参数-t: 创建表格-s: 指定分隔符-c: 指定列宽实际案例格式化列输出column file.txt创建表格column -t file.txt使用指定分隔符column -s ‘,’ file.txt指定列宽column -c 80 file.txtAI写代码bash1234567891011执行结果$ column -t file.txtHello WorldThis is line 2This is line 3AI写代码bash1234详细解析column命令将输入格式化为整齐的列输出,便于阅读。fmt - 格式化文本命令语法fmt [选项] [文件…]AI写代码bash1功能说明格式化文本段落。常用参数-w: 设置行宽-u: 统一空格-s: 只分割长行实际案例格式化文本fmt file.txt设置行宽fmt -w 60 file.txt统一空格fmt -u file.txt只分割长行fmt -s file.txtAI写代码bash1234567891011执行结果$ fmt -w 40 file.txtHello World This is a long linethat will be wrapped to fitwithin the specified width.AI写代码bash1234详细解析fmt命令用于格式化文本段落,调整行宽和空格。fold - 折叠长行命令语法fold [选项] [文件…]AI写代码bash1功能说明将长行折叠到指定宽度。常用参数-w: 设置行宽-s: 在空格处折叠-b: 按字节计算宽度实际案例折叠长行fold file.txt设置行宽fold -w 40 file.txt在空格处折叠fold -s -w 40 file.txt按字节计算fold -b -w 40 file.txtAI写代码bash1234567891011执行结果$ fold -w 20 file.txtHello World This isa long line thatwill be foldedAI写代码bash1234详细解析fold命令将长行折叠到指定宽度,保持文本的可读性。pr - 格式化打印命令语法pr [选项] [文件…]AI写代码bash1功能说明格式化文件用于打印。常用参数-h: 设置页眉-l: 设置页长-w: 设置行宽-c: 设置列数实际案例格式化打印pr file.txt设置页眉pr -h “My Document” file.txt设置页长pr -l 50 file.txt设置列数pr -c 2 file.txtAI写代码bash1234567891011执行结果$ pr file.txt2023-12-15 10:30 file.txt Page 1Hello WorldThis is line 2This is line 3AI写代码bash123456详细解析pr命令格式化文件用于打印,添加页眉、页脚和分页符。nl - 添加行号命令语法nl [选项] [文件…]AI写代码bash1功能说明为文件添加行号。常用参数-b: 设置行号样式-n: 设置行号格式-w: 设置行号宽度-s: 设置行号分隔符实际案例添加行号nl file.txt设置行号样式nl -b a file.txt设置行号格式nl -n ln file.txt设置行号宽度nl -w 3 file.txt设置分隔符nl -s ": " file.txtAI写代码bash1234567891011121314执行结果$ nl file.txt1 Hello World2 This is line 23 This is line 3AI写代码bash1234详细解析nl命令为文件添加行号,支持多种行号样式和格式。wc - 统计行数/字数命令语法wc [选项] [文件…]AI写代码bash1功能说明统计文件的行数、字数和字符数。常用参数-l: 只统计行数-w: 只统计字数-c: 只统计字符数-m: 只统计字符数(多字节字符)实际案例统计所有信息wc file.txt只统计行数wc -l file.txt只统计字数wc -w file.txt只统计字符数wc -c file.txt统计多个文件wc file1.txt file2.txtAI写代码bash1234567891011121314执行结果$ wc file.txt3 9 45 file.txtAI写代码bash12详细解析wc命令显示文件的行数、字数和字符数,输出格式为:行数 字数 字符数 文件名。sort - 排序命令语法sort [选项] [文件…]AI写代码bash1功能说明对文件内容进行排序。常用参数-r: 反向排序-n: 按数值排序-k: 指定排序字段-u: 去除重复行-f: 忽略大小写实际案例基本排序sort file.txt反向排序sort -r file.txt按数值排序sort -n numbers.txt指定排序字段sort -k 2 file.txt去除重复行sort -u file.txt忽略大小写sort -f file.txtAI写代码bash1234567891011121314151617执行结果$ sort file.txtAnother lineHello WorldThis is line 2This is line 3AI写代码bash12345详细解析sort命令对文件内容进行排序,支持多种排序方式和字段选择。uniq - 去重命令语法uniq [选项] [输入文件] [输出文件]AI写代码bash1功能说明去除或报告重复行。常用参数-c: 显示重复次数-d: 只显示重复行-u: 只显示唯一行-i: 忽略大小写实际案例去除重复行uniq file.txt显示重复次数uniq -c file.txt只显示重复行uniq -d file.txt只显示唯一行uniq -u file.txt忽略大小写uniq -i file.txtAI写代码bash1234567891011121314执行结果$ uniq -c file.txt2 Hello World1 This is line 21 This is line 3AI写代码bash1234详细解析uniq命令去除重复行,通常与sort命令配合使用。cut - 提取列命令语法cut [选项] [文件…]AI写代码bash1功能说明从文件中提取列。常用参数-c: 按字符位置提取-f: 按字段提取-d: 指定字段分隔符实际案例按字符位置提取cut -c 1-10 file.txt按字段提取cut -f 1,3 file.txt使用指定分隔符cut -d ‘,’ -f 1,3 file.txt提取多个字段cut -f 1-3 file.txtAI写代码bash1234567891011执行结果$ cut -f 1 file.txtHelloThisAnother详细解析cut命令从文件中提取指定的列,支持按字符位置和字段提取。总结本部分介绍了Linux系统中用于文件内容查看和编辑的核心命令。这些命令是文本处理、日志分析和文件操作的基础工具。主要命令分类:文件查看:cat、less、more、head、tail文本搜索:grep、egrep、fgrep、rgrep文本编辑:sed、awk、nano、vi、vim、emacs文本处理:sort、uniq、cut、paste、tr格式化:fmt、fold、column、pr、nl使用建议:查看大文件使用less而不是cat实时监控日志使用tail -f文本搜索使用grep,支持正则表达式复杂文本处理使用awk或sed编辑文件根据熟练程度选择nano、vi或vim文本分析结合sort、uniq、cut等命令这些命令为Linux系统管理和文本处理提供了强大的工具集。————————————————版权声明:本文为CSDN博主「Flying_Fish_Xuan」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/Flying_Fish_roe/article/details/154492357
-
一、引言在前端开发中,Webpack 作为一款强大的模块打包工具,广泛应用于项目的构建过程。然而,随着项目规模的不断扩大,模块数量和复杂度的增加,打包后的文件体积也会相应增大,导致页面加载速度变慢,影响用户体验。因此,对 Webpack 打包进行优化显得尤为重要。本文将详细介绍一些常见的 Webpack 打包优化方法。二、优化打包速度2.1 合理配置 loader减少 loader 应用范围:通过 test 选项精确匹配需要处理的文件类型,避免对不必要的文件应用 loader。例如,对于 css-loader 和 style-loader,只对 .css 文件进行处理:module.exports = { module: { rules: [ { test: /\.css$/, use: ['style-loader', 'css-loader'] } ] }};缓存 loader 结果:一些 loader 支持缓存,如 babel-loader,通过设置 cacheDirectory 选项启用缓存,避免重复编译:module.exports = { module: { rules: [ { test: /\.js$/, use: { loader: 'babel-loader', options: { cacheDirectory: true } } } ] }};2.2 优化 resolve 配置减少 resolve 查找路径:在 resolve.modules 中只配置必要的路径,减少 Webpack 查找模块的时间。例如:module.exports = { resolve: { modules: ['node_modules', path.resolve(__dirname,'src')] }};使用 alias 别名:为常用的模块路径设置别名,加快模块的解析速度。比如:module.exports = { resolve: { alias: { '@': path.resolve(__dirname,'src') } }};这样在代码中 import Component from '@/components/Component.vue'; 就可以快速找到对应的模块。2.3 启用多进程构建使用 thread-loader 等插件,将耗时的 loader 操作分配到多个进程中并行处理,提高打包速度。例如:module.exports = { module: { rules: [ { test: /\.js$/, use: [ 'thread-loader', { loader: 'babel-loader', options: { // babel 配置 } } ] } ] }};三、优化打包体积3.1 代码分割使用 splitChunks:Webpack 的 optimization.splitChunks 可以将公共模块提取出来,避免重复打包。例如:module.exports = { optimization: { splitChunks: { chunks: 'all' } }};这会将所有模块中的公共部分提取到单独的文件中,减少最终打包文件的体积。2. 动态导入:使用 ES2020 的动态导入语法 import(),实现按需加载模块。例如:button.addEventListener('click', () => { import('./module.js').then((module) => { // 使用 module });});这样只有在按钮点击时才会加载 module.js,减小初始加载的文件体积。3.2 压缩代码JavaScript 压缩:Webpack 4 及以上版本默认使用 terser-webpack-plugin 对 JavaScript 代码进行压缩。可以通过配置 terserOptions 来进一步优化压缩效果。例如:module.exports = { optimization: { minimizer: [ new TerserPlugin({ terserOptions: { compress: { drop_console: true // 移除 console.log 等语句 } } }) ] }};CSS 压缩:使用 css-minimizer-webpack-plugin 对 CSS 代码进行压缩。配置如下:const MiniCssExtractPlugin = require('mini-css-extract-plugin');const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');module.exports = { module: { rules: [ { test: /\.css$/, use: [MiniCssExtractPlugin.loader, 'css-loader'] } ] }, optimization: { minimizer: [ new CssMinimizerPlugin() ] }, plugins: [ new MiniCssExtractPlugin() ]};3.3 图片优化压缩图片:使用 image-webpack-loader 对图片进行压缩,减少图片文件的大小。例如:module.exports = { module: { rules: [ { test: /\.(png|jpg|gif)$/, use: [ { loader: 'file-loader', options: { name: 'images/[name].[ext]' } }, { loader: 'image-webpack-loader', options: { mozjpeg: { progressive: true, quality: 65 }, optipng: { enabled: false }, pngquant: { quality: [0.65, 0.90], speed: 4 }, gifsicle: { interlaced: false }, webp: { quality: 75 } } } ] } ] }};使用 SVG 图标:将图标转换为 SVG 格式,SVG 是矢量图,文件体积小且可无损缩放。四、优化开发体验4.1 启用热模块替换(HMR)通过配置 devServer 启用热模块替换,当代码发生变化时,只更新变化的模块,而不是重新加载整个页面。例如:module.exports = { devServer: { hot: true }};4.2 配置 source-map在开发环境中,配置 devtool 选项生成 source-map,方便调试代码。例如:module.exports = { devtool: 'eval-source-map'};不同的 source-map 类型有不同的性能和调试效果,可以根据实际需求选择。五、总结Webpack 打包优化是一个综合性的工作,涉及到打包速度、打包体积和开发体验等多个方面。通过合理配置 loader、优化 resolve、进行代码分割、压缩代码、优化图片以及启用 HMR 和配置 source-map 等方法,可以显著提高 Webpack 的打包效率,减小打包文件体积,提升开发体验,从而为用户提供更快、更流畅的前端应用。在实际项目中,需要根据项目的特点和需求,灵活运用这些优化方法。————————————————版权声明:本文为CSDN博主「阿珊和她的猫」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/weixin_42554191/article/details/154236415
-
,这里面的都是rpm包的文件没有iso镜像文件,有没有打包镜像的指导手册或者这些软件包要怎么打宝成可以安装系统的ISO镜像
-
我在主机集群中添加目标主机后,无法完成连通性测试。失败原因为“主机连接超时”。查看目标主机 SSH 登陆日志,可以看到来自 139.159.226.153 的 SSH登陆已经成功。该 IP 为 cid:link_0 所列的部署服务的对外IP。2025-07-01T17:54:31.715456+08:00 hcss-ecs-4e01 sshd[31899]: Accepted password for root from 139.159.226.153 port 38931 ssh2 2025-07-01T17:54:31.721823+08:00 hcss-ecs-4e01 sshd[31899]: pam_unix(sshd:session): session opened for user root(uid=0) by root(uid=0) 2025-07-01T17:54:31.722117+08:00 hcss-ecs-4e01 systemd-logind[756]: New session 194 of user root.
-
如何支持连接WSL进行开发?添加remote-dev或remote-wsl均不行
-
这里部署失败可以在哪里看到全量的日志吗?cid:link_0CodeArts IDE for java 运行报错cid:link_5codearts Ide 同一目录下多模块,Java智能助手无法识别cid:link_6CodeArts Ide SmartAssist启动失败cid:link_1Astro怎么动态设置工作流标题cid:link_7当前读和快照读有什么区别? cid:link_2MySQL的行级锁锁的到底是什么?cid:link_8InnoDB支持哪几种行格式?cid:link_9InnoDB的一次更新事务是怎么实现的? cid:link_10GaussDB轻量化部署,安装TPOPS平台失败cid:link_11mysql在InnoDB引擎下加索引,这个时候会锁表吗? cid:link_12InnoDB的聚簇索引是按照表的主键创建一个B+树,但是如果我们在表结构中没有定义主键怎么办?cid:link_13mysql中如何减少回表,增加查询的性能?cid:link_14走了索引,但是还是很慢是什么原因?cid:link_3mysql中操作同一条记录会发生死锁吗? cid:link_15数据库如果发生了死锁,该如何解决? cid:link_4
-
上回我们谈到AI模型的两大基石之一,云能力,而云能力分为边缘计算能力和PAAS层中心能力。在咨询项目中,如何构建PAAS层中心能力。从当时地质业务需求来看,中心层能力是大模型计算的核心能力,依赖机房的计算存储平台,大模型可以按需运算并预测结果。 由于部署了台风预测模型,业务侧需要分钟级输出未来30天的预测结果,每分钟计算资源要非常充足。因此,给每个因子每个场景配置了4VPU,128flop/VCPU;由于地质勘查图片量非常大,要一分钟内分析上千份图片,因此计算速度用最快的NPU,9XX型号的算力卡,20张/秒的分析速度,1200张/分钟。有了超级快的计算能力外,还要有海量的存储单元,分为块存储、文件存储和缓存三种类型。其中块存储的空间需求最多,因为它非常灵活,可以存放多种格式的数据;按10M/图片来计算,块存储空间预留500T空间,存储15年的图片数据。 硬件平台讲了这么多,其实都是为PAAS层能力服务。为了让业务侧具备自主编程和调试台风预测模型的能力,PAAS层配备了微服务流水线的能力,codearts, 微服务架构。这也是因为地质行业数据是保密数据,不允许外发到专有云外,因此必须在本地训练。同时业务场景层出不穷,目前只是梳理了5种场景:全球场景、局部场景、自然灾害场景、山体滑坡场景和泥石流场景。未来模型应用的场景会逐步增多,新场景除了模型泛化能力支持外,还要进行算法调优或RAG等技术辅助。欢迎点赞和关注公众号“科技江河”,如果喜欢,在公众号打赏下呗,感谢华为云App
-
首次使用华为云CodeArts时,开发者们总会遇到一些问题,小编针对大家遇到的问题做了分类总结,比如标准页面的表格数据问题、标准页面的表格数据问题、如何在标准页面的事件里面通过JS代码,获得下拉框选择的值?、标准页面的表格数据问题。憋着急!下面小编就来为大家一一解答遇到这几类问题时该如何快速解决,一步解决大家的困扰。 华为云CodeArts系列产品参考手册:1、CodeArts:软件开发平台(CodeArts)官方手册:https://support.huaweicloud.com/devcloud/index.html软件开发平台(CodeArts)相关文章:https://bbs.huaweicloud.com/forum/thread-59032-1-1.html产品官方页面:https://devcloud.cn-north-4.huaweicloud.com/home2、CodeArts项目管理:项目管理(ProjectMan)官方手册:https://support.huaweicloud.com/projectman/index.html项目管理(ProjectMan)更新预览:https://support.huaweicloud.com/wtsnew-projectman/index.html产品官方页面:https://www.huaweicloud.com/product/projectman.html3、低代码平台Astro:应用魔方官方手册:https://support.huaweicloud.com/qs-appcube/appcube_02_0110.html操作指导:https://support.huaweicloud.com/appcube_video/index.html产品官方页面:https://appcube.cn-north-4.huaweicloud.com/studio/index.html#/projects/零代码官方手册:https://support.huaweicloud.com/usermanual-appcube/appcube_05_1404.html问题汇总:(以↓问题都是由官方人员解答后的文章链接)7月:高级页面如何实现数据实时更新 https://bbs.huaweicloud.com/forum/thread-02127156068292491055-1-1.html终端打开后,如何缩放,我看其他ssh工具都有自动缩放功能https://bbs.huaweicloud.com/forum/thread-02127155363552050024-1-1.htmlCodeArts IDE 怎么安装python支持?https://bbs.huaweicloud.com/forum/thread-02127155382761967021-1-1.html希望文件自动自动追踪终端所在目录 https://bbs.huaweicloud.com/forum/thread-02127155476600512035-1-1.html 怎么运行调试https://bbs.huaweicloud.com/forum/thread-0201155524286312029-1-1.html希望后续版本能够支持ruffhttps://bbs.huaweicloud.com/forum/thread-02127155568161998037-1-1.html为什么不能创建新工程,网络也没有问题https://bbs.huaweicloud.com/forum/thread-0217155900141351039-1-1.htmlcodearts Ide 同一目录下多模块启动问题https://bbs.huaweicloud.com/forum/thread-02127155917751440040-1-1.html制品仓上传提示“当前用户可用容量小于文件大小”cid:link_118月:自定义规则语言何时支持鸿蒙开发语言,有没有这块的计划 cid:link_12查询路由器中的各种表cid:link_0建议增加scratch镜像cid:link_1Astro低码是否可以实现以下功能???cid:link_2"405234216","resMsg":"请求资源项: RequestDMLStatementsAmount-每次请求执行数据库DML操作最大次数, 使用量已经达到上限值: 150"cid:link_3匿名登录申请cid:link_139月:CodeArts IDE支持Linux系统不?cid:link_14CodeArts Checkcid:link_4maven在哪配置cid:link_5未发现登录插件,初始化失败cid:link_15创建低代码应用时提示:命名空间'xxx'已被占用cid:link_16脚本里 图片地址如何转成base64 cid:link_1710月:关于codearts中代码修改报错cid:link_18无法在IDE中运行和调试程序cid:link_19CodeArts Modeling 类图创建中 类模块如何表示C++中类的虚拟函数cid:link_20目前CodeArts Snap对于鸿蒙ArkTS的支持情况如何?cid:link_21CodeArts Modeling可真难用,入手门槛太高了,元素间感觉存在太多约束cid:link_22CodeArts IDE没有像pycharm一样的图形包管理界面cid:link_23nvm-windows安装后设置华为源地址问题cid:link_2411月:华为云story导出后,表格上的描述内容没有区分换行符,导致内容描述格式混乱影响查看效率cid:link_25解答cid:link_26新人求解cid:link_27大佬帮忙看看有没有错误cid:link_28大佬些这个可以得吃不cid:link_29流水线构建报错,pip源怎么修改?cid:link_6Astro能否实现统计页作为首页?cid:link_3012月:开源镜像站的maven仓为啥无法打开了?cid:link_31创建一个问题跟踪应用,需要每周填报跟踪进展,如何实现每次跟踪的进展数据都保留且能查看,数据不会被覆盖cid:link_32gs_dump支持多个IP吗 cid:link_7查询分布键的存储位置cid:link_8current:124,max_connections/reserved/service_reserved: 4000/3/10. FATAL: Too many clients alreadycid:link_33update一个很大的表会引发什么问题cid:link_34explain真的靠谱吗?cid:link_9高斯数据库安装直接就是分布式的库吗?cid:link_10Query dialect missing 使用DataQL查询数据,分页查询报方言错误cid:link_35为什么代码规则集不能取消?误触之后几百个问题?烦死了https://bbs.huaweicloud.com/forum/thread-02109169302751190083-1-1.html开源镜像站的maven仓为啥无法打开了?cid:link_31求助!接口测试自带的redisGet关键字如何指定数据库 https://bbs.huaweicloud.com/forum/thread-0276169892704793120-1-1.html------------------------------------------------------------------------------------------------------------------补充:https://bbs.huaweicloud.com/forum/thread-0244154257656850036-1-1.html(1-6月FAQ解答)
-
华为云开发者日·北京站来啦!参加“软件开发生产线CodeArts:云上持续规划与设计实践”体验项目提出你的建议或使用体验有机会获得开发者盲盒礼包惊喜不容错过,快叫上小伙伴一起来参加吧~【体验项目】软件开发生产线CodeArts:云上持续规划与设计实践【活动时间】2024年12月23日-12月31日【参与方式】直接在此活动帖下方回帖提建议/提建议即可比如对产品功能的改进建议、对活动流程的感想、对现场活动的感悟等等PS:不要少于30字哦~【获奖规则】奖项设置有效回复楼层评选条件获奖名额激励礼品优质建议奖20对产品功能有改进价值的建议1名开发者盲盒礼品价值50-100元积极反馈奖20优质建议奖轮空的情况下进行抽取每满20层抽取1名开发者盲盒礼品价值50元【活动规则】1、本帖的回帖建议不少于30字,仅限于对“软件开发生产线CodeArts:云上持续规划与设计实践”体验项目,其他项目建议不参与此次活动,否则将视为无效内容。2、本次活动将根据实际参与情况发放奖励,包括但不限于用户百分之百中奖或奖项轮空的情况;以上奖品均为实物奖品,具体发放视出库情况而定;3、活动预计于结束后七天内完成奖项公示,并于结束后15个工作日内完成邮寄。【温馨提示】1、请务必使用个人实名账号参与活动(IAM、企业账号等账号参与无效)。如一个实名认证对应多个账号,只有一个账号可领取奖励,若同一账号填写多个不同收件人或不同账号填写同一收件人,均不予发放奖励。2、所有获得奖品的获奖用户,请于获奖后3日内完成实名认证,否则视为放弃奖励。
推荐直播
-
HDC深度解读系列 - Serverless与MCP融合创新,构建AI应用全新智能中枢2025/08/20 周三 16:30-18:00
张昆鹏 HCDG北京核心组代表
HDC2025期间,华为云展示了Serverless与MCP融合创新的解决方案,本期访谈直播,由华为云开发者专家(HCDE)兼华为云开发者社区组织HCDG北京核心组代表张鹏先生主持,华为云PaaS服务产品部 Serverless总监Ewen为大家深度解读华为云Serverless与MCP如何融合构建AI应用全新智能中枢
回顾中 -
关于RISC-V生态发展的思考2025/09/02 周二 17:00-18:00
中国科学院计算技术研究所副所长包云岗教授
中科院包云岗老师将在本次直播中,探讨处理器生态的关键要素及其联系,分享过去几年推动RISC-V生态建设实践过程中的经验与教训。
回顾中 -
一键搞定华为云万级资源,3步轻松管理企业成本2025/09/09 周二 15:00-16:00
阿言 华为云交易产品经理
本直播重点介绍如何一键续费万级资源,3步轻松管理成本,帮助提升日常管理效率!
回顾中
热门标签