• 存储服务2024.4月技术干货&资讯合集
    技术干货GaussDB数据量与分区策略分析https://bbs.huaweicloud.com/forum/thread-02106149308401380040-1-1.htmlGaussDB分页查询的实现方法https://bbs.huaweicloud.com/forum/thread-02106149308219906039-1-1.html高可用prometheus集群方案选型分享https://bbs.huaweicloud.com/forum/thread-02120149171280544026-1-1.html数据结构小实践https://bbs.huaweicloud.com/forum/thread-0205148913374176023-1-1.html常用的Python 正则表达式笔记分享https://bbs.huaweicloud.com/forum/thread-0229148809003688021-1-1.htmlOBS常用存储类别及介绍笔记分享https://bbs.huaweicloud.com/forum/thread-02107148640450505013-1-1.htmlOBS存储加密方式https://bbs.huaweicloud.com/forum/thread-02107148640269972012-1-1.html计算机常用基础常识https://bbs.huaweicloud.com/forum/thread-02107148640095926011-1-1.htmlC线性链表https://bbs.huaweicloud.com/forum/thread-02107148566274864009-1-1.htmlLinux基础与服务器架构综合小实践https://bbs.huaweicloud.com/forum/thread-0208148385106201002-1-1.html数码管的动态显示https://bbs.huaweicloud.com/forum/thread-0229148385031520001-1-1.htmlLinux磁盘配额小实践https://bbs.huaweicloud.com/forum/thread-0208148316143191001-1-1.htmlNUMA架构笔记分享https://bbs.huaweicloud.com/forum/thread-0291148012681064004-1-1.htmlNUMA-Aware亲和性优化https://bbs.huaweicloud.com/forum/thread-0231148012477529001-1-1.htmlGaussDB分布式与单机模式的比较https://bbs.huaweicloud.com/forum/thread-0252147925786150001-1-1.html中断源类型详解https://bbs.huaweicloud.com/forum/thread-02109147598839758040-1-1.html资讯【话题交流】说说大家都知道的认证考试和学习推荐讨论https://bbs.huaweicloud.com/forum/thread-0208149308741557029-1-1.html
  • 【话题交流】说说大家都知道的认证考试和学习推荐讨论
    随着IT技术的不断发展,知识的不断更新迭代,大家讨论讨论说说大家都知道的认证考试和学习推荐,欢迎大家一起来讨论所有IT方面都可以、大数据、物联网、人工智能、云计算、区块链、项目管理等等等……都可以来说说有没有推荐的
  • GaussDB数据量与分区策略分析
    简要概述我们可以得出一些关于GaussDB数据库是否需要分区,以及如何进行分区的初步建议。分区是一种数据库管理技术,用于提高数据处理效率、优化存储使用和提高系统的可维护性。通常,分区决策是基于数据量和表的大小来决定的。详细分析1. 分区策略的选择分区策略的选择取决于数据的特性和表的使用情况。例如,具有明显区间性特征的字段(如日期、区域、数值等)适合进行表分区。时间字段是最常见的分区字段,因为业务查询经常具有明显的区间范围特征。此外,对于数据量大的表,分区可以有效提升数据扫描效率,降低IO开销。2. 分区的标准和方法GaussDB支持多种分区方法,如RANGE分区、INTERVAL分区、LIST分区和HASH分区。RANGE分区是基于连续范围进行的分区,适用于数据范围固定的字段。INTERVAL分区是基于固定间隔进行的分区,适用于时间字段。LIST分区是基于特定列表值进行的分区,适用于枚举类型字段。HASH分区是基于哈希函数进行的分区,适用于任意类型的字段。3. 分区的限制和注意事项一些分区时的限制,例如二级分区表的叶子节点个数不能超过1048575个,一级分区无限制。同时,还应注意分区策略可能会受到磁盘容量不足的影响,需要合理规划磁盘分区以避免容量不足。总结建议综上所述,GaussDB的数据量达到一定程度并且表的大小符合分区的要求时,建议进行分区。具体的分区策略应基于数据特性和业务需求来确定,考虑范围性字段、时间字段等适合进行分区的字段。在实施分区之前,需要评估磁盘容量,确保分区不会因容量不足而影响性能。GaussDB的数据量是否需要分区取决于多个因素,包括但不限于数据的规模、查询性能需求以及存储资源等。一般来说,当表的数据量较大,查询频繁并且需要优化查询性能时,可以考虑进行分区。GaussDB支持多种分区方式,包括Range分区、Interval分区、List分区和Hash分区1。具体的分区策略需要根据实际的数据特征和业务需求来制定。例如,如果你的数据具有明显的时间范围特征,你可以选择Range或者Interval分区;如果你希望根据特定的值来进行分区,可以选择List分区;如果你希望根据数据的散列值来进行分区,可以选择Hash分区。此外,GaussDB还支持二级分区,即在一级分区的基础上进一步划分二级分区。但是需要注意的是,二级分区表的二级分区(叶子节点)个数不能超过1048575个,一级分区无限制,但一级分区下面至少有一个二级分区。总的来说,GaussDB的分区策略是为了提高查询性能和优化存储资源的使用,具体是否需要分区以及如何分区,需要根据你的实际需求和数据特征来决定。
  • GaussDB分页查询的实现方法
    概述GaussDB的分页查询通常涉及到数据库的排序和数据量的限制。在数据库管理系统中,分页查询可以帮助用户一次获取少量数据,减少数据传输量和内存使用,提高查询效率。接下来将从多个角度详细探讨GaussDB分页查询的具体实现方法和优化技巧。分页查询的SQL写法在GaussDB中,分页查询可以通过以下两种SQL语句来实现:第一种:子查询法SELECT * FROM ( SELECT a.*, ROWNUM rn FROM (SELECT * FROM tab1 WHERE status = 1 ORDER BY id) a ) b WHERE rn <= 500这里使用了一个子查询来生成行号,并通过ROWNUM限制行数不超过500。第二种:LIMIT用法SELECT * FROM tab1 WHERE status = 1 ORDER BY id LIMIT 500, 1这种写法使用了LIMIT语句来跳过前面的数据行,直接选取接下来的500行数据。场景优化及建议当查询的数据量非常大时,建议使用索引来优化查询性能。如果大部分查询都是访问前几页数据,建议使用排序字段的索引来提高效率。对于需要频繁翻页的场景,建议使用不排序的分页查询方式,如使用LIMIT语句。当需要对统计分页数据总数时,建议缓存结果或合理设计查询逻辑以避免重复计算。分页查询的性能优化索引策略:适当地创建和使用索引可以大幅提高查询速度,特别是对于排序和筛选操作。SQL语句优化:合理编写SQL语句,避免使用过多的子查询,减少数据处理的层级。数据库引擎优化:选择合适的数据库引擎,例如GaussDB的并行执行能力可以有效地处理大数据量的分页查询。在GaussDB中实现分页查询,您可以使用LIMIT和OFFSET关键字。LIMIT关键字用来限制返回的记录数量,而OFFSET关键字用来跳过前面的记录。这两个关键字通常一起使用,以实现分页的效果。以下是使用LIMIT和OFFSET关键字的一个基本例子:SELECT * FROM your_table_nameLIMIT 10OFFSET 20;在这个例子中,LIMIT 10指定了每页显示10条记录,而OFFSET 20指定了从第20条记录开始显示。这意味着查询结果将显示第21到第30条记录。请注意,不同的数据库系统可能有不同的分页查询语法。在GaussDB中,上述方法是实现分页查询的标准方式。在实际使用中,您可能需要根据具体的查询需求和数据表结构调整LIMIT和OFFSET的值。深入研究如何在保持高性能的同时,对大规模数据集进行有效的分页查询?在对大规模数据集进行分页查询时,为了保持高性能,可以采取以下几种策略:使用覆盖索引覆盖索引是指查询时只需要访问索引而无需访问表中的数据行。通过对表中的字段建立索引,并在查询时使用这些索引,可以显著提高查询速度。例如,如果有一个字段id是自增的,并且是连续增长的,可以在id上建立索引,然后在查询时使用LIMIT和OFFSET来快速定位到需要的页面。延迟关联延迟关联是一种优化策略,它涉及到先通过索引获取到需要的主键,然后再根据主键关联原表以获取完整数据,而不是通过二级索引获取主键后再遍历数据页。这样可以避免大量的随机I/O请求,从而提高查询效率。使用游标分页游标分页是通过记录的唯一标识符来定位分页的起点和终点,避免了大量的跳跃查询。这种方法通常适用于有唯一标识符的字段,如id或row_number等。选择合适的分页策略在某些情况下,可能需要根据实际应用场景选择最合适的数据分页策略。例如,如果数据是连续增长的,可以选择基于ID的分页;如果数据是无序的,可能需要使用其他方法,如基于时间的分页或其他业务逻辑上的分页。利用缓存如果数据不是实时变化的,可以考虑使用缓存来存储最近的分页结果,减少对数据库的查询次数,从而提高性能。分区表分页如果数据表非常大,可以考虑将其分区,每个分区包含一部分数据。这样,在进行分页查询时,只需访问包含所需数据的分区,减少了不必要的数据扫描。硬件和资源优化除了查询优化外,还可以通过增加服务器资源、使用更快的存储解决方案(如SSD)、优化数据库配置等方式来提高整体性能。综上所述,通过对大规模数据集采用适当的分页策略和技术,可以在保持高性能的同时有效地进行分页查询。在设计分页查询功能时,如何解决数据库资源消耗与用户体验之间的平衡?在设计分页查询功能时,解决数据库资源消耗与用户体验之间的平衡是一个重要的考虑因素。以下是一些关键点,可以帮助您在开发过程中找到这种平衡:1. 优化查询语句确保您的查询尽可能高效,避免使用复杂的子查询和不必要的联接操作。使用正确的索引可以大大减少查询所需的IO操作,从而降低资源消耗。2. 使用合理的分页大小默认的分页大小应该适应大多数用户的浏览习惯,同时考虑到后端服务的处理能力。过大或过小的分页尺寸都可能导致资源过度消耗或不满足用户需求。3. 提供自定义分页选项允许用户根据自己的偏好设置分页大小,可以在保证用户体验的同时,减轻服务器的压力。4. 引入缓存机制对于不经常变化的数据,可以通过缓存来减少数据库访问次数,从而节省资源。合理设计的缓存策略可以有效缓解热点数据的查询压力。5. 监控和调优实施监控工具来跟踪分页查询的性能指标,如响应时间、吞吐量等。根据监控数据进行调优,以确保资源消耗保持在可接受的范围内。6. 负载均衡如果可能的话,使用负载均衡器来分散流量,减轻单个服务器的负担。这有助于在高负载下维持稳定性和可用性。7. 异步处理对于非关键路径上的分页查询,可以考虑使用异步处理的方式,让用户界面保持响应,同时在后台慢慢处理数据。8. 用户反馈收集用户反馈,了解用户在使用分页功能时的真实感受,并根据这些反馈来调整设计和参数。通过综合考虑以上因素,可以在确保数据库资源得到合理利用的同时,为用户提供一个流畅且友好的分页查询体验。考虑到分页查询在大数据环境下的局限性,未来数据库技术发展趋势中可能出现哪些替代方案?在大数据环境下,分页查询确实存在一定的局限性,因为它可能会导致大量数据的重复加载,特别是在高交互的应用场景中。未来的数据库技术发展趋势可能会出现以下几个替代方案来解决这一问题:1. 动态数据流处理未来的数据库技术可能会更加注重实时数据处理能力的提升,通过动态数据流处理技术,可以不断地向用户展示最新的数据片段,而不是一次性加载整个数据集。2. 智能预加载算法通过机器学习和人工智能技术,数据库可以预测用户的查询模式,并提前加载可能被请求的数据,以此来减少等待时间和资源消耗。3. 分布式计算和存储随着云计算和边缘计算的发展,数据库技术可能会越来越多地依赖于分布式计算和存储解决方案,以提高处理大数据的能力和效率。4. 内存数据库和缓存为了减少磁盘I/O操作,未来的数据库技术可能会更多地使用内存数据库和缓存技术,以提高数据访问的速度。5. 微服务和容器化通过微服务和容器化的架构,可以将数据库分解成多个小块,每个小块负责处理特定类型的查询,从而提高整体的灵活性和效率。6. 无SQL数据库无SQL数据库(NoSQL databases)提供了不同于传统关系型数据库的模型,它们通常更适合于处理大规模的非结构化数据,可能在未来的大数据环境中扮演更重要的角色。7. 数据虚拟化数据虚拟化技术可以创建一个抽象层,使得用户可以直接访问不同来源和格式的数据,而不需要关心数据实际存储在哪里,这可能有助于简化大数据环境下的数据管理。8. 增强现实和虚拟现实虽然目前还不是主流技术,但增强现实(AR)和虚拟现实(VR)技术在未来可能会提供一种全新的数据可视化和交互方式,尤其是在需要复杂数据可视化的领域。这些潜在的替代方案表明,未来的数据库技术发展将会集中在提高处理速度、降低资源消耗以及提供更加智能化和个性化的用户体验。随着技术的不断进步,这些新兴的解决方案有望克服现有的大数据挑战。总结分页查询是数据库常用的操作,尤其是在数据量较大时。合理使用SQL语句、索引以及数据库引擎的特性,可以有效地提高分页查询的性能。在实际应用中,应根据具体情况选择合适的分页查询方式和优化策略。审核中
  • [技术干货] 高可用prometheus集群方案选型分享
      Prometheus采用Pul模型收集监控数据,服务高可用意味着同一个服务需要至少两个节点同时拉取或者切换为Push模型,使用一致性哈希,将不同实例的Metrics推送到固定推送到其中一台服务,这个模式优势是,在保障服务可用性的同时,资源消耗量少一半;新节点不需要重新配置抓取规则可以做到快速平行扩容。但缺点是,节点故障将导致历史数据丢失。应用于生产环境的监控服务,单机Promtheus往往是无法满足需求的,此时就要搭建一套Prometheus集群,此时就需要考虑:服务高可用:服务要冗余备份,以消除单点故障。水平可扩展:可以通过增加服务数量,线性提高服务能力。数据持久化:节点故障数据不丢失、海量历史数据存储数据一致性:冗余结点之间数据需要保证一致性。选型⼀      Prometheus 根据功能或服务维度进行拆分,即如果要采集的服务比较多,一个Prometheus 实例就配置成仅采集和存储某一个或某一部分服务的指标,这样根据要采集的服务将 Prometheus 拆分成多个实例分别去采集,也能一定程度上达到水平扩容的目的。优点:服务被拆分给多个prometheus实例例收集,从而降低了单实例的性能瓶颈不同的prometheus实例配置可以不同拆分存储,分摊采集指标的量缺点统⼀查询入⼝不统⼀,每个prometheus都是一个查询入口采集数据依然存在本地,受本地磁盘容量和io限制选型⼆      针对选型一,一个Prometheus实例可能连这单个服务的采集任务都扛不住。     prometheus需要向这个服务所有后端实例发请求采集数据,由于后端实例数量规模太大,采集并发量就会很高,一方面对节点的带宽、CPU、磁盘lo都有一定的压力,另一方面Prometheus使用的磁盘空间有限,采集的数据量过大很容易就将磁盘塞满了,通常要做一些取舍才能将数据量控制在一定范围,但这种取舍也会降低数据完整和精确程度,不推荐这样做。那么我们可以给这种大规模类型的服务做一下分片(Sharding),将其拆分成多个group,让一个Prometheus 实例仅采集这个服务背后的某一个group 的数据,这样就可以将这个大体量服务的监控数据拆分到多个Prometheus 实例上。优点︰解决单个服务监控指标大,利用切片方式让不同prometheus负责不同分片可以做Prometheus水平扩容缺点︰加剧了监控数据落盘的分散程度,使用grafana查询数据依然需要添加多个数据源不同数据源之间的数据还不能聚合查询选型三      可以让Prometheus 不负责存储,仅采集数据并通过remote write接口方式写入远程存储的adapter,远程存储使用OpenTSDB或InfluxDB这些支持集群部署的时序数据库。然后Grafana添加我们使用的时序数据库作为数据源来查询监控数据来展示。优点数据存储远程写入,实现单数据源的查询缺点:查询语句得使用远程数据源的语法,并不能使用prometheus的promeQL语法查询选型四       虽然上面我们通过一些列操作将Prometheus进行了分布式改造,但并没有解决Prometheus 本身的高可用问题,即如果其中一个实例挂了,数据的查询和完整性都将受到影响,那么我们可以将所有Prometheus实例都使用两个相同副本,分别挂载数据盘,它们都采集相同的服务,所以它们的数据是一致的,查询它们之中任意一个都可以,所以可以在它们前面再挂一层负载均衡,所有查询都经过这个负载均衡分流到其中一台Prometheus,如果其中一台挂掉就从负载列表里踢掉不再转发。优点:保障了prometheus的高可用缺点:数据并不能保证完全一致,当其中一台故障恢复后,他将丢失该时间的数据选型五        thanos架构,可以帮我们简化分布式 Prometheus的部署与管理,并提供了一些的高级特性︰全局视图,长期存储,高可用,该架构使用grpc保持各个组件的通讯,sidecar组件负责连接Prometheus,将其数据提供给Thanos Query查询,并且/或者将其上传到对象存储,以供长期存储。Query组件实现了Prometheus APl,将来自下游组件提供的数据进行聚合最终返回给查询数据的client(如grafana),类似数据库中间件。Thanos Store Gateway组件将对象存储的数据暴露给Thanos Query去查询,Thanos Compact组件将对象存储中的数据进行压缩和降低采样率,大时间区间监控数据查询的速度。Thanos Ruler组件对监控数据进行评估和告警,还可以计算出新的监控数据,将这些新数据提供给Thanos Query查询并且/或者上传到对象存储,以供长期存储。优点:采集数据可永久性保存全局Query入口查询支持PromeQL语法。支持监控数据的聚合和去重保障prometheus的高可用缺点︰sidecar如果分布在不同地域,容易造成较高延迟,查询速度会较慢。但可以用Receiver模式(还不稳定)
  • 数据结构小实践
    单向链表的概念单向链表是一种线性数据结构,它由一系列节点组成,每个节点包含数据和指向下一个节点的指针。在单向链表中,数据元素之间是单向连接的,每个节点只有一个指针指向下一个节点,而没有指向前一个节点的指针。因此,一旦形成链表,就不能从任意节点直接访问前一个节点,只能从头节点开始沿着指针依次访问每个节点单向链表的基本操作单向链表的主要操作包括插入、删除和遍历等。插入操作:在链表的任意位置插入一个新节点。这通常涉及到创建一个新的节点,然后将其插入到链表的特定位置,并更新相应节点的指针2。删除操作:删除链表中指定位置的节点。这通常需要找到要删除的节点,然后将前一个节点的指针跳过该节点,指向下一个节点,最后释放该节点的资源2。遍历操作:遍历链表,访问链表中的每个节点。这可以通过从头节点开始,逐步移动到尾节点来实现下列给定程序是建立一个带头结点的单向链表,并用随机函数为各结点赋值。函数fun的功能是将单向链表结点(不包括头结点)数据域为偶数的值累加起来,并且作为函数值返回。#include <stdio.h>#include <conio.h>#include <stdlib.h>typedef struct aa{ int data;  struct aa *next;} NODE;int fun (NODE *h){ int sum=0;  NODE *p;  p=h->next;/*************found**************/  while(p->next)       { if(p->data%2==0)             sum+=p->data;/*************found**************/          p=h->next;       }  return sum;}NODE *creatlink(int n){   NODE *h,*p,*s;  int i;  h=p=(NODE*)malloc(sizeof(NODE));  for(i=1;i<n;i++)  {         s=(NODE*)malloc(sizeof(NODE));               s->data=rand()%16;               s->next=p->next;               p->next=s;               p=p->next;  }  p->next=NULL;  return h;}outlink(NODE *h){ NODE  *p;  p=h->next;  printf("\n\n The LIST :\n\n HEAD");  while(p)    { printf("->%d",p->data);      p=p->next;}  printf("\n");}void main(){ NODE *head; int sum;  system("CLS");  head=creatlink(10);  outlink(head);  sum=fun(head);  printf("\nSUM=%d",sum);}【解题思路】本题考查的是在这种链表的数据结构中,必须利用指针变量才能实现,即一个节点中应包含一个指针变量,用以存放下一节点的地址。建立单项链表的一般步骤是:建立头指针→建立第一个节点→头指针指向第一个节点→建立第二个节点→第一个节点的指针与指向第二个节点→…→最后一个节点的指针指向null。本题重点是:了解链表的基本思想和相关算法,理解有关链表插入及删除时,指针移动的先后顺序问题,注意指针的保存和归位。while循环条件是判断链表是否结束,所以改为while (p!=NULL),要指向下个节点所以改为p=p->next。注意事项在使用单向链表时,需要注意的是,由于链表的节点之间是通过指针相连的,因此在插入和删除节点时,需要特别小心处理这些指针关系,以确保链表的正确性和完整性。同时,由于单向链表不支持快速反向访问,所以在需要频繁访问链表尾部或中间节点的场景下,可能不如双向链表或数组方便
  • 常用的Python 正则表达式笔记分享
     正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。 Python 自1.5版本起增加了 re 模块,是用于处理字符串的强大工具,re 模块使 Python 语言拥有全部的正则表达式功能。compile() 函数根据一个模式字符串和可选的标志参数生成一个正则表达式对象。该对象拥有一系列方法用于正则表达式匹配和替换。re 模块也提供了与这些方法功能完全一致的函数,这些函数使用一个模式字符串做为它们的第一个参数。本章节主要介绍Python中常用的正则表达式处理函数。re.match函数re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。函数语法:re.match(pattern, string, flags=0)函数参数说明:参数描述pattern匹配的正则表达式string要匹配的字符串。flags标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。正则表达式修饰符 - 可选标志正则表达式可以包含一些可选标志修饰符来控制匹配的模式。修饰符被指定为一个可选的标志。多个标志可以通过按位 OR(|) 它们来指定。如 re.I | re.M 被设置成 I 和 M 标志:修饰符描述re.I使匹配对大小写不敏感re.L做本地化识别(locale-aware)匹配re.M多行匹配,影响 ^ 和 $re.S使 .匹配包括换行在内的所有字符re.U根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B.re.X该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。匹配成功re.match方法返回一个匹配的对象,否则返回None。我们可以使用group(num) 或 groups() 匹配对象函数来获取匹配表达式。匹配对象方法描述group(num=0)匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。groups()返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。实例import re print(re.match('www', 'www.python.org').span())  # 在起始位置匹配 print(re.match('org', 'www.python.org'))         # 不在起始位置匹配以上实例运行输出结果为:(0, 3) None实例import re line = "Cats are smarter than dogs" matchObj = re.match( r'(.*) are (.*?) .*', line, re.M|re.I) if matchObj:   print ("matchObj.group() : ", matchObj.group())   print ("matchObj.group(1) : ", matchObj.group(1))   print ("matchObj.group(2) : ", matchObj.group(2)) else:   print ("No match!!")以上实例执行结果如下:matchObj.group() : Cats are smarter than dogs matchObj.group(1) : Cats matchObj.group(2) : smarterre.search 方法re.search 扫描整个字符串并返回第一个成功的匹配。函数语法:re.search(pattern, string, flags=0)函数参数说明:参数描述pattern匹配的正则表达式string要匹配的字符串flags标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等匹配成功re.search方法返回一个匹配的对象,否则返回None。 我们可以使用group(num) 或 groups() 匹配对象函数来获取匹配表达式。匹配对象方法描述group(num=0)匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。groups()返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。实例import re print(re.search('www', 'www.python.org').span())  # 在起始位置匹配 print(re.search('org', 'www.python.org').span())  # 不在起始位置匹配以上实例运行输出结果为:(0, 3) (11, 14)实例import re line = "Cats are smarter than dogs"; searchObj = re.search( r'(.*) are (.*?) .*', line, re.M|re.I) if searchObj:   print ("searchObj.group() : ", searchObj.group())   print ("searchObj.group(1) : ", searchObj.group(1))   print ("searchObj.group(2) : ", searchObj.group(2)) else:   print ("Nothing found!!")以上实例执行结果如下:searchObj.group() : Cats are smarter than dogs searchObj.group(1) : Cats searchObj.group(2) : smarterre.match 与 re.search 的区别re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。实例import re line = "Cats are smarter than dogs"; matchObj = re.match( r'dogs', line, re.M|re.I) if matchObj:   print ("match --> matchObj.group() : ", matchObj.group()) else:   print ("No match!!") matchObj = re.search( r'dogs', line, re.M|re.I) if matchObj:   print ("search --> matchObj.group() : ", matchObj.group()) else:   print ("No match!!")以上实例运行结果如下:No match!! search --> matchObj.group() : dogs检索和替换Python 的 re 模块提供了 re.sub 用于替换字符串中的匹配项。语法:re.sub(pattern, repl, string, count=0)参数:pattern : 正则中的模式字符串。repl : 替换的字符串,也可为一个函数。string : 要被查找替换的原始字符串。count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。实例import re phone = "2004-959-559 # 这是一个电话号码" # 删除注释 num = re.sub(r' #.*$', "", phone) print ("电话号码 : ", num) # 移除非数字的内容 num = re.sub(r'\D', "", phone) print ("电话号码 : ", num)以上实例执行结果如下:电话号码 : 2004-959-559 电话号码 : 2004959559re.compile 函数compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match() 和 search() 这两个函数使用。语法格式为:re.compile(pattern[, flags])参数:pattern : 一个字符串形式的正则表达式flags 可选,表示匹配模式,比如忽略大小写,多行模式等,具体参数为:re.I 忽略大小写re.L 表示特殊字符集 \w, \W, \b, \B, \s, \S 依赖于当前环境re.M 多行模式re.S 即为' . '并且包括换行符在内的任意字符(' . '不包括换行符)re.U 表示特殊字符集 \w, \W, \b, \B, \d, \D, \s, \S 依赖于 Unicode 字符属性数据库re.X 为了增加可读性,忽略空格和' # '后面的注释实例>>> import re >>> pattern = re.compile(r'\d+')                    # 用于匹配至少一个数字 >>> m = pattern.match('one12twothree34four')        # 查找头部,没有匹配 >>> print m None >>> m = pattern.match('one12twothree34four', 2, 10) # 从'e'的位置开始匹配,没有匹配 >>> print m None >>> m = pattern.match('one12twothree34four', 3, 10) # 从'1'的位置开始匹配,正好匹配 >>> print m                                         # 返回一个 Match 对象 <_sre.SRE_Match object at 0x10a42aac0> >>> m.group(0)   # 可省略 0 '12' >>> m.start(0)   # 可省略 0 3 >>> m.end(0)     # 可省略 0 5 >>> m.span(0)    # 可省略 0 (3, 5)在上面,当匹配成功时返回一个 Match 对象,其中:group([group1, …]) 方法用于获得一个或多个分组匹配的字符串,当要获得整个匹配的子串时,可直接使用 group()或 group(0);start([group]) 方法用于获取分组匹配的子串在整个字符串中的起始位置(子串第一个字符的索引),参数默认值为 0;end([group]) 方法用于获取分组匹配的子串在整个字符串中的结束位置(子串最后一个字符的索引+1),参数默认值为 0;span([group]) 方法返回 (start(group), end(group))。实例>>> import re >>> pattern = re.compile(r'([a-z]+) ([a-z]+)', re.I)   # re.I 表示忽略大小写 >>> m = pattern.match('Hello World Wide Web') >>> print(m)                               # 匹配成功,返回一个 Match 对象 <_sre.SRE_Match object at 0x10bea83e8> >>> m.group(0)                            # 返回匹配成功的整个子串 'Hello World' >>> m.span(0)                             # 返回匹配成功的整个子串的索引 (0, 11) >>> m.group(1)                            # 返回第一个分组匹配成功的子串 'Hello' >>> m.span(1)                             # 返回第一个分组匹配成功的子串的索引 (0, 5) >>> m.group(2)                            # 返回第二个分组匹配成功的子串 'World' >>> m.span(2)                             # 返回第二个分组匹配成功的子串 (6, 11) >>> m.groups()                            # 等价于 (m.group(1), m.group(2), ...) ('Hello', 'World') >>> m.group(3)                            # 不存在第三个分组 Traceback (most recent call last):  File "<stdin>", line 1, in <module> IndexError: no such groupfindall在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。注意: match 和 search 是匹配一次 findall 匹配所有。语法格式为:re.findall(pattern, string, flags=0)参数:参数描述pattern匹配的正则表达式string要匹配的字符串。flags标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。查找字符串中的所有数字:实例import re result1 = re.findall(r'\d+', 'TechLab 123 google 456') result2 = re.findall(r'\d+', 'Tech88Lab123google456') print(result1) print(result2)输出结果:['123', '456'] ['88', '123', '456']re.finditer和 findall 类似,在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回。re.finditer(pattern, string, flags=0)参数:参数描述pattern匹配的正则表达式string要匹配的字符串。flags标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。实例import re it = re.finditer(r"\d+","12a32bc43jf3") for match in it:    print (match.group())输出结果:12 32 43 3re.splitsplit 方法按照能够匹配的子串将字符串分割后返回列表,它的使用形式如下:re.split(pattern, string[, maxsplit=0, flags=0])参数:参数描述pattern匹配的正则表达式string要匹配的字符串。maxsplit分隔次数,maxsplit=1 分隔一次,默认为 0,不限制次数。flags标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。实例>>> import re >>> re.split('\W+', 'python, python, python.') ['python', 'python', 'python', ''] >>> re.split('(\W+)', ' python, python, python.') ['', ' ', 'python', ', ', 'python', ', ', 'python', '.', ''] >>> re.split('\W+', ' python, python, python.', 1) ['', 'python, python, python.'] >>> re.split('a*', 'hello world')   # 对于一个找不到匹配的字符串而言,split 不会对其作出分割 ['hello world']附录正则表达式对象re.RegexObjectre.compile() 返回 RegexObject 对象。re.MatchObjectgroup() 返回被 RE 匹配的字符串。start() 返回匹配开始的位置end() 返回匹配结束的位置span() 返回一个元组包含匹配 (开始,结束) 的位置正则表达式模式模式字符串使用特殊的语法来表示一个正则表达式:字母和数字表示他们自身。一个正则表达式模式中的字母和数字匹配同样的字符串。多数字母和数字前加一个反斜杠时会拥有不同的含义。标点符号只有被转义时才匹配自身,否则它们表示特殊的含义。反斜杠本身需要使用反斜杠转义。由于正则表达式通常都包含反斜杠,所以你最好使用原始字符串来表示它们。模式元素(如r'\t',等价于\\t )匹配相应的特殊字符。下表列出了正则表达式模式语法中的特殊元素。如果你使用模式的同时提供了可选的标志参数,某些模式元素的含义会改变。模式描述^匹配字符串的开头$匹配字符串的末尾。.匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。[...]用来表示一组字符,单独列出:[amk]匹配'a','m'或'k'[^...]不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。re*匹配0个或多个的表达式。re+匹配1个或多个的表达式。re?匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式re{ n}匹配n个前面表达式。例如,"o{2}"不能匹配"Bob"中的"o",但是能匹配"food"中的两个o。re{ n,}精确匹配n个前面表达式。例如,"o{2,}"不能匹配"Bob"中的"o",但能匹配"foooood"中的所有o。"o{1,}"等价于"o+"。"o{0,}"则等价于"o*"。re{ n, m}匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式a|b匹配a或b(re)匹配括号内的表达式,也表示一个组(?imx)正则表达式包含三种可选标志:i, m, 或 x 。只影响括号中的区域。(?-imx)正则表达式关闭 i, m, 或 x 可选标志。只影响括号中的区域。(?: re)类似(...), 但是不表示一个组(?imx: re)在括号中使用i, m, 或 x 可选标志(?-imx: re)在括号中不使用i, m, 或 x 可选标志(?#...)注释.(?= re)前向肯定界定符。如果所含正则表达式,以 ... 表示,在当前位置成功匹配时成功,否则失败。但一旦所含表达式已经尝试,匹配引擎根本没有提高;模式的剩余部分还要尝试界定符的右边。(?! re)前向否定界定符。与肯定界定符相反;当所含表达式不能在字符串当前位置匹配时成功。(?> re)匹配的独立模式,省去回溯。\w匹配数字字母下划线\W匹配非数字字母下划线\s匹配任意空白字符,等价于[\t\n\r\f]。\S匹配任意非空字符\d匹配任意数字,等价于[0-9]。\D匹配任意非数字\A匹配字符串开始\Z匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。\z匹配字符串结束\G匹配最后匹配完成的位置。\b匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never"中的'er',但不能匹配 "verb" 中的'er'。\B匹配非单词边界。'er\B'能匹配 "verb"中的'er',但不能匹配 "never"中的 'er'。\n, \t, 等。匹配一个换行符。匹配一个制表符, 等\1...\9匹配第n个分组的内容。\10匹配第n个分组的内容,如果它经匹配。否则指的是八进制字符码的表达式。正则表达式使用实例字符匹配实例描述python匹配 "python".字符类实例描述[Pp]ython匹配"Python" 或"python"rub[ye]匹配 "ruby" 或 "rube"[aeiou]匹配中括号内的任意一个字母[0-9]匹配任何数字。类似于[0123456789][a-z]匹配任何小写字母[A-Z]匹配任何大写字母[a-zA-Z0-9]匹配任何字母及数字[^aeiou]除了aeiou字母以外的所有字符[^0-9]匹配除了数字外的字符特殊字符类实例描述.匹配除 \n之外的任何单个字符。要匹配包括\n在内的任何字符,请使用像[.\n]的模式。\d匹配一个数字字符。等价于[0-9]。\D匹配一个非数字字符。等价于[^0-9]。\s匹配任何空白字符,包括空格、制表符、换页符等等。等价于[\f\n\r\t\v]。\S匹配任何非空白字符。等价于[^ \f\n\r\t\v]。\w匹配包括下划线的任何单词字符。等价于[A-Za-z0-9_]。\W匹配任何非单词字符。等价于[^A-Za-z0-9_]。
  • OBS常用存储类别及介绍笔记分享
    对象存储服务(Object Storage Service,OBS)是一个基于对象的海量存储服务,它的基本组成是桶和对象,桶是OBS中存储对象的容器,对象是OBS中数据存储的基本单位,它能够为客户提供海量、安全、高可靠、低成本的数据存储能力。华为云在全球多区域部署了OBS基础设施,用户可以根据自身需要指定区域使用OBS,由此获得更快的访问速度和实惠的服务价格。OBS系统是一项面向Internet访问的服务,用户可以随时随地连接到Internet的电脑上,因为OBS提供了基于HTTP/HTTPS协议的Web服务接口,用户可以通过OBS管理控制台或各种OBS工具访问和管理存储在OBS中的数据。企业也可以在自己的应用程序中随心管理自己存储在OBS上的数据,因为OBS对外提供了支持SDK和OBS API接口,企业的开发人员可以根据OBS提供的SDK和API接口随心的调用存储在OBS上的数据。OBS提供了四种存储类别:标准存储、低频访问存储、归档存储、深度归档存储(受限公测中),从而在各个方面满足客户业务对存储性能、成本的不同诉求。标准存储:它的访问延时低、吞吐量高,所以它适用于有大量热点文件(平均一个月多次)或小文件(小于1MB),并且适用于需要频繁访问数据的业务场景,比如:大数据、移动应用、热点视频、社交图片等场景。低频访问存储:它有和标准存储一样的数据持久性、吞吐量以及访问时延,且成本较低,就是可用性略低于标准存储,它适用于不频繁访问(平均一年少于12次)但在需要时也要求快速访问数据的业务场景,比如:文件同步/共享、企业备份等场景。归档存储:它的特点是安全、持久且成本极低,可以用来替代磁带库。归档存储为了保持成本低廉,数据取回时间可能长达数分钟到数小时不等,所以它适用于很少访问(平均一年访问一次)数据的业务场景,比如:数据归档、长期备份等场景。深度归档存储:它的成本比归档存储更低,它适用于长期不访问(平均几年访问一次)数据的业务场景。OBS共用5大优势,数据稳定,业务可靠:OBS支撑华为手机云相册,能够支持数亿用户的访问,能够给应用提供稳定可靠的数据;多重防护,授权管理:OBS通过可信云认证,让数据安全放心;千亿对象,千万并发:OBS通过智能调度和响应,优化数据访问路径、传输加速等技术,可以为各场景下用户的千亿对象提供千万级并发、超高带宽、稳定低时延的数据访问体验;简单易用,便于管理:OBS提供SDK和标准REST API接口,能够让业务快速上云,OBS还有管理控制台或各种OBS工具,可以使用户方便管理自己存储在OBS上的数据;数据分层,按需使用:OBS提供按量计费和包年包月两种支付方式,用户可以随心选择的适合自己的支付方式。OBS有很多的适用场景,比如:大数据分析、静态网站托管、在线视频点播、基因测序、智能视频监控、备份归档等,这么多的使用场景总有一种满足你。2022年“华为云双12”已重磅开启,华为云以优质的产品解决方案及服务全方位满足企业上云、用云需求,助力企业实现创新增效。
  • OBS存储加密方式
    OBS对象存储是华为云提供的一种高效、安全、可靠的云存储服务,它提供了数据加密和备份机制,为用户的数据安全性提供了更可靠的保障。数据加密在OBS对象存储中,对数据的加密是采用AES-256位加密算法,这是一种经典、高安全性的算法。用户可以选择在上传文件时对文件进行加密处理,或者在创建桶时对整个桶进行加密处理。同时,OBS对象存储还提供了多种密钥管理模式,用户可以自主选择对密钥的管理方式。这些功能可以帮助用户更好地保护自己的数据,确保数据不被未经授权的人员访问。备份机制备份是保障数据安全的重要手段之一,OBS对象存储提供了多层次的备份机制,包括跨机房备份和跨地域备份。跨机房备份可以保障在主机房出现故障时,数据能够快速备份到备用机房,确保数据的可用性。跨地域备份则能够保障在某个地域发生不可抗力因素时,数据能够备份到其他地域,避免数据的丢失。同时,OBS对象存储还提供了数据版本控制功能,用户可以对数据进行历史版本的管理和查询,确保数据的完整性和可靠性。总结作为一种高效、安全、可靠的云存储服务,OBS对象存储为用户提供了强大的数据加密和备份机制,为用户的数据安全性提供了更可靠的保障。除此之外,OBS对象存储还具备高可靠性和高性能的特点,可以满足用户对于数据存储和处理的需求。因此,对于企业和组织来说,选择OBS对象存储作为数据存储的方案是一个明智的选择。
  • 计算机常用基础常识
    计算机的发展、类型及其应用领域。计算机(computer)是一种能自动、高速进行大量算术运算和逻辑运算的电子设备。 其特点为:速度快、精度高、存储容量大、通用性强、具有逻辑判断和自动控制能力。第一台计算机:ENIAC,美国,1946年 宾夕法尼亚大学  冯诺依曼 “存储程序”和“程序控制”冯诺依曼思想的核心要点是:    1)计算机的基本结构应由五大部件组成:运算器、控制器、存储器、输入设备和输出设备。    2)计算机中应采用二进制形式表示数据和指令。    3)采用“存储程序”和“程序控制”的工作方式。 计算机的发展过程阶段年份物理器件软件特征应用范围第一代1946-1959电子管机器语言、汇编语言科学计算第二代1959-1964晶体管高级语言科学计算、数据处理、工业控制第三代1964-1970小规模集成电路操作系统科学计算、数据处理、工业控制、文字处理、图形处理第四代1970-至今大规模集成电路数据库网络等各个领域主要特点:运算速度快、精确度高、具有记忆和逻辑判断能力计算机的主要应用科学计算:例如:气象预报、海湾战争中伊拉克导弹的监测数据/信息处理:例如:高考招生中考生录取与统计工作,铁路、飞机客票的预定系统,银行系统的业务管理计算机控制计算机辅助系统:例如:用CAI演示化学反应人工智能:例如:代替人类到危险的环境中去工作办公自动化系统中的应用:例如:Internet发emailCBE:计算机辅助教育CAI:计算机辅助教学CMI:计算机管理教学CAD:计算机辅助设计CAT:计算机辅助翻译CAM:计算机辅助制造CAE:计算机辅助工程计算机的分类:1)、根据规模大小分类:巨型机、大型通用机、微型机、工作站、服务器2)、根据用途分类:通用计算机、专用计算机3)、根据计算机处理数据的类型:模拟计算机、数字计算机、数字与模拟计算机计算机科学研究与应用人工智能:研究如何让计算机来完成过去只有人才能做的智能的工作。网格计算:专门针对复杂科学计算的新型计算模式。中间件技术:是介于应用软件和操作系统之间的系统软件。云计算:是分布式计算、网格计算、并行计算、网络存储及虚拟化计算机和网络技术发展融合的产物,或者说是它们的商业实现。
  • C线性链表
    线性链表的概念线性链表是一种数据结构,它由一系列节点组成,每个节点包含两部分:数据域和指针域。数据域存储实际数据,而指针域存储指向下一个节点的地址,也称为后继节点。线性链表中的节点在内存中并不需要连续存储,而是通过指针相互连接形成一个逻辑上的连续序列线性链表的特点线性链表的主要特点包括:动态性:线性链表的存储空间可以根据需要动态地分配和释放,这使得链表的长度可以随时改变。非连续性:线性链表中的节点在内存中可以分散存储,不需要像数组那样连续排列。访问特性:在链表中访问特定元素通常需要从头节点开始遍历,因此访问效率不如数组。插入和删除效率:在链表中插入或删除元素通常只需要修改相应的指针,而不需要移动其他元素,因此在某些情况下比数组更高效。线性链表的实现线性链表可以通过编程语言提供的各种数据类型和结构来实现。例如,在C++中,可以通过结构体和指针来实现链表节点和链表本身。链表节点通常定义为一个结构体,其中包含了数据和指向下一个节点的指针。链表本身则可以通过一个指向头节点的指针来实现线性链表的应用线性链表广泛应用于各种场景,尤其是在需要频繁插入和删除操作的数据结构中。例如,它可以用来实现动态数组、栈、队列等数据结构。在这些应用中,链表的动态性和灵活性使其能够有效地管理数据元素的增删操作。注意事项在使用线性链表时,需要注意内存管理和指针操作的正确性。错误的指针操作可能会导致内存泄漏或程序崩溃。此外,由于链表不支持随机访问,访问特定元素通常需要从头节点开始遍历,这可能影响性能。综上所述,线性链表是一种基本且重要的数据结构,它在许多编程问题中都有应用。了解其特性和实现方法对于掌握数据结构和算法的基础知识至关重要。已知非空线性链表第1个链结点指针为list,链结点构造为struct node{datatype data;node *link;};请写一算法,将该链表中数据域值最大的那个点移到链表的最后面。(假设链表中数据域值最大的链结点惟一)(注意:要求先写出算法的解题思路,然后再写出算法)【输入形式】输入为一个整数序列,整数之间以空格隔开,序列以回车结尾。【输出形式】输出为移动后的整数序列,整数之间以空格隔开,序列以回车结尾。【样例输入】312 4951【样例输出】3495112【样例说明】将序列中最大的数字12移动到序列最后。【评分标准】本题必须采用链表来实现移动操作,其他方法不得分。#include <stdio.h>#include <stdlib.h>struct Node { int data; struct Node* next;};int main(){ struct Node* head, *tempHead; int data; char flag; head = (struct Node*)malloc(sizeof(struct Node)); scanf("%d", &data); head->data = data; flag = getchar(); head->next = NULL; tempHead = head; while (flag != '\n') { scanf("%d", &data); flag = getchar(); tempHead->next = (struct Node*)malloc(sizeof(struct Node)); tempHead = tempHead->next; tempHead->data = data; tempHead->next = NULL; } struct Node* maxPtr, *endPtr; int maxData = head->data; maxPtr = endPtr = head; while (endPtr->next != NULL) { endPtr = endPtr->next; if (endPtr->data > maxData) { maxData = endPtr->data; maxPtr = endPtr; } } data = maxPtr->data; maxPtr->data = endPtr->data; endPtr->data = data; tempHead = head; while (tempHead != NULL) { printf("%d ", tempHead->data); tempHead = tempHead->next; } return 0;
  • Linux基础与服务器架构综合小实践
    请根据要求在MINI-Linux或GUI-Linux的终端窗口中依次完成以下操作(系统:Red Hat Enterprise Linux 6.5)Linux用户和用户组概述在Linux操作系统中,用户和用户组是两个非常重要的概念。用户是指那些有权限访问和使用系统资源的实体,而用户组则是具有相同特征用户的逻辑集合。Linux用户Linux系统是一个多用户多任务的分时操作系统,任何一个要使用系统资源的用户,都必须首先向系统管理员申请一个账号,然后以这个账号的身份进入系统。用户的账号一方面可以帮助系统管理员对使用系统的用户进行跟踪,并控制他们对系统资源的访问;另一方面也可以帮助用户组织文件,并为用户提供安全性保护。Linux用户组用户组是具有相同特征用户的逻辑集合。在Linux系统中,我们可以将多个用户分配到一个组中,然后对这个组进行权限设置,这样就可以实现对组内所有用户的统一管理4。此外,用户也可以属于多个用户组,从而获得这些组的共同权限。用户和用户组的管理在Linux系统中,用户和用户组的管理是非常重要的。用户的管理包括用户的添加、删除和修改,而用户组的管理则包括用户组的增加、删除和修改。这些操作通常是通过一些特定的命令来实现的,例如useradd用于添加用户,userdel用于删除用户,groupadd用于增加用户组,groupdel用于删除用户组等。总的来说,Linux用户和用户组是Linux系统管理的重要概念,它们不仅关系到系统的安全性,也关系到系统的效率和易用性。因此,理解和掌握这两个概念对于Linux系统的管理和维护是非常重要的。一、创建用户组与用户用户组与用户名中112用户组信息表序号用户组GID1tech11266662market1127777用户信息表序号用户名密码UIDGID1tom11216666166662jack11216666266663bruce1121777717777root用户登录系统,按照以上两表中的信息创建用户组与组户,完成操作,截图1张,图中仅呈现所创建的两个用户组与三个用户信息,不显示其他用户组或其他用户信息。二、目录与文件权限目录信息表序号路径类型权限所有者1/midterm/目录777root2/midterm/tech/目录775tom1123/midterm/tech/net.c文件754tom112注:net.c文件中添加1-3行文本。(1)根据上表信息完成目录与文件的相关操作之后,截图1张,图中呈现相关目录与文件的权限、所有者信息。截图2-1——目录与文件创建(2)切换至用户bruce112,进入目录/midterm/tech/之后,尝试以下操作:(1)创建文件abc;(2)读取net.c文件内容;(3)向net.c中添加文本;(4)删除net.c文件。完成操作,填表并截图1张。用户操作对象操作结果(Y/N)bruce112目录/midterm/tech/创建文件N文件/midterm/tech/net.c读取Y添加文本N删除N截图2-2——其他组用户操作权限测试(3)切换至用户jack112,进入目录/midterm/tech/之后,尝试以下操作:(1)创建文件abc;(2)将abc改名为a123;(3)删除文件a123;(4)读取net.c文件内容;(5)向net.c中添加文本;(6)删除net.c文件。完成操作,填表并截图1张。用户操作对象操作结果(Y/N)jack112目录/midterm/tech/创建文件abcY文件/midterm/tech/abc改名Y文件/midterm/tech/a123删除Y文件/midterm/tech/net.c读取Y添加文本N删除Y截图2-3——同组用户操作权限测试三、文件隐藏属性(1)切换至root用户,在/midterm/目录中新建文件a112.c,添加2-3行文本。为文件a112.c增加append属性,查看确认新增属性。尝试对文件a112.c执行以下操作:改名、覆盖添加文本、追加文本、创建链接文件、删除等操作。完成操作,填表并截图1张。属性操作对象操作结果(Y/N)appenda112.c改名N覆盖添加文本N追加文本Y创建硬链接文件N创建软链接文件Y删除N截图3-1——文件append属性测试(2)为文件a112.c去掉append属性,增加i属性,查看确认新增属性。尝试对文件a112.c执行以下操作:改名、覆盖添加文本、追加文本、创建链接文件、删除等操作。完成操作,截图1张。属性操作对象操作结果(Y/N)ia112.c改名N覆盖添加文本N追加文本N创建硬链接文件N创建软链接文件Y删除N截图3-2——文件i属性测试3)自行设计操作步骤,测试文件A属性的作用。完成操作,截图1张。截图3-3——文件A属性测试属性A锁定其访问时间,但是touch依旧可以更改,且vi保存退出后其属性消失了。
  • 数码管的动态显示
      多个数码管显示数字的时候,我们实际上是轮流点亮数码管(一个时刻内只有一个数码管是亮的),利用人眼的视觉暂留现象(也叫余辉效应),就可以做到看起来是所有数码管都同时亮了,这就是动态显示,也叫做动态扫描。      那么一个数码管需要点亮多长时间呢?也就是说要多长时间完成一次全部数码管的扫描呢(很明显:整体扫描时间=单个数码管点亮时间*数码管个数)      答案是: 10ms以内。当电视机和显示器还处在CRT(电子显像管)时代的时候,有一句很流行的广告语——“100Hz无闪烁”,没错,只要刷新率大于100Hz,即刷新时间小于10ms,就可以做到无闪烁,这也就是我们的动态扫描的硬性指标。那么你也许会问,有最小值的限制吗?理论上没有,但实际上做到更快的刷新却没有任何进步的意义了,因为已经无闪烁了,再快也还是无闪烁,只是徒然增加CPU的负荷而已(因为1秒内要执行更多次的扫描程序)。所以,通常设计程序的时候,都是取一个接近10ms,又比较规整的值就行了。6 个数码管,目标还是实现秒表功能,只不过这次有 6 个位了,最大可以计到 999999 秒#include <reg52.h>sbit ADDR0 = P1^0;sbit ADDR1 = P1^1;sbit ADDR2 = P1^2;sbit ADDR3 = P1^3;sbit ENLED = P1^4;unsigned char code LedChar[ ] = {//数码管显示字符转换表 0xc0,OxF9,OxA4,0xB0,ox99,0x92,0x82,OxF8,0x80,0x90,0x88,0x83,0xC6,OxA1,0x86,0x8E};unsigned char LedBuff[6] = {//数码管显示缓冲区,初值0xFF确保启动时都不亮 0xFF,OxFF,OxFF,OxFF,OxFF,OxFF};void main (){unsigned char i = 0; //动态扫描的索引unsigned int cnt = 0; //记录T0中断次数unsigned long sec = 0; //记录经过的秒数ENLED =0 ; //使能u3,选择控制数码管ADDR3 = l; //因为需要动态改变ADDR0-2的值,所以不需要再初始化了TMOD = 0x01; //设置T0为模式1TH0 = 0xFC; //为T0赋初值OxFC67,定时1msTL0= Ox67;TRO= l; //启动T0while (1){ if(TFO== 1) //判断T0是否溢出 { TFO = 0 ; //T0溢出后,清零中断标志 TH0 = 0xFC; //并重新赋初值 TL0 = 0x67; cnt++;//计数值自加1 if (cnt >=1000)//判断T0溢出是否达到1000次 { cnt = 0 ; //达到1000次后计数值清零 sec++;//秒计数自加1//将sec按十进制位从低到高依次提取并转为数码管显示字符LedBuff[0]= Ledchar [sec%10] ; LedBuff [ 1]= LedChar [ sec/10%10]; LedBuff [2]= LedChar [sec/100%10] ; LedBuff[3] = LedChar [sec/ 1000%10]; LedBuff [4]= LedChar [sec/ 10000%10]; LcdBuf[5] = LcdChar [scc/100000%10]; }//完成数码管动态扫描刷新if (i == 0 ){ADDR2=0 ; ADDR1=0; ADDRO=0 ; i++; PO=LedBuff [0]; }else if (i == 1){ ADDR2=0; ADDR1=0; ADDRO=1; i++;PO=LedBuff 「11; 1else if (i -= 2){ADDR2=0; ADDR1=1; ADDRO=0; i++; PO=LedBuff[2];}else if (i == 3 ){ADDR2=0; ADDR1=1; ADDRO=1; i++; PO=LedBuff[3]; }else if (i == 4){ADDR2=l; ADDRl=0; ADDRO=0; i++; PO=LedBuff[ 4 ];}else if (i== 5){ADDR2=1; ADDR1=0; ADDRO=1; i=0; PO=LedBuff[5];} } }}      其中下边的 if...else 语句就是每 1ms 快速的刷新一个数码管,这样 6个数码管整体刷新一遍的时间就是 6ms,视觉感官上就是 6 个数码管同时亮起来了。 
  • Linux磁盘配额小实践
    磁盘配额(Disk Quotas)是一种在计算机中限制用户对磁盘空间使用的机制。在多用户环境下,为了防止部分用户占用大量磁盘空间,导致其他用户无法正常使用,管理员可以为每个用户设定一个磁盘使用上限,即配额。一旦用户达到了这个上限,系统将阻止其继续使用更多的磁盘空间,并可能记录事件。这种机制有助于管理员有效地管理磁盘资源,保证系统的稳定运行。1、实现磁盘限额的条件需要Linux内核支持安装quota软件包2、Linux磁盘限额的特点作用范围:针对指定的文件系统(分区)限制对象:用户帐号、组帐号限制类型:磁盘容量(默认单位为KB)文件数量限制方法:软限制、硬限制 在RHEL6系统中,内核已经制定了支持Linux文件系统的磁盘配额功能,而且在系统中默认安装了quota软件包,用于配置和管理磁盘配额实现步骤:1、启用/dev/sdb1的配额支持vi /etc/fstab /dev/sdb1 /mailbox ext4 defaults,usrquota,grpquota 0 02、重新挂载mailboxmount /dev/sdb1 /mailbox mount -o remount /mailbox mount | tail -13、检测磁盘配额并创建配额文件 (如出现报错则使用命令关闭selinux,命令为:setenforce 0)setenforce 0 quotacheck -ugcv /dev/sdb1 ls -l /mailbox/aquota.*4、增加用户useradd jc5、修改用户XXX密码6、启用/mailbox的配额功对用户jc在/mailbox目录上实现软限制为2个文件,硬限制为3个文件的磁盘配额setquota -u jc 1000M 1000M 2 3 /mailboxquotaon -ugv /mailbox7、验证XXX磁盘配额功能,创建三个文件$touch 1 2 3,如再创建第四个文件报错测试前记得以管理员身份修改权限chmod 777 /mailbox8、查看配额使用情况注意事项磁盘配额限制的是用户对磁盘空间的使用,而不是文件的数量。管理员用户(如root)通常不受磁盘配额的限制。磁盘配额对于防止恶意用户占用过多磁盘空间非常有用。磁盘配额可能会导致用户达到限制后无法继续存储数据,因此应当合理设置。实际应用案例磁盘配额在实际应用中十分广泛,例如在企业环境中,管理员可以为员工设定一定的磁盘使用上限,防止个人占用过多的公司资源。在学校环境中,教师和学生可能被限制在特定的磁盘空间内存储文件,以避免过度消耗学校的存储资源。综上所述,磁盘配额是一种重要的系统管理工具,它可以帮助管理员有效地控制用户对磁盘空间的使用,保障系统的稳定性和资源的合理分配。无论是在Windows系统还是Linux系统中,管理员都可以通过相应的工具来实现磁盘配额的功能。
  • NUMA架构笔记分享
    NUMA架构简介NUMA(Non-Uniform Memory Access)架构是一种计算机架构,主要用于改善多处理器系统中的内存访问性能。与传统的SMP(Symmetric Multi-Processing)架构相比,NUMA架构的主要特点在于它将内存和处理能力分布在不同的节点上,每个节点有自己的内存和处理器,并通过高速互连网络相互连接。在NUMA架构中,处理器可以更快地访问本地内存,而访问其他节点上的内存则需要通过互连总线,这可能带来额外的访问延迟。NUMA架构下的内存访问控制器在NUMA架构中,每个节点通常包含一个或多个处理器以及相应的本地内存。这些处理器和内存由一个内存访问控制器(Memory Access Controller)所控制。在某些情况下,内存控制器可能集成在CPU内部,而在其他情况下,它们可能是作为独立组件存在的。每个节点的内存控制器负责管理该节点的内存访问,使得处理器能以最有效的方式访问本地内存。。NUMA架构中内存访问控制器的数量NUMA架构并不是单一内存访问控制器的架构。相反,它允许多个内存访问控制器分布在不同的节点上。每个节点可以拥有自己的内存访问控制器,从而实现对本地内存的高速访问。这一点可以从多个来源得到证实,其中包括对NUMA架构的描述、内存访问控制器的作用以及如何在NUMA架构下配置内存访问控制器的说明结论综上所述,NUMA架构下并非只有一个内存访问控制器,而是每个节点都可以拥有自己的内存访问控制器。因此,原始问题的表述“NUMA架构下只有一个内存访问控制器”是不正确的。实际情况是,在NUMA架构中,每个节点通常都有一个或多个内存访问控制器,它们负责处理该节点的内存访问,从而优化内存访问性能和系统的整体性能
总条数:98 到第
上滑加载中