• 常用的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架构中,每个节点通常都有一个或多个内存访问控制器,它们负责处理该节点的内存访问,从而优化内存访问性能和系统的整体性能
  • NUMA-Aware亲和性优化
    NUMA-Aware亲和性优化是否为硬件加速方式概述NUMA-Aware亲和性优化是一种针对非均匀内存访问(NUMA)架构的优化技术,旨在改善多核处理器对内存的访问效率。这种优化策略尝试将任务分配到能够更快地访问所需内存的CPU核心上,从而减少内存访问的延迟。NUMA架构简介在NUMA架构中,每个CPU核心被分配一部分内存,称为本地内存。相较于访问非本地内存,CPU核心访问本地内存的速度更快。这是因为非本地内存可能需要通过跨CPU或跨内存控制器的方式进行访问,而本地内存则可以直接从CPU核心旁边的内存控制器中读取或写入。NUMA-Aware亲和性优化的原理NUMA-Aware亲和性优化涉及操作系统或应用程序的优化,使得特定的任务能够优先在拥有较快本地内存访问能力的CPU核心上执行。这样的优化可以减少因为内存访问延迟而造成的性能瓶颈。硬件加速方式硬件加速通常指的是利用硬件特性来提高数据处理的速率,例如使用专门的硬件加速器或指令集来处理特定类型的运算。与软件层面的优化相比,硬件加速通常是在硬件层面进行的,可以提供更直接的性能提升。NUMA-Aware亲和性优化的实施方法实施NUMA-Aware亲和性优化的一种常见方法是使用numactl工具或在应用程序代码中设置CPU亲和性。这些方法可以有效地将进程绑定到特定的CPU核心,确保任务运行在拥有最优内存访问性能的CPU上。综合分析根据以上信息,我们可以得出结论,NUMA-Aware亲和性优化更多地是一种软件层面的优化策略,而非硬件加速方式。它通过优化任务在CPU核心间的分配来提升性能,并不是直接通过硬件来实现加速。因此,认为NUMA-Aware亲和性优化是一种硬件加速方式是不正确的。结论综上所述,NUMA-Aware亲和性优化是一种有效的软件优化技术,它通过合理分配任务到具有更好内存访问性能的CPU核心上来提高整个系统的性能。但它不属于硬件加速方式,因为它不依赖于硬件特有的加速功能,而是依赖于软件层面的任务管理和CPU亲和性设置。
  • GaussDB分布式与单机模式的比较
    GaussDB分布式与单机模式的比较优点分布式模式高可用性: 分布式数据库通过冗余存储和自动故障转移提高了系统的可用性。即使在某个节点出现故障的情况下,其他节点也可以继续提供服务,从而保证了服务的持续可用。更好的资源利用: 分布式数据库可以跨多个服务器部署,这使得它可以更有效地利用硬件资源,尤其是在处理大规模数据集或高并发请求时。易于扩展: 分布式数据库更容易进行水平扩展,即增加更多的节点来提升系统的处理能力和存储容量。单机模式简单易用: 单机模式下的GaussDB可能比分布式模式更易于管理和维护,因为它涉及到的组件和配置较少。快速响应: 在数据量不是特别大的情况下,单机模式的GaussDB可能能更快地响应用户的请求,因为所有数据都在本地存储和处理。缺点分布式模式复杂性: 分布式数据库的设计和维护可能比单机模式更复杂,因为它涉及到数据的一致性、同步和故障转移等问题。成本: 分布式数据库可能需要更多的硬件资源和网络带宽,这可能会增加整体的运营成本。单机模式扩展性有限: 如果数据量和并发请求增大,单机模式的GaussDB可能难以满足需求,因为它受限于单个服务器的处理能力和存储空间。可用性风险: 单机模式的GaussDB在面临硬件故障或维护活动时,可能导致整个系统不可用,这在分布式模式下可以通过故障转移机制避免。总结GaussDB的分布式模式相比于单机模式,提供了更高的可用性、更好的资源利用率和易于扩展等优点,但也带来了更高的复杂性和可能的成本。相比之下,单机模式的GaussDB在简单易用和快速响应方面有一定的优势,但在扩展性和可用性方面存在局限性。根据具体的业务需求和资源情况,可以选择适合的模式
  • 中断源类型详解
    SPI (Shared Peripheral Interrupt)SPI 是一种共享中断,所有 CPU 核心都可以响应的公共中断源。SPI 适用于多数外部设备中断,如按钮按下、传感器信号等。SPI 在 GIC(Generic Interrupt Controller)架构中被广泛使用,并且在多核处理器中,SPI 可以被任意一个 CPU 核心响应。PPI (Private Peripheral Interrupt)PPI 是私有中断,仅由特定 CPU 核心响应。PPI 常用于 CPU 特定的功能,比如本地定时器中断。在多核处理器中,每个核心可能有自己独特的 PPI 来源。SGI (Software-generated Interrupt)SGI 是由软件生成的中断,主要用于多核之间的通信。例如,一个 CPU 可以通过写入 GIC(Generic Interrupt Controller)的寄存器来触发另一个 CPU 响应中断。SGI 在多核环境下用于进程间通信(IPI)。LPS (Local Peripheral Interrupt)LPS 是局部中断,主要用于同一场所内的中断通信。LPS 在 GICv3 架构中引入,其特点是中断路由上的不同,它基于消息的中断,配置保存在表中而不是寄存器。LPS 的一个例子是 PCI Express 的 MSI/MSI-x 中断。总结综上所述,我们可以看到 SPI、PPI、SGI 和 LPS 都是中断控制器处理的中断源类型。其中,SPI 和 PPI 是基于硬件的外设中断,而 SGI 则是基于软件触发的中断。LPS 作为 GICv3 的新特性,是基于消息的中断,它的配置和中断源不同于前三者。由于 SGl 并不存在于已知的中断源类型中,因此我们可以得出结论,它不属于中断控制器处理的中断源。
  • 存储服务2024.3月技术干货&资讯合集
    技术干货python多线程https://bbs.huaweicloud.com/forum/thread-0292146735777295033-1-1.html存储磁盘阵列 RAID5小实践https://bbs.huaweicloud.com/forum/thread-02127146736116279031-1-1.html操作系统发展与概述笔记分享https://bbs.huaweicloud.com/forum/thread-0229146736192282026-1-1.html常用的RPM管理工具笔记https://bbs.huaweicloud.com/forum/thread-0282146736263599024-1-1.htmlBios和Coms的联系和区别https://bbs.huaweicloud.com/forum/thread-02109146736335233022-1-1.html同时同频全双工技术https://bbs.huaweicloud.com/forum/thread-0282146736464324026-1-1.html逻辑电路与逻辑运算笔记分享https://bbs.huaweicloud.com/forum/thread-02109146888993731002-1-1.htmlPython应用发布常见打包https://bbs.huaweicloud.com/forum/thread-0276146889049485005-1-1.htmlNAPT特性与配置实践分享https://developer.huaweicloud.com/usercenter/mycommunity/forum-topic计算技术的发展趋势笔记https://bbs.huaweicloud.com/forum/thread-02110146889172331003-1-1.html网站、网页与HTML文档笔记分享https://bbs.huaweicloud.com/forum/thread-0274146889904776004-1-1.html小白学习Linux的学习建议和阶段https://bbs.huaweicloud.com/forum/thread-0274146988740636014-1-1.html资讯资讯|全国首个”工业软件产教融合协同育人基地”正式揭牌,开启工业软件人才培养新篇章https://bbs.huaweicloud.com/forum/thread-02110146889741172004-1-1.html资讯|分布式数据库技术的演进和发展方向https://bbs.huaweicloud.com/forum/thread-0274146889493751003-1-1.html【话题交流】存储知识学习书屋讨论https://bbs.huaweicloud.com/forum/thread-02127146736552549032-1-1.html
  • 小白学习Linux的学习建议和阶段
        linux 是一个开源、免费的操作系统 ,其稳定性、安全性 、处 理多并发已经得到业界的认可,目前很多中型,大型甚 至是集群项 目都在使用 linux, 很多软件公司考虑到开发成本 都首 选 linux, 在中国软件公司得到广泛的使用 。       近些年来linux在嵌入式领域的应用得到了飞速的提高linux 运行稳定、对网络的良好支持性、低成本,且可以根据需要进行软件裁剪,内核最小可以达到几百KB 等特点,使其近些年来在嵌入式领域的应用得到非常大的提高主要应用:机顶盒、数字电视、网络电话、程控交换机、手机、PDA、智能家居、智能硬件等都是其应用领域。以后再物联网中应用会更加广泛。我认为学习 linux 流程: 第1 阶段 : linux环境下的基本操作命令,包括 文件操作命令(rm mkdir chmod, chown) 编辑工具使用(vi vim)linux用户管理(useradd userdel usermod)等第2 阶段 : linux的各种配置(环境变量配置,网络配置,服务配置)第3 阶段 : linux下如何搭建对应语言的开发环境(大数据,JavaEE, Python等)第4 阶段 : 能编写shell脚本,对Linux服务器进行维护。第5 阶段 : 能进行安全设置,防止攻击,保障服务器正常运行,能对系统调优。第6 阶段 : 深入理解Linux系统(对内核有研究),熟练掌握大型网站应用架构组成、并熟悉各个环节的部署和维护方法。一些基本的指令:(1)cd命令cd :切换目录用法:cdcd ../ 切换到上级目录cd /   切换到根目录cd ~  (或只有cd )切换到当前用户主目录(home底下以用户名命名的文件夹) /root目录mkdir 创建目录mkdir 目录名  -p   递归创建目录(2)rm删除文件用法:rmdir 目录名也可用:rm -rf 目录名(3)ls命令查看目录或文件信息主要选项:-l 列出目录或者文件的详细信息。比如权限、修改时间等等-a 列出当前目录下所有文件,包括隐藏文件(已点开头的都是隐藏文件)(4)万能文本编辑vi/vim命令i 进入编辑状态退出编辑按ESC键不保存退出: :q!保存退出:   :wq输入/,进入搜索输入:set nu,显示每一行的行数按键盘G,可以直接定位到最末尾(5)cp复制和mv移动命令用法:cp [选项]文件名或目录  目标地址-R 拷贝目录及目录下所有目录和文件cp a.txt  b.txt   #将a文件复制,且另命名为b文件(目录名)(6)| 管道符 (竖线,英文输入法状态下shift+键盘上的的|\)在命令之间建立管道,将前面命令的输出作为后面命令的输入#通过命令查找tomcat进程 ps -ef | grep tomcat #通过命令查找到占用此端口的进程编号 netstat -apn|grep 3306(7)tar 解压,压缩tar.gz#将test文件夹压缩成 tar -czvf test.tar.gz test #将test.tar.gz解压得到test文件夹 test.tar.gztar -xzvf test.tar.gz(8)zip 解压,压缩zip#将test文件夹压缩成test.zip,必须带r 才会把文件压缩进去,不然会生成一个空的文件夹 zip –r test.zip test #将test.zip文件夹解压 unzip test.zip(9)关闭防火墙#开启 service iptables start #关闭 service iptables stop永久关闭防火墙#开启 chkconfig iptables on  #关闭 chkconfig iptables off
  • 网站、网页与HTML文档笔记分享
    网站>网站用于集中提供各种相关的网页。网页>主页,指网站中的首页,通常命名为index.*。当URL中不包含文件名时,即访问网站的主页。HTML文档>      超文本标记语言或超文本链接标示语言(标准通用标记语言下的一个应用)HTML(HyperText Mark-up Language)是一种制作万维网页面的标准语言,是万维网浏览器使用的一种语言,它消除了不同计算机之间信息交流的障碍。      它是目前网络上应用最为广泛的语言,也是构成网页文档的主要语言。HTML文件是由HTML命令组成的描述性文本,HTML命令可以说明文字、图形、动画、声音、表格、链接等。HTML文件的结构包括头部(Head)、主体(Body)两大部分,其中头部描述浏览器所需的信息,而主体则包含所要说明的具体内容。<!DOCTYPE html><html><head><meta   charset="UTF-8"><title>页面标题</title></head><body>我是快乐的小男孩<img src="images/boy.gif"   /></body></html>经浏览器解析后呈现为超媒体页面,如图:
总条数:91 到第
上滑加载中