Basic Facts公证需要预约，美驻华使领馆网站有专门的页面介绍公证服务，预约入口在那里，预约需要用护照，到现场也要带上所有电子产品都带不进办公区，但安检处可以免费存包，如果你害怕人多，附近有好几个丰巢柜，2块钱一小时使领馆的华裔工作人员都是普粤英三语精通，沟通无障碍公证收费按章计算，盖一个50刀，需要盖几个就交几个的钱领馆只管公证，不管文件内容，不能也不会解释文件内容付费只收现金（人民币/美金，使馆现行汇率7.4）、Mastercard/Visa银行卡预约流程在上面提到的页面进到预约入口。选好国家、城市，下一个页面选择“Make Appointment!"，然后就到选择服务类型的页面，选择第三个"Request notarial and other services not listed above."（公证和未列出的其他服务），勾选最下面的对话框，提交，就跳到日历，离笔者最近的总领馆是广州，周一、二、四有服务，选完就跳到选具体时段、写个人信息的页面，然后提交就完成预约。注意！预约完成的页面需要打印出来，后面的步骤会用到。现场流程带上要公证的文件、打印的预约信息和护照，地铁3/5号线珠江新城B1口，过了马路就是领馆入口。首先会有一位安保看你身份证和预约信息，通过后会有另一位警察用带摄像头的柜式机再次核对你的身份证是不是本人，然后一直往里走到安检处，会有领馆职员检查你的护照和预约信息，然后过安检，带了包的在这里把所有电子产品拿出来，会放到墙上一堆小格子的其中一个，包就放到他们柜台里面的地上，会给一个手牌，出来的时候凭手牌取回。安检后一直走到办公区二楼（只有一条路），会有工作人员指引先到10号窗取号，给预约截图和护照，窗口会问要公证的材料和目的，然后在护照上贴号码，坐着等叫号（声音贼大），窗口会再问一遍材料和目的，然后把材料收走，给缴费单，拿着缴费单去旁边的缴费窗交钱（这位好像只会英语），交完以后把单交回窗口，然后继续等叫号（都会去2号窗的）。叫到后会核对你的姓名，然后在你要公证的文件上签字、盖章。我申请ITIN所以公证护照复印件，使馆就给出了带钢印的证明，和复印件钉在一起。然后就搞定了，拎着文件走人吧﻿
本文所采用chatGPT模型，为openai为chatGPT Plus用户提供的GPT-4。本文使用的chatGPT版本为ChatGPT May 24 Version本文所采用conda版本为23.3.1，python版本为3.10.6需求概述这个活是在某个月黑风高的晚上，莫名其妙到我手上的。简单来说，手上有一份word格式题库，需要在这份题库里面抽取题目出成卷子。时间很赶，需要在短时间内出两套结构相同，题目不一样的卷子。题库的结构如下图：可以看到这东西将近一百页（其实满打满算正好一百页）的体量，已经让我根本不想去翻。再粗略翻了以下，发现里面有好几个题型，每个题目还指向一个知识点。想要出一张涵盖所有题型和知识点的题目，光是卷面题型安排就已经能把我累死，更别说题目随机性的事情了。更何况干这个活又没有加班费……但是这个活不干也不行，毕竟刚刚入职，哪个比我大的都是我老板。能不能用一些自动化工具来帮我干呢？Python是个好东西，之前为了捣鼓stable diffusion，电脑上也有miniconda环境，但是我不会写python啊。没有关系，chatGPT是会的。磕磕碰碰的开始通过观察，题库中同一题型的题目都放在了一起，以形如“〖判断题〗”这样的文字分隔不同题型的段落，每个题目都是以下格式：试题编号：[6位数字，各不相同]知识点：[某个知识点，大量重复][题目本身及答案]由于每个题型的题目写法都不一样，和最终试卷上的格式也有很大不同，因此，这次我并不追求全自动化出卷，只需要抽题，抽完了我再去题库里找出来手动处理。抛给GPT的第一个问题是：我想在word中某个章节统计"知识点："后各单词的出现频率。啪的一下，很快啊，它就给了我一个回答：在 Word 文档中统计某些特定单词或短语的频率需要使用一些特定的工具，比如脚本或者宏。但是，Word 自身并没有提供这种功能。一个可能的方案是使用 Python，一个被广泛使用的编程语言，来处理 Word 文档并统计单词的频率。这种方法的一个关键部分是使用 python-docx 库来读取 Word 文档。然后你可以使用 Python 的 collections 库中的 Counter 类来统计单词的频率。下面是一个基本的 Python 脚本，它可以打开一个 Word 文档并统计在"知识点："之后的各单词出现的频率：from docx import Document from collections import Counter def count_words_after_keyword(doc_path, keyword): doc = Document(doc_path) counter = Counter() for para in doc.paragraphs: if keyword in para.text: words_after_keyword = para.text.split(keyword)[1].split() counter.update(words_after_keyword) return counter # 替换以下路径为你的文档路径 doc_path = "your_document.docx" keyword = "知识点：" counter = count_words_after_keyword(doc_path, keyword) # 打印单词及其频率 for word, freq in counter.items(): print(f"{word}: {freq}")你需要先安装 python-docx 库才能运行上述代码。你可以通过在命令行中运行 pip install python-docx 来安装。注意，这个脚本并不完美，因为它只检查每一段落中的 "知识点：" 关键词。如果 "知识点：" 在一个段落中出现多次，或者跨越多个段落，那么这个脚本可能就不能正确地工作了。为了处理这些更复杂的情况，你可能需要写一个更复杂的脚本，或者使用更复杂的工具。当时就把我惊呆了，它建议我用python，与我的需求不谋而合（prompt里完全没提），不仅给出了代码，这代码里面甚至还有注释，还将变量单独抽了出来以方便修改，还告诉了我要装什么库，这可用性也太强了吧！因为题库文档里不止这一百多页的题目（这个文档六百多页），我想把这一部分单独拎到新的word文档上处理，但我又不想在word里面拉呀拉呀拉，于是我问了GPT第二个问题：我想将word文档中其中100页的内容存到另一个word上。如果你想将 Word 文档中的某些页面复制到另一个 Word 文档，你可以手动做，也可以使用Python脚本自动化这个过程。这个Python脚本将使用python-docx库来处理 Word 文档。但是，你需要知道的是，python-docx并没有直接提供处理页码的功能，因为 Word 文档的页数取决于许多因素，如页面大小，字体大小，间距等。因此，如果你是按照固定的段落数量（例如100个段落代表100页）来处理的话，可以使用如下的Python脚本：from docx import Document # 打开源文档 source_doc = Document('source.docx') # 创建新文档 new_doc = Document() # 设置要复制的段落数量 num_paragraphs = 100 # 复制段落 for i in range(num_paragraphs): if i < len(source_doc.paragraphs): text = source_doc.paragraphs[i].text new_doc.add_paragraph(text) # 保存新文档 new_doc.save('new_doc.docx')在这个脚本中，我们打开源文档，然后创建一个新的文档。然后，我们复制源文档的前100个段落到新的文档。最后，我们保存新的文档。这个脚本可能不完全符合你的需求，因为它是按段落而不是按页面来复制的。如果你确实需要按页面来复制，你可能需要使用其他的工具或者手动复制。如果你可以明确每一页大概有多少段落，那么你可以修改脚本中的num_paragraphs变量来达到你想要的效果。我并不能确定一段有多少段落，所以当时就放弃了用python去复制文档，真的去手动拉了。现在想想，完全可以用一级标题到一级标题的方式去确定复制的范围，让python自个儿去数就好了。当我返回去执行第一个回答的代码的时候，python直接给我抛了个错：ImportError: cannot import name 'Document' from partially initialized module 'docx'我又去问了GPT，它告诉我：这个错误可能是由于你的Python环境中存在命名冲突，或者python-docx模块没有正确安装。以下是一些可能的解决方法：检查模块安装情况：确保python-docx模块已经正确安装。你可以在Python环境中运行以下命令来检查已安装的模块：pip list如果你看不到python-docx在列表中，那么你需要安装它：pip install python-docx避免命名冲突：确保你的Python脚本的文件名或者其所在的目录名没有与docx模块发生冲突。换句话说，你的脚本文件名不应该是docx.py，也不应该在名为docx的目录下。否则Python在导入模块时可能会混淆你的脚本和python-docx模块。检查Python环境：确保你在运行脚本的Python环境中安装了python-docx模块。如果你有多个Python环境（例如，一个系统级别的Python和一个或多个Python虚拟环境），那么你需要确保你在运行脚本的那个环境中安装了python-docx模块。以上都是可能的解决方案，如果这些都无法解决问题，你可能需要更深入地检查你的Python环境或代码。好家伙，我的确把执行任务的py命名成docx.py了，毕竟是处理word文档的py嘛，这么取名也很合情合理……总之，改完名之后，代码顺利运行。从这三次对话中可以发现，GPT可以很好地理解我的需求，给出可用性和可读性都极高的python代码（它甚至加注释），还可以帮我对报错信息做初步判断。只要我不断地追加和修正需求，GPT完全能写出一些开箱即用的东西来。既然能用，那就继续干活。来做亿点点调试先回顾一下这段对话最开始，我给GPT提出的需求：我想在word中某个章节统计"知识点："后各单词的出现频率在这一部分，我只想让告诉我题库里到底有多少题，按照章节、知识点和题型分类统计。在接下来的对话中，我不断追加了各种条件：现在，我需要将统计的结果按照章节标题来划分我的标题都有都以“1.4..”开始，*可能是任何数字在这个的基础上，我还希望统计不同题型的题量。相同题型的题目会放在一起，所以我需要统计两个提醒关键词A和B之间“题目编号”出现的次数，以确定A题型的题目数量我有判断、多选、单选、案例分析、计算和简答六个题型（注：这个条件描述是错误的，后面会提到其实不止这六种，这导致了抽题的时候出现问题）我的题型都是以这种形式划分的“〖判断题〗”keyword中的冒号去掉，文档路径为"1.docx"我希望在输出的时候，按题型统计同一章节的题目数量，另外，将question_keyword更换为"试题编号"到这里，GPT已经给出了一份功能很完整的代码：import re from docx import Document from collections import Counter, defaultdict def count_words_and_questions(doc_path, keyword, question_keyword): doc = Document(doc_path) chapter_counters = {} question_counters = defaultdict(lambda: defaultdict(int)) current_chapter = None current_question_type = None for para in doc.paragraphs: if re.match(r'1\.4\.\d+\.\d+', para.text): # 开始一个新的章节 current_chapter = para.text chapter_counters[current_chapter] = Counter() current_question_type = None elif current_chapter is not None: if keyword in para.text: # 在当前章节中统计单词 words_after_keyword = para.text.split(keyword)[1].split() chapter_counters[current_chapter].update(words_after_keyword) elif question_keyword in para.text: if current_question_type is not None: # 在当前题型中统计题目数量 question_counters[current_chapter][current_question_type] += 1 else: for question_type in ["判断题", "多选题", "单选题", "案例分析题", "计算题", "简答题"]: if question_type in para.text: current_question_type = question_type break return chapter_counters, question_counters # 替换以下路径为你的文档路径 doc_path = "1.docx" keyword = "知识点" question_keyword = "试题编号" chapter_counters, question_counters = count_words_and_questions(doc_path, keyword, question_keyword) # 打印每个章节的单词及其频率以及各题型的题目数量 for chapter in chapter_counters.keys(): print(chapter) for word, freq in chapter_counters[chapter].items(): print(f"{word}: {freq}") # 按照题型排序输出 for question_type in sorted(question_counters[chapter].keys()): print(f"{question_type}数量: {question_counters[chapter][question_type]}")不过这还不是我最后想要的，别忘了我的需求是抽题，这还没抽呢。来，怎么抽首先，我想知道怎么抽题是合适的，这个问题当然也是抛给GPT了：我要出一份卷子，有〖判断题〗", "〖多选题〗", "〖单选题〗", "〖案例分析题〗", "〖计算题〗", "〖简答题〗几个题型，满分一百分，我应该怎样设定分值的题量它给出的方案是：你的需求涉及到6种题型，满分是100分。如何设定分值，这在一定程度上取决于每种题型对于总评价的重要性。以下是一种可能的分配方式：判断题：通常这种题型比较简单，所以可以设定比较低的分值，比如20%的总分，也就是20分。假设每题2分，那么就需要出10个判断题。多选题：这种题型相对复杂一些，可以设定为15%的总分，也就是15分。假设每题3分，那么就需要出5个多选题。单选题：这种题型的难度介于判断题和多选题之间，可以设定为15%的总分，也就是15分。假设每题3分，那么就需要出5个单选题。案例分析题：这种题型的难度较大，需要考生有较强的综合运用知识的能力，可以设定为20%的总分，也就是20分。假设每题10分，那么就需要出2个案例分析题。计算题：这种题型通常也比较难，可以设定为15%的总分，也就是15分。假设每题7.5分，那么就需要出2个计算题。简答题：这种题型需要考生能清晰准确地表述自己的观点，可以设定为15%的总分，也就是15分。假设每题7.5分，那么就需要出2个简答题。以上是一种可能的分配方式，你可以根据实际情况进行调整。好怪异的分数这是和出题方法……看来要调教一下了。这一调教，问题就出来了。我给它指定了判断、单选、多选题的分值：如果判断题、单选题都是1分，多选题2分，又应该怎么分配它给出了一个依然很怪异的回答：如果你希望判断题和单选题都是1分，多选题2分，那么我们需要重新考虑分配方式。假设其余的题型分值保持原样，即案例分析题每题10分，计算题每题7.5分，简答题每题7.5分。那么以下是一种可能的分配方式：判断题：15题，总分15分。单选题：15题，总分15分。多选题：10题，总分20分。案例分析题：2题，总分20分。计算题：2题，总分15分。简答题：2题，总分15分。这样每种题型的数量和分值相加，总分数就是100分。你可以根据实际需要调整题目的数量和分值。又做了一个修正：7.5分太奇怪了，我觉得5分比较合理它终于给出了看上去比较正常的回答：明白你的需求，我们可以将计算题和简答题的分值都调整为5分。然后，相应地调整判断题、单选题和多选题的题量。下面是新的分配方式：判断题：20题，总分20分。单选题：20题，总分20分。多选题：15题，总分30分。案例分析题：2题，总分20分。计算题：2题，总分10分。简答题：2题，总分10分。这样，所有的题型数量和分值相加，总分数仍然是100分。到这里，读者们可能已经发现了，GPT给出的总分数根本不是它说的100分！ 不过当时我还没有发现这个问题，因为我正在处理另一个问题：我看漏题型了。如上所述，这份题库非常的厚，而我之前只是草草翻了一遍，并没有翻到底，实际上除了我上文提到的六种题型之外，还有识绘图题和论述题，一共是八种题型。解决这个事情倒是简单，让GPT加上就行了：我的需求有误，事实上还有识绘图题和论述题我希望识绘图题只有一道我希望识绘图和论述题的分值都是一道5份（没错，就是打错字了，但是GPT还是懂了）了解你的需求。如果识绘图题和论述题每题都是5分，那么我们可以相应地调整其他题型的分值和题量。以下是一个可能的分配方式：判断题：18题，总分18分。单选题：18题，总分18分。多选题：10题，总分20分。案例分析题：2题，总分10分。计算题：2题，总分10分。简答题：2题，总分10分。识绘图题：1题，总分5分。论述题：1题，总分5分。这样，所有的题型数量和分值相加，总分数仍然是100分。这只是一个建议，具体的题目数量和分值可以根据你的实际需求进行调整。这个时候，我也发现事情不对劲了，这个编排下总分压根不是100分。我提醒了一下GPT，结果这货给我整出了加分题。我……算了算了，犯傻是常有的事情，我告诉它没有加分题，它终于给出了一份合理的编排方案，总分也终于是100分了：非常抱歉之前理解有误，感谢你的耐心。现在，我们重新计算一下题目的分配：如果判断题和单选题每题都是1分，多选题每题是2分，而案例分析题、计算题、简答题、识绘图题和论述题每题都是5分，那么分配方式可以是：判断题：20题，总分20分。单选题：15题，总分15分。多选题：10题，总分20分。案例分析题：2题，总分10分。计算题：2题，总分10分。简答题：2题，总分10分。识绘图题：1题，总分5分。论述题：2题，总分10分。这样，所有题型的数量和分值相加，总分数就是100分。这只是一个建议，具体的题目数量和分值可以根据你的实际需求进行调整。从这一轮的对话可以看出，即便是GPT-4模型，在这种数学计算上犯傻的概率依然不低，有时候这种错误没有办法用prompt进行修正（可能是受到了上下文的影响），在使用其输出进行工作前，需要对涉及数字的部分进行核对，以免出现错误。开始抽题有了上面的出题方案，我们可以开始让GPT帮忙写抽题的代码了。在没有发现自己漏了两个题型之前，我将6种题型的方案发给了它：你做得很好，现在，我需要出一份卷子，题目构成如下：判断题：20题，总分20分。单选题：20题，总分20分。多选题：15题，总分30分。案例分析题：2题，总分20分。计算题：2题，总分10分。简答题：2题，总分10分。在刚刚给你的文档中，每个题目都有独一无二的试题编号，我需要从里面随机抽出对应数量的题目，且抽出的题目内容需要和各章节题目数量的比例保持相对一致GPT的回答如下：这是一个有趣的挑战，我们可以在前面的代码的基础上进行修改。首先，我们需要为每个章节和题型创建一个列表来保存每个题目的编号。然后，我们可以根据你给出的每个题型的题目数量，按章节的题目比例，随机选择题目。这是一个可能的解决方案：import re from docx import Document from collections import defaultdict from random import choices def gather_questions(doc_path, keyword, question_keyword): doc = Document(doc_path) chapter_questions = defaultdict(lambda: defaultdict(list)) current_chapter = None current_question_type = None for para in doc.paragraphs: if re.match(r'1\.4\.\d+\.\d+', para.text): # 开始一个新的章节 current_chapter = para.text current_question_type = None elif current_chapter is not None: if question_keyword in para.text: if current_question_type is not None: # 在当前题型中添加题目编号 chapter_questions[current_chapter][current_question_type].append(para.text) else: for question_type in ["判断题", "多选题", "单选题", "案例分析题", "计算题", "简答题"]: if question_type in para.text: current_question_type = question_type break return chapter_questions def select_questions(chapter_questions, target_counts): selected_questions = defaultdict(list) for question_type, target_count in target_counts.items(): chapter_weights = [len(chapter_questions[chapter][question_type]) for chapter in chapter_questions.keys()] for _ in range(target_count): selected_chapter = choices(list(chapter_questions.keys()), weights=chapter_weights, k=1)[0] question = chapter_questions[selected_chapter][question_type].pop() selected_questions[question_type].append(question) chapter_weights = [len(chapter_questions[chapter][question_type]) for chapter in chapter_questions.keys()] return selected_questions # 替换以下路径为你的文档路径 doc_path = "1.docx" keyword = "知识点" question_keyword = "试题编号" chapter_questions = gather_questions(doc_path, keyword, question_keyword) target_counts = {"判断题": 20, "单选题": 20, "多选题": 15, "案例分析题": 2, "计算题": 2, "简答题": 2} selected_questions = select_questions(chapter_questions, target_counts) # 打印选出的题目编号 for question_type, questions in selected_questions.items(): print(question_type) for question in questions: print(question)这个脚本首先创建了一个字典，键是章节和题型，值是该章节和题型的题目编号列表。然后，它根据你给出的目标题目数量，按章节题目比例随机选择题目。需要注意的是，这个脚本假设每个题目编号都在一个单独的段落中，而且每个题目编号都是唯一的。如果你的文档的结构不同，你可能需要对脚本进行一些调整。一如既往的开箱即用，注释齐全，解释清楚，它甚至还说“这是个有趣的挑战”，太好用了真的是……代替程序员有点难，但是提高工作的自动化水平已经是绰绰有余了。因为我之前看漏了两个题型，导致这两个题型的题目被统计入了其他题目里，上面给出的代码抽出的题目有一些是和题型对不上的。我一开始以为是代码的问题，GPT给出的解决方案是在统计每一道题的时候往前遍历它所属的题型（之前的方案是碰到题型关键字开始统计，碰到下一个题型关键字的时候停止统计，开始统计新的题型），但这样一来O(n)的算法直接变成了O(n^2)，跑起来大概是一晚上都跑不完。所幸后来发现了是题型的问题，让GPT改了回来。最终GPT生成的代码如下：import re from docx import Document from collections import defaultdict from random import choices def gather_questions(doc_path, keyword, question_keyword): doc = Document(doc_path) chapter_questions = defaultdict(lambda: defaultdict(list)) current_chapter = None current_question_type = None for para in doc.paragraphs: if re.match(r'1\.4\.\d+\.\d+', para.text): # 开始一个新的章节 current_chapter = para.text elif current_chapter is not None: for question_type in ["判断题", "多选题", "单选题", "案例分析题", "计算题", "简答题", "识绘图题", "论述题"]: if question_type in para.text: current_question_type = question_type if question_keyword in para.text and current_question_type is not None: # 在当前题型中添加题目编号 chapter_questions[current_chapter][current_question_type].append(para.text) return chapter_questions def select_questions(chapter_questions, target_counts): selected_questions = defaultdict(list) for question_type, target_count in target_counts.items(): chapter_weights = [len(chapter_questions[chapter][question_type]) for chapter in chapter_questions.keys()] for _ in range(target_count): selected_chapter = choices(list(chapter_questions.keys()), weights=chapter_weights, k=1)[0] question = chapter_questions[selected_chapter][question_type].pop() selected_questions[question_type].append(question) chapter_weights = [len(chapter_questions[chapter][question_type]) for chapter in chapter_questions.keys()] return selected_questions # 替换以下路径为你的文档路径 doc_path = "1.docx" keyword = "知识点" question_keyword = "试题编号" chapter_questions = gather_questions(doc_path, keyword, question_keyword) target_counts = {"判断题": 20, "单选题": 15, "多选题": 10, "案例分析题": 2, "计算题": 2, "简答题": 2, "识绘图题": 1, "论述题": 2} selected_questions = select_questions(chapter_questions, target_counts) # 打印选出的题目编号 for question_type, questions in selected_questions.items(): print(question_type) for question in questions: print(question)这份代码抛弃了兼顾知识点的平衡（虽然keyword“知识点”依然在，但没有用上），毕竟题目足够多，根据章节加权抽取已经能够满足基本的随机性。这份代码创建了一份字典，以"1.4.x.x"特征识别章节，以给定的题型关键字识别题型，以"试题编号"识别题目，将编号放入章节和题型对应的位置中。将题库遍历一遍后，调用select_questions函数，对题目进行加权随机抽取，并设定了每个题型的抽取数目。用这份代码，我从题库中顺利抽取了两套不一样的题目（计算和识绘图题因为题目本身就少，抽来抽去就是二选一），完成了出两套试卷的任务。这其实不算是我第一次把GPT用在工作当中，之前一些学习心得之类的东西，我也使用了chatGPT和New Bing帮助我写。在写心得这件事情上，GPT产出的东西离最终可以交出去的成品还很远，但它能够提供一个清晰的骨架，告诉我应该先写什么，后写什么。顺着它的回答，我再不断地往prompt上加东西，以至于后期的prompt我需要先在记事本上编辑好再发出去。同时，由于GPT压根就没法处理好”字数“这个事情，给我的成果往往只有我要求的一半甚至更少。我有考虑过是中英文字符差别的影响，将发给它的字数要求翻了一番，但收效甚微，只好给它一个大到离谱的字数要求，让它尽可能多地输出，我再去一点一点删减。总而言之，GPT写的心得绝对不是什么开箱即用的东西。但这一次的使用体验和写心得是完全不同。在这种”利用简单的python提高工作效率“的使用情景里，GPT的表现堪称完美，它可以准确地识别需求，给出方案，还对代码进行了必要的注释。虽然我在对话中不断地对prompt修修补补，但GPT给出的代码实际上和第一次给出来的大差不差（毕竟有些对话我只是让它改掉关键字而已），期间唯一一次代码运行报错，也是因为我自己的原因，而不是代码有问题。可以说，chatGPT可以成为真正意义上的”个人助手“，而不仅仅是一个有趣的玩具。
简介公司云电脑采用华为FusionAccess云桌面方案，华为自己的云电脑在2021年已经停止运营，FusionAccess的各平台客户端也就在2021年停止更新，后续华为又推出了Workspace企业自部署云桌面方案，但是公司内部并没有更新方案，继续沿用已经停止运行的旧有方案。过去半个星期我一直在对FusionAccess的各个客户端进行测试，得出的结论是：勉强能用，但怎么用都要难受一下。Windows端Windows客户端的测试在Windows 11、Windows10 LTSC上进行。内部网络提供的Windows客户端与华为提供的最新客户端只存在版本号的差别，公网版本的安装包版本号更新，但安装后内部显示的版本号并没有更新，猜测公网客户端只是为了刷年份/版本号，核心代码并没有更新。通过Geek Uninstaller进行卸载测试，Windows客户端的卸载比较干净，没有留下卸载残留。Windows端对高分屏的兼容性一般，需要在兼容性设置中开启代替缩放（应用程序），开启后登陆页面清晰度大幅提高，但字体会过小，比较难看清楚。客户端缩放设置与云桌面的缩放设置无关，因此兼容性设置的调整可以跳过。内外网的云电脑域名是相同的，外网通过VPN登录云电脑需要手机验证码登录，而在内网登录则不需要这一步，只需要账号密码即可，这种差异可能是管理员设置造成。登录后，会自动打开云桌面并全屏。在这里，如果没有在设置中开启“分辨率自适应”，云桌面会维持在一个非常低的分辨率上，开启之后，则会根据客户端的分辨率进行调整。这就造成了一个问题：不开启自适应时，云桌面的分辨率实在太低，影响工作；开启自适应时，云桌面可能会自动调节成2k分辨率（取决于客户机分辨率），此时没有显卡支持的云桌面会耗费本就紧张的CPU资源进行渲染，让卡顿的系统进一步卡顿。雪上加霜的是，不论网络环境如何，Windows客户端每秒钟都会卡顿一次，严重影响工作效率。Linux端Linux端的测试在包括Deepin、UOS专业版、Ubuntu 22.04 LTS和Ubuntu 16.04LTS的多个发行版上进行。对Linux端的测试都以失败告终。内网显示安装包只兼容UOS，但在上述几个与debian相近的发行版上都能顺利安装。想要顺利运行云客户端，还需要以下步骤：在Launchpad下载multiarch-support、libgstreamer0.10和libgstreamer-plugin-base0.10安装包使用dpkg命令依次安装上述包（UOS专业版使用sudo需要授权，可以直接依次点击安装）利用添加源/下载安装包的方式，安装libssl1.0-dev在Ubuntu上，右键单击桌面的快捷方式，选择“允许运行”经过上述步骤，云电脑客户端可以正常打开和登录，而且登录页面对高分屏的支持比Windows端要好。但登录之后，会一直提示正在连接中和“云电脑正在重启或重置”，始终连不上云桌面。后台输出的日志无法定位问题，在尝试以上四种发行版均告失败后，对Linux端的测试也就结束了。需要注意的是，公司内网环境中，可以使用UOS专业版登录云电脑，可以正常使用，相当流畅的同时，还可以使用本地打印机和ukey，不知道是做了什么设置让它成功跑了起来。Android端Android端的安装也颇费一番周折。公司内网提供的安卓端隐藏在另一个内网办公软件中，无法单独使用。在公网上搜索到FusionAccess的旧版客户端，输入云电脑地址后，会提示需要安装插件，实际上就是兼容版本的客户端补丁，安装后，原有客户端的图标会消失，替换成另一个同名图标。补丁依托客户端存在，如果在应用管理中将旧版客户端卸载，则补丁也会一同卸载。实际使用过程中，Android端是使用体验最为良好的一个。登录过程与桌面端没有差别，只是设置中没有了HTTP代理的选项。登录后，分辨率可以选择适应屏幕、1080p或720p，可以通过固定为1080p和16:9来降低系统渲染开销和网页元素错位。在模拟器上，因为客户端针对手机设计，并没有适配右键响应时间（也可能是模拟器本身就不响应右键单击事件），右键单击操作通过长按左键完成。安卓端可以在屏幕顶端显示实时帧率与网络延时，使用过程中帧率最高达到20Hz。考虑到云桌面的性能以及没有客户端卡顿的影响，安卓端表现比Windows端有了比较大的提升。结论尽管公司提供了较好的VPN环境，但受制于云桌面羸弱的性能（4核，但是服务器级CPU）和华为HDP协议的特性，云电脑在Windows端和Android端的使用体验都远远不及个人使用的一些远程桌面方案（NoMachine、Teamviewer、Parsec等等），更不用说和本地电脑比较了。如果想要相对较好的体验，推荐在安卓模拟器（我使用的是bluestacks）中使用移动端应用登录，可以规避Windows端每秒卡顿一下的恶性bug。需要声明的是，以上体验都是在外网环境中使用VPN连接公司专网进行的，由于手上没有苹果设备，无法对iOS以及macOS端进行评测。
记录一下所需要的安装程序，接下来可能要做迁移，东西要重新弄过，有点麻烦的。Hyper-V虚拟机配置网络配置开启电脑Hyper-V功能，在Hyper-V中添加一个内部交换机（假设取名为NAT-VM），然后在管理员权限的Powershell/Windows Terminal中执行一下命令#查看 NAT-VM 的 ifindex Get-NetAdapter #创建ip，InterfaceIndex参数自行调整为上一步获取到的ifindex。这一步等同于在 控制面版-网卡属性 中设置ip New-NetIPAddress -IPAddress 192.168.56.1 -PrefixLength 24 -InterfaceIndex 6 #创建nat网络，这一步是教程中的关键命令，24为子网掩码位数，即：255.255.255.0 New-NetNat -Name NAT-VM -InternalIPInterfaceAddressPrefix 192.168.56.0/24使用tftpd64配置DHCP服务器，设置开机启动。不要叉掉tftpd64的窗口，在任务栏图标选择隐藏。虚拟机配置使用官方的Ubuntu Server镜像安装（似乎也可以用ubuntu-minimal），不要在安装过程中选择安装docker，因为系统会使用snap安装，后续权限管理会比较麻烦。修改软件源为https://mirrors.ustc.edu.cn过程中添加宿主机的代理地址，方便访问外网。免密码使用sudosudo visudo在%sudo 一栏最后一个ALL前添加NOPASSWD:,最终效果如下%sudo ALL=(ALL:ALL) NOPASSWD:ALL加入Zerotier#安装zerotier curl -s https://install.zerotier.com | sudo bash #加入网络 sudo zerotier-cli join 83048a06326f196c #添加moon中转主机 sudo zerotier-cli orbit db53baa8e6 db53baa8e6安装docker(这是为了别的东西，也是图方便)#如果有的话，清除旧的docker sudo apt remove docker docker-engine docker.io containerd runc #安装依赖 sudo apt install \ ca-certificates \ curl \ gnupg \ lsb-release #添加密钥 curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg #添加apt软件源 echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null #更新软件源 sudo apt update #安装docker sudo apt-get install docker-ce docker-ce-cli containerd.ioDocker备份、恢复、迁移在原主机上执行：#查看docker容器情况 sudo docker ps #创建docker快照 sudo docker commit -p $container_id $image_name #备份到tar文件 sudo docker save -o $location $image_name执行完后，将生成的tar文件复制到新主机，执行：#从tar文件恢复 sudo docker load -i $location #检查镜像是否恢复成功 sudo docker images #从镜像生成容器 #这里记录一下某js定时面板的指令，方便使用 sudo docker run -dit \ -v $PWD/ql/config:/ql/config \ -v $PWD/ql/log:/ql/log \ -v $PWD/ql/db:/ql/db \ -v $PWD/ql/repo:/ql/repo \ -v $PWD/ql/raw:/ql/raw \ -v $PWD/ql/scripts:/ql/scripts \ -p 5700:5700 \ --name qinglong \ --hostname qinglong \ --restart unless-stopped \ whyour/qinglong:latestdocker免sudo执行# 创建docker用户组 sudo groupadd docker # 将当前用户添加到docker用户组 sudo usermod -aG docker $USER # 重启docker服务 sudo systemctl restart docker # 切换或者退出当前账户，重新登入 exit安装openjdk-14使用openjdk14是考虑到openjdk是开源的，代码开放，审计方便且安全，也不涉及商业问题。#下载openjdk14安装包 wget https://download.java.net/openjdk/jdk14/ri/openjdk-14+36_linux-x64_bin.tar.gz #解压 tar xvf openjdk-14+36_linux-x64_bin.tar.gz #移动到不那么容易误删的位置 sudo mkdir /usr/local/java sudo mv ./jdk-14 /usr/local/java/jdk14 #设置环境变量 sudo nano /etc/profile.d/jdk.sh #添加以下代码 export JAVA_HOME=/usr/local/java/jdk14 export PATH=$PATH:$JAVA_HOME/bin #更新环境 source /etc/profile.d/jdk.sh安装lnmp#使用无人值守工具 wget http://soft.vpser.net/lnmp/lnmp1.8.tar.gz -cO lnmp1.8.tar.gz && tar zxf lnmp1.8.tar.gz && cd lnmp1.8 && LNMP_Auto="y" DBSelect="5" DB_Root_Password="t9*ScJ&oJyZ4M@" InstallInnodb="y" PHPSelect="11" SelectMalloc="2" CheckMirror="n" ./install.sh lnmpFisco BCOS国密链部署采用源码编译方式获得Fisco Bcos二进制文件，再使用官方提供的build_chain.sh搭建一条拥有四个节点的国密区块链依赖安装sudo apt install -y g++ libssl-dev openssl cmake git build-essential autoconf texinfo flex patch bison libgmp-dev zlib1g-dev automake libtool下载代码git clone https://github.com/FISCO-BCOS/FISCO-BCOS.git -b master-2.0准备编译cd FISCO-BCOS mkdir -p build && cd build cmake .. make #可添加多线程下载build_chain脚本并使用cd ~ && mkdir -p fisco && cd fisco curl -LO https://github.com/FISCO-BCOS/FISCO-BCOS/releases/download/v2.8.0/build_chain.sh && chmod u+x build_chain.sh #使用-e指定刚刚编译完成的二进制fisco-bcos来生成链 #使用-g搭建国密版本链 #使用-G设置`chain.sm_crypto_channel=true`。确认sdk支持的情况下（Java SDK 以及 Web3sdk v2.5.0+），可以指定-G参数，连接也使用国密SSL ./build_chain.sh -l 127.0.0.1:4 -p 30300,20200,8545 -g -G这样会生成一个全链路国密版本的四个节点文件启动BCOS链bash nodes/127.0.0.1/start_all.sh获取并使用Fisco Bcos控制台#获取控制台 cd ~/fisco && curl -LO https://github.com/FISCO-BCOS/console/releases/download/v2.8.0/download_console.sh && bash download_console.sh #复制控制台配置文件 cp -n console/conf/config-example.toml console/conf/config.toml #配置控制台证书 cp -r nodes/127.0.0.1/sdk/* console/conf/ #启动 cd ~/fisco/console && bash start.sh部署WeBase套件安装节点前置服务因为本机部署了一条四节点的链，而每个节点对应一个前置服务，因此需要在本机运行四个前置服务。#拉取代码并进入目录 git clone https://github.com/WeBankBlockchain/WeBASE-Front.git cd WeBASE-Front #编辑build.gradle，注释掉下面这行 #maven { url 'https://dl.bintray.com/ethereum/maven/' } #为保证gradle兼容性，使用gradlew编译 chmod +x ./gradlew && ./gradlew build -x test #拷贝配置 cd dist cp -r conf_template conf #修改配置 cd conf #将节点所在目录下nodes/${ip}/sdk下的所有文件拷贝到当前conf目录 cp -r nodes/${ip}/sdk/* ./conf/修改application.ymlspring: datasource: url: jdbc:h2:file:./h2/webasefront;DB_CLOSE_ON_EXIT=FALSE // 默认H2库为webasefront，建议修改数据库存放路径； ... server: port: 5003 // 服务端口 context-path: /WeBASE-Front sdk: ... ip: 127.0.0.1 // 连接节点的监听ip channelPort: 20200 // 连接节点的链上链下端口 certPath: conf // sdk证书的目录，默认为conf logging: config: classpath:log4j2.xml level: com.webank.webase.front: info //建议修改为warn或更高级别，不然会生成海量日志 constant: keyServer: 127.0.0.1:5004 // 密钥服务的IP和端口(WeBASE-Node-Manager服务或者WeBASE-Sign服务，不同服务支持的接口不同)，如果作为独立控制台使用可以不配置 aesKey: EfdsW23D23d3df43 // aes加密key(16位) 如启用，各互联的子系统的加密key需保持一致 transMaxWait: 30 // 交易最大等待时间 monitorDisk: / // 要监控的磁盘目录，配置节点所在目录（如：/data） monitorEnabled: true // 是否监控数据，默认true nodePath: /fisco/nodes/127.0.0.1/node0 //配置所连节点的绝对路径，用于监控节点配置与日志 ...退回到WeBASE-Front，将dist目录复制出另外三个副本，并编辑副本中的application.yml，修改其中的数据库、服务端口和节点信息，分别对应不同的节点。端口冲突会导致服务无法启动。#启动前置服务 cd dist #启动 bash start.sh #停止 bash stop.sh #检查 bash status.sh分别进入dist的副本，进行同样的操作。#进入控制台 http://{deployIP}:{frontPort}/WeBASE-Front 示例：http://localhost:5002/WeBASE-Front安装签名服务#拉取代码 git clone https://github.com/WeBankBlockchain/WeBASE-Sign.git #进入目录 cd WeBASE-Sign #为保证gradle兼容性，使用gradlew编译 chmod +x ./gradlew && ./gradlew build -x test #下面两步也可以在phpmyadmin图形界面上执行，更直观 #登录MySQL: mysql -u ${your_db_account} -p${your_db_password} 例如：mysql -u root -p123456 #新建数据库： CREATE DATABASE IF NOT EXISTS {your_db_name} DEFAULT CHARSET utf8 COLLATE utf8_general_ci; #为保安全性，最好是专门新增一个用户，给予这个数据库的全部权限后，后续全部使用这个用户来操作，而不是直接使用root用户操作 #修改配置 cd dist #复制配置文件 cp conf_template conf -r #修改配置文件 nano conf/application.ymlserver: # 本工程服务端口，端口被占用则修改 port: 5004 context-path: /WeBASE-Sign spring: datasource: # 数据库连接信息 url: jdbc:mysql://127.0.0.1:3306/webasesign?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8 # 数据库用户名 username: "dbUsername" # 数据库密码 password: "dbPassword" driver-class-name: com.mysql.cj.jdbc.Driver constant: # aes加密key(16位)，如启用，各互联的子系统的加密key需保持一致 aesKey: EfdsW23D23d3df43#启动服务 #在dist目录下 启动：bash start.sh 停止：bash stop.sh 检查：bash status.sh安装节点管理服务#拉取代码 git clone https://github.com/WeBankBlockchain/WeBASE-Node-Manager.git #进入目录 cd WeBASE-Node-Manager #为保证gradle兼容性，使用gradlew编译 chmod +x ./gradlew && ./gradlew build -x test #新建数据库，这里和上面的顺序类似 ... #修改脚本配置 cd dist/script nano webase.sh #修改服务器名称、用户名和密码 #数据库初始化 bash webase.sh ${dbIP} ${dbPort} 实例：bash webase.sh 127.0.0.1 3306 #回到dist目录，复制配置文件模板到conf cp conf_template conf -r #修改application.yml nano conf/application.yml #修改数据库相关信息以及log level针对国密，要将application.yml中sdk.encryptType由0改成1。#在dist目录下： 启动：bash start.sh 停止：bash stop.sh 检查：bash status.sh安装WeBase管理平台#拉取代码 git clone https://github.com/WeBankBlockchain/WeBASE-Web.git #进入目录 cd WeBASE-Web #下载solc-bin bash ./get_solc_js.sh #返回上级目录，拉取移动端代码 cd .. git clone https://github.com/WeBankBlockchain/WeBASE-Web-Mobile.git然后修改nginx.conf，下面是示例：server { listen 5000 default_server; # 前端端口（端口需要开通策略且不能被占用） server_name 127.0.0.1; # 服务器ip，也可配置为域名 location / { root /data/WeBASE-Web/dist; # 前端文件路径(文件需要有权限访问) # 下面是移动端nginx配置 if ( $http_user_agent ~ "(MIDP)|(WAP)|(UP.Browser)|(Smartphone)|(Obigo)|(Mobile)|(AU.Browser)|(wxd.Mms)|(WxdB.Browser)|(CLDC)|(UP.Link)|(KM.Browser)|(UCWEB)|(SEMC-Browser)|(Mini)|(Symbian)|(Palm)|(Nokia)|(Panasonic)|(MOT-)|(SonyEricsson)|(NEC-)|(Alcatel)|(Ericsson)|(BENQ)|(BenQ)|(Amoisonic)|(Amoi-)|(Capitel)|(PHILIPS)|(SAMSUNG)|(Lenovo)|(Mitsu)|(Motorola)|(SHARP)|(WAPPER)|(LG-)|(LG/)|(EG900)|(CECT)|(Compal)|(kejian)|(Bird)|(BIRD)|(G900/V1.0)|(Arima)|(CTL)|(TDG)|(Daxian)|(DAXIAN)|(DBTEL)|(Eastcom)|(EASTCOM)|(PANTECH)|(Dopod)|(Haier)|(HAIER)|(KONKA)|(KEJIAN)|(LENOVO)|(Soutec)|(SOUTEC)|(SAGEM)|(SEC-)|(SED-)|(EMOL-)|(INNO55)|(ZTE)|(iPhone)|(Android)|(Windows CE)|(Wget)|(Java)|(curl)|(Opera)" ) { root /data/WeBASE-Web-Mobile/dist; } index index.html index.htm; try_files $uri $uri/ /index.html =404; } include /etc/nginx/default.d/*.conf; location /mgr { proxy_pass http://10.0.0.1:5001/; #节点管理服务ip和端口 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }重启nginxsudo nginx -s reload访问http://{deployIP}:{webPort}测试部署WeIdentity采用可视化部署方式，部署WeIdentity实体身份标识服务下载部署工具wget -c https://gitee.com/WeBank/WeIdentity-Build-Tools/raw/master/common/script/install/weid_install.sh执行安装脚本chmod u+x weid_install.sh ./weid_install.sh cd weid-build-tools启动./start.sh访问http://{deployIP}:6021继续进行可视化部署可视化部署选择“WeID + WeBASE集成模式”从WeBase控制台粘贴相关信息选择“联盟链委员会管理员”配置区块链节点机构名称AMOP 通讯 ID，建议使用英文，并确保该 ID 在联盟链中唯一配置区块链节点 IP 和 Channel 端口配置说明：填入集成 WeIdentity Java SDK 的service（或者部署 WeIdentity Rest Service），所需连接的区块链节点的内网或公网 IP。Channel 端口为该节点的Channel端口。配置要求：格式为区块链节点 IP:Channel 端口。如需使用多个区块链节点, 请用半角逗号”,”分隔。连接单个节点的配置示例：10.10.4.1:20200连接多个节点的配置示例：10.10.4.1:20200,10.10.4.2:20200,127.0.0.1:20200配置SDK证书配置说明：连接区块链节点时需要使用的 SDK 证书。请从您的FISCO-BCOS节点安装目录获取 SDK 证书文件(包括三个文件：ca.crt, node.crt 和 node.key), 可能正在下面两个目录: ~/fisco/nodes/127.0.0.1/sdk/ 或 ~/fisco/generator/tmp_one_click/agencyA/sdk/。选择主群组：应该只有一个默认的群组配置数据库（MySQL）创建机构的 WeID：WeBASE同步账户模式部署 WeIdentity 智能合约：设置链ID和用户名FISCO BCOS各种服务占用端口：记录各种服务原始文档中所占用的端口以及修改位置端口说明修改位置80Nginx默认监听端口/usr/local/nginx/conf/nginx.conf/usr/local/nginx/conf/vhost/*.conf3306MySQL数据库占用端口/etc/my.cnf5000WeBase管理平台前端端口/usr/local/nginx/conf/nginx.conf/usr/local/nginx/conf/vhost/*.conf5001WeBase节点管理服务端口WeBASE-Node-Manager/dist/conf/application.yml5003WeBase节点前置服务端口WeBASE-Front/dist/conf/application.yml5004WeBase签名服务端口WeBASE-Sign/dist/conf/application.yml
试卷内容单选题 20分判断题 20分简答题 5*6=30分综合题 30分考试范围：第一章~第七章第一章定义远动：利用远程通信技术进行信息传输，实现对远方运行设备的监视和控制遥测：远程测量，应用远程通信技术，传输被测变量的值遥信：远程指示；远程信号，对诸如告警情况、开关位置或阀门位置这样的状态信息的远程监视遥控：远程命令，应用远程通信技术，使运行设备的状态产生变化遥调：远程调节，对具有两个以上状态的运行设备进行控制的远程命令电力系统调度中心的任务一是合理地调度所属各发电厂的输出功率，指定运行方式，从而保证电力系统的正常运行二是在电力系统发生故障时，迅速排除故障，尽快恢复电力系统的正常运行远动信息内容遥测信息传送发电厂、变电站的各种运行参数，分为电量和非电量两类。电量包括母线电压、系统频率、流过电力设备（发电机、变压器）及输电线的有功功率、无功功率和电流。非电量包括发电机机内温度以及水电厂的水库水位等。遥信信息包括发电厂、变电站中断路器和隔离开关的合闸或分闸状态，主要设备的保护继电器动作状态，自动装置的动作状态，以及一些运行状态信号，如厂站设备事故总信号、发电机组开或停的状态信号、远动及通信设备的运行状态信号等。遥测信息和遥信信息称为上行信息。遥控信息传输改变运行设备状态的命令，如发电机组的启停命令、断路器的分合命令、并联电容器和电抗器的投切命令等。遥调信息传送改变运行设备参数的命令，如改变发电机有功输出功率和励磁电流的设定值，改变变压器分接头的位置等。遥控信息和遥调信息称为下行信息。远动信息的传输模式循环数字传输模式CDT，厂站端将要发送的远动信息按规约的规定组成各种帧，再编排帧的顺序，一帧一帧地循环向调度端传送。信息的传送是周期性的、周而复始的。问答传输模式polling模式，调度端需要主动向厂站端发送查询命令报文得到监视信息。查询命令不同，报文中的类型标志取不同值，报文的字节数一般也不一样。远动信息的编码CDT模式：8位功能码：区分代表不同信息内容的各种信息字32位信息码：信息内容8位校验码：用于检错和纠错，提高信息字在传输过程中抗信道干扰的能力，采用CRC校验polling模式：问答双方RTU地址报文类型报文数据区字节数信息内容校验码常用的远动信道专用有线信道复用电力线载波信道微波信道光纤信道无线电信道远动系统的构成及各部分功能前置机是缓冲和处理输入或输出数据的处理机。它接收远动终端装置RTU送来的实时远动信息，经译码后还原出被测量的实际大小值和被监视对象的实际状态，显示在调度室的CRT上和调度模拟屏上。这些信息还要向主计算机传送。RTU对各种电量变送器送来的0~5V直流电压分时完成A/D转换，得到与被测量对应的二进制数值；并由脉冲采集电路对脉冲输入进行计数，得到与脉冲量对应的计数值；海拔状态量的输入状态转换成逻辑电平“0”或“1”。再将上述各种数字信息按规约编码或遥测信息字和遥信信息字，向前置机传送。远动系统配置的基本模式点对点配置主站与子站之间通过专用的传输链路相连接的一种配置多路点对点配置控制中心或主站，通过各自链路与多个子站相连的一种配置，主站与各子站可同时交换数据多点星形配置控制中心或主站与多个子站相连接的一种配置。任何时刻只许一个子站传输数据到主站；主站可选择一个或多个子站传输数据，也可向全部子站同时传输全局性报文。多点共线配置控制中心或主站通过一公共链路与多个子站相连的一种配置。任何时刻只许一个子站传输数据到主站；主站可选择一个或多个子站传输数据，也可向全部子站同时传输全局性报文。多点环形配置所有站之间的通信链路形成环状，控制中心或主站可以通过两条不同的路径与每一子站通信。第二章数字通信系统模型信息源：将消息转换成信号输出信源编码：对信息源发出的模拟信号完成A/D转换，得到对应的数字信号。然后对数字信号进行编码得到一串离散的数字信息m。信道编码/差错控制编码：按照一定的规则，在信息序列m中添加一些冗余码元，将信息序列m变成较原来更长的二进制数字序列c，称为码字，提高信息序列m的抗干扰能力。调制：将用数字序列表示的码字c变换成适合于在信道中传输的信号形式，送入信道。信道：传输信号的通道解调：把从信道中接收到的两种不同频率或两种不同相位的正弦交流信号，还原成数字序列。信道译码：根据信道编码规则，对接收码字进行译码校验，达到检出或纠正接收码字R中错误码元的目的，并产生出估计与发送码字c对应的接收码字c*，再从c*还原出估计与信息序列m对应的m*信源译码：根据信源编码规则，变换信息序列m*为信息源输出s的对应值s*，并送给收信者予以显示或打印等。通信方式单工通信：信息的传输始终是一个方向，不能进行与此相反方向的传输。半双工通信：信息可以在两个方向上传输，但某一时刻只限于一个方向，不能同时进行双向传输。全双工通信：信息可以同时做双向传输。异步通信与同步通信异步通信：按字符传送，每个字符以起始位开始，以停止位结束。每个字符的起始位都起到对该字符的位同步作用，使频率的漂移不会积累。异步通信时，收发双方必须设置相同的字符格式。同步通信：以同步字符作为传送开始，字符与字符之间不允许有空隙，当线路空闲或没有字符可发时，发送同步字符。同步通信时，收发双方必须设置相同的同步字符，另外收发双方必须保证有同步的时钟，由他们分别控制信号的发送与接收。CDT传输规约帧结构同步字标明一帧的开始，它取固定的48位二进制数，写入串行口的同步字为三组D709H控制字和信息字中都包含有8位校验码，构成（48，40）码组，生成多项式$g(x)=x^8+x^2+x+1$，陪集码FFH控制字由6个字节组成：控制字节、帧类别、信息字数n、源站址、目的站址和校验码字节CDT传输规约信息字结构遥测与遥信的最大容量计算遥测信息字功能码00H~7FH，每个遥测信息字传送两路遥测量，所以要测的最大容量为128*2=256路遥信信息字功能码F0H~FFH，每个遥信信息字传送两个遥信字，一个遥信字包含16个状态位，所以遥信的最大容量为16*32=512路帧的组织方式远动信息按其重要性和实时性要求，分为A、B、C、D（D1、D2）、E帧。重要遥测量安排在A帧传送，循环时间不大于3s次要遥测量安排在B帧传送，循环时间不大于6s一般遥测量安排在C帧传送，循环时间不大于20s遥信状态信息，包含子站工作状态信息，安排在D1帧定时传送电能脉冲计数值安排在D2帧定时传送事件顺序记录（SoE）安排在E帧，以帧插入方式传送三遍问答式传输规约 主站与子站间的问答过程RTU刚合电源时，子站向主站发送电源合闸报文，主站收到后向子站送电源合闸确认命令，子站收到后对该命令回答确认报文。然后主站通过各种送参数命令对RTU的各种参数初始化。最后反复用类别询问获取RTU的实时数据，直至RTU的所有量送完为止，以便主站建立数据库。主站向子站发类别询问命令时，若子站无变化数据，回答确认报文；若有变化数据，则用送数据报文传送变化数据回答主站；当子站有时标数据出现时，则回答时标数据出现的报文，主站便多次发送召唤事件记录数据的命令获取RTU的时标数据。第三章最小距离与码的检错、纠错能力信道编码中，用$k$表示信息序列m的长度，也是向信道编码输入的信息序列的码元位数用$n$表示经信道编码后输出码字的码元位数，因此码字中的校验码是$(n-k)$位，即$r=n-k$通常把这种码记为$(n,k)$码信道译码时采用最大似然译码，把接收到的码字与信道编码时可能输出的$2^k$个码字比较，把最相似的码字作为正确的接收码字。码字的相似程度可以用码距的大小判断。两个同样长度的码字之间，对应码位上不相同码元的数目，称为码距。在一种码的所有码字集合中，任意两个码字之间的码距并非都相等。把所有可能的码字对之间码距的最小值，称为这个码字集合的最小距离，记为$d_{min}$。对最小距离为$d_{min}$的码，它能纠正的码字中的错误个数$t$和能检出的码字中的错误个数$l$满足如下关系：$$ \begin{aligned} t&\le\cfrac{d_{min}-1}{2}\\ l&\le d_{min}-1 \end{aligned} $$增加一种码的最小距离，可以提高这种码的检错和纠错能力。抗干扰编码就是对信源编码得到的$k$位信息序列，按照某种规律添加校验码元，以达到增大这种码的最小距离的目的。模2运算加法运算规则$$ \begin{gather} 1\oplus1=0\\ 0\oplus0=0\\ 0\oplus1=1\\ 1\oplus0=1 \end{gather} $$乘法运算规则$$ \begin{gather} 1\odot1=1\\ 0\odot0=0\\ 0\odot1=0\\ 1\odot0=0 \end{gather} $$在信道编码中，经常用多项式来表示一个信息序列或码字，称为信息多项式或码多项式。信息多项式：$$ m(x)=m_{k-1}x^{k-1}+m_{k-2}x^{k-2}+\cdots+m_1x+m_0 $$码多项式：$$ c(x)=c_{n-1}x^{n-1}+c_{n-2}x^{n-2}+\cdots+c_1x+c_0 $$多项式中的x只表示系数所处的位置，系数表示码元的取值。奇偶校验码一个$(n,k)$码，如果码字中的$r$个校验码元不仅与本码字中的信息元相关，还与前面若干个码字的信息元相关，这$2^k$的码字的集合称为卷积码。如果每个码字中的$r$个校验码元都只与本码字的$k$位信息元有关，这$2^k$个码字的集合称为分组码。奇偶校验码是一个$(n,n-1)$分组码，编码规则是在$n-1$位信息元后面，添加一个奇校验或偶校验的检验码元，使每个码字中"1"码元的个数恒为奇数或偶数。偶校验码的检验码元等于信息码元的模2和奇校验码的检验码元等于信息码元的模2和再取非线性分组码生成矩阵当分组码满足每个码字的每一位校验码元，都是本码字中某些位信息码元的线性模2和时，这个分组码为线性分组码。如果线性分组码的每个码字都满足前$k$位为信息位，后$n-k$位为校验位，这个线性分组码称为系统线性分组码。以$(6,3)$分组码为例，如果是每个码字的校验码元和该码字的信息元之间满足如下线性关系：$$ r_2=m_2+m_0\\ r_1=m_2+m_1\\ r_0=m_1+m_0 $$用$c=c_5c_4c_3c_2c_1c_0$表示任意码字，即$$ c=c_5c_4c_3c_2c_1c_0=m_2m_1m_0r_2r_1r_0 $$可以以矩阵形式表示出线性分组码：$$ [c_5c_4c_3c_2c_1c_0]=[m_2m_1m_0] \begin{bmatrix} 1&0&0&1&1&0\\ 0&1&0&0&1&1\\ 0&0&1&1&0&1 \end{bmatrix} =[m_2m_1m_0]G $$矩阵G称为线性分组码的生成矩阵。循环码的编译码原理如果一个$(n,k)$线性分组码，它的$2^k$个码字中的任何一个码字的任意次循环移位，得到的仍然是这个线性分组码中的码字，这个线性分组码称为循环码。$(n,k)$次循环码的生成多项式$g(x)$是$x^n+1$的一个因式：$$ x^n+1=g(x)h(x) $$假若根据需要欲生成一个码长为n位，信息位为k位的$(n,k)$循环码：将$x^n+1$进行因式分解，找出一个次数为$n-k$的因式以这个因式位生成多项式，分别乘以$2^k$个不同的信息序列，得到$2^k$个码字$(n,k)$系统循环码的编码过程是：将信息多项式$m(x)$乘以$x^{n-k}$得到$x^{n-k}m(x)$以生成多项式$g(x)$除$x^{n-k}m(x)$，若商为$q(x)$，余式为$r(x)$，则$x^{n-k}m(x)=q(x)g(x)+r(x)$用$r(x)$模2加$x^{m-k}m(x)$，得到系统循环码码字$x^{m-k}m(x)+r(x)$循环码的编译码算法——软件表算法Ⅰ软件表算法Ⅰ适合校验位比较少的情况设$k$位信息序列$m=m_{k-1}m_{k-2}\cdots m_1m_0$，软件表算法Ⅰ生成循环码步骤：把信息序列分成长度为$n-k$的$p$个信息段，记为$m=M_1M_2\cdots M_p$在第一个信息段$M_1$后面添加$n-k$个零，然后除以生成多项式$g(x)$得余数$r_1$。再将余数与第二个信息段$M_2$模2加得$M'_2$在$M'_2$后面后面添加$n-k$个零，然后除以生成多项式$g(x)$得余数$r_2$，将余数与第三个信息段$M_3$模2加得$M'_3$重复步骤，直到对$M'_p$按同样步骤得到$r_p$，它就是信息序列$m$编码应得的余数。这时信息序列$m$对应的码字为$c=M_1M_2\cdots M_pr_p$将中间步骤中可能出现的$2^{n-k}$个余数称为中间余数，存在内存中，建立中间余数表，即软件表。循环码的编译码算法——软件表算法Ⅱ软件表算法Ⅱ适合校验位比较多的情况设$k$位信息序列$m=m_{k-1}m_{k-2}\cdots m_1m_0$，软件表算法Ⅱ生成循环码步骤：把信息序列分成长度为$(n-k)/2$的$p$个信息段，记为$m=M_1M_2\cdots M_p$在第一个信息段$M_1$后面添加$n-k$个零，然后除以生成多项式$g(x)$得中间余数$r_1$。再将$r_1$分成两段，前半段$(n-k)/2$位是高位段，记为$r_{1H}$，后半段是低位段，记为$r_{1L}$将$r_{1L}$与第二个信息段$M_2$模2加，得$M'_2$。在$M'_2$后面添加$n-k$个零，然后除以生成多项式$g(x)$得中间余数$r_2$。再将$r_2$分成两段，前半段$(n-k)/2$位记为$r_{2H}$，后半段记为$r_{2L}$。将$r_{2H},r_{1L}$与第三个信息段$M_3$模2加，得$M'_3=r_{2H}+r_{1L}+M_3$。在$M'_3$后面添加$n-k$个零，然后除以生成多项式$g(x)$得中间余数$r_3$。再将$r_3$分成两段，前半段$(n-k)/2$位记为$r_{3H}$，后半段记为$r_{3L}$。重复步骤，直到求出$M'_p=r_{(p-1)H}+r_{(p-2)L}+M_p$.在$M'_p$后面添加$n-k$个零，然后除以生成多项式$g(x)$得中间余数$r_p$。再将$r_p$分成两段，前半段$(n-k)/2$位记为$r_{pH}$，后半段记为$r_{pL}$。将$r_{pH}$与$r_{(p-1)L}$模2加得$r_H=r_{pH}+r_{(p-1)L}$，令$r_L=r_{pL}$,则$r_H,r_L$分别是信息序列$m$的余式$r$的高$(n-k)/2$位和低$(n-k)/2$位，$r=r_Hr_L$第四章同步的必要性接收端对接收到的信息内容的识别完全按照规约规定的帧结构、码字结构，再对照本段的码字计数器、字节计数器的计数值进行判断。要求收端的码字计数器、字节计数器的计数值，必须和发端的码字计数器、字节计数器的计数值保持一致，只有这样收端对信息的识别才是正确的。发送端每位码元的发送由发端串行接口电路的发送时钟控制，接收端在接收每位码元时由收端串行接口电路的接收时钟控制，发送时钟频率和接收时钟频率必须设置相等。即使如此，它们之间仍然存在一定频差，将产生相位差，相位差不断积累，到一定时间收发端将出现错位同步字的检测两种情况：一种是接收端正确接收完一帧信息后，在下一帧的同步字应该出现的时间间隔内寻找同步字，称为惯性同步状态；另一种情况是接发两端处于失步状态，此时接收端必须从接收信息中首先寻找出同步字，称为搜索同步状态。第五章定时扫查模式遥信信息通常情况下状态不变化，而状态改变往往瞬间完成，因此对遥信量采集时，必须不断地扫查，以捕捉遥信变位。通常系统对遥信采集有一分辨率的指标，即对同一遥信量的前后两次扫查的时间间隔。根据分辨率可以设定遥信扫查的时间间隔，一般将遥信扫查置于实时时钟中断服务程序中，每一个等时间间隔都要对全部的遥信量进行一次扫查。变位触发模式在实时扫查模式的基础上，稍加修改则可实现变位触发模式。提高遥测信息可靠性措施在硬件方面保证强电系统和弱电系统的信号隔离，通常采用继电器隔离和光电耦合隔离。在软件方面不能以一次瞬间的状态来表示遥信状态，必须连续多次读取状态，以其每次读取均相同的状态作为遥信状态。遥信的防抖和消噪处理可以采用软件的方法实现。事件顺序记录、建立全网统一时钟的方法事件指的是运行设备状态的变化。事件顺序记录是指开关或继电保护动作时，按动作的时间先后顺序进行的记录。要完成SOE功能，远动装置中必须提供实时时钟。时间分辨率指能正确区分事件发生顺序的最小时间间隔。为了保证系统分辨率，全系统应该参照同一个时间标准，即必须建立全网统一时钟。一种统一全网时钟的方法是由主站周期性地向各RTU发送时钟命令，各RTU以主站的实时时钟为标准对本站实时时钟的各计数单元进行修正，达到统一时钟的目的。另一种方法是在主站和各RTU处分别装配标准时钟信号的接收装置，接收天文台发出的无线电校时信号或GPS提供的标准时钟信号。统一全网时钟的方法主站向RTU发送设置时钟命令RTU接收后修改RTU的实时时钟主站再向RTU发送召唤子站时钟命令RTU收到后插入返送两个信息字，即RTU时钟和等待时间主站收到返送信息后，计算出RTU的时间校正值，向RTU发出设置时钟校正值命令RTU收到校正值后修正RTU的实时时钟遥测量的转换过程四种A/D转换方法逐位比较式A/D转换把待转换的直流模拟电压与一组呈二进制关系的标准电压一位一位由高至低逐位进行比较，决定每位是去码还是留码，从而实现模拟电压到二进制数码的转换。转换速度快、出现波动或受到干扰直接会给转换结果带来严重误差。双积分式A/D转换采用U/T转换方式，具有转换精度高、抑制干扰能力强、造价低等优点，但采样速度低。并行比较式A/D转换转换速度最快、转换原理最直观的转换技术，但电路组成复杂，集成度高，价格昂贵。电荷平衡式U/$f$转换输出串行频率信号，计算机接口简单、灵活，易于实现光电隔离和信号远传，具有良好的精度和线性度，频率输出动态范围宽。数字滤波算法一阶递归滤波限幅滤波算术平均滤波递推平均滤波中位值滤波死区计算对连续变化的模拟量规定一个较小的变化范围。当模拟量在这个规定的范围内变化时，认为该模拟量没有变化，这个期间模拟量的值用原值表示，这个规定的范围称为死区。当模拟量连续变化超过死区时，则以此刻的模拟量值代替旧值，并以此值为中心再设死区。死区计算实际上是一种降低模拟量变化灵敏度的一种方法。越限比较对运行参数量用上限值和下限值来规定其允许的运行范围，用这些量的实时运行值与其限值作比较，一旦发现某一量超出允许范围即判为超限，可能是越上限或越下限。标度转换将A/D转换结果的无量纲数字量还原成有量纲的实际值的换算方法。二—十转换标度转换后的数据已经代表了遥测量的实际值，但此数据是以二进制数表示的。在某些场合，还希望再转换为十进制数，这就需要进行二—十转换。实际上转换结果为二进制的BCD码。事故追忆电力系统在运行过程中随时可能发生事故，因此在对电力系统运行监测时，希望把事故发生前后的一段时间内遥测数据的变化情况保存下来，为今后的事故分析提供原始依据。远动规约中的遥控命令CDT模式主机（调度端）向子站（RTU）发送遥控选择命令子站向主站返送遥控返较信息根据实现情况，主站向子站下达遥控执行命令或遥控撤销命令如果遥控执行则RTU改变遥控输出状态，如果是遥控撤销则遥控状态保持不变问答式主站向RTU发送一个遥控对象、性质的选择命令报文由RTU向主站返送一个返送校核码的报文主站向RTU发送一个执行命令RTU向主站报告一个正确接收的确认信号主站向RTU发送询问报文遥调的两种实现方式模拟整定值调节方式正增值/负增值脉冲调节方式遥控和遥调的可靠性对遥控和遥调的可靠性要求是极高的，不允许有误操作。在远动规约中，遥控、遥调命令的定义和实现过程已充分保证了调度端和RTU通信的可靠性。在RTU方面，应使硬件和软件具有遥控和遥调执行过程正确性的自检功能。在系统设计中，必须要考虑对遥控对象和遥调对象的运行状态和运行水平进行监视的遥信和遥测的回送量，用以对控制和调节结果的监测。第六章交流电流/电压变送器原理图电量变送器的概念一次系统的强电信号经电压互感器和电流互感器变换成额定值为100V和5A/1A的交流信号，供二次系统仪表、保护和测量使用。电量变送器将二次系统信号再经过一级变换，以使达到远动装置遥测量采集信号接口特性要求。根据被测电量的不同，相应地有不同的电量变送器。功率变送器的原理框图三相功率测量原理三相有功功率的测量三元件法可以正确地反映三相四线制和三相三线制的有功功率二元件法可以正确地反映三相三线制的有功功率三相无功功率的测量一元件法和二元件法仅适应于三相完全对称电路的无功功率测量三元件法适应于三相简单不对称电路中的三相无功功率测量交流采样算法交流采样：直接对交流电压、电流进行采样，用软件完成各类电量变送器的功能，从而获得全部电量信息。交流采样算法分类：时域分析算法积分算法二点算法频域分析算法离散傅里叶变换快速傅里叶变换交流采样的误差分析信号转换误差：输入/输出信号在转换过程中出现线性对应关系的破坏而产生的误差。应选择线性好、温漂小、稳定性高的器件，在后续处理中引入修正系数改善。模型误差：建立交流采样算法的必要条件不能满足时所引起的误差。最大限度满足算法成立条件。计算误差：计算中的舍入误差以及一些运算结果的精度损失引起的误差。采用浮点运算；将小信号放大后再处理运算。第七章二进制数字调制数字调制是利用数字信号去控制一定形式的载波而实现调制的一种方法。载波信号表示为：$$ u(t)=U_m\cos(\omega t+\varphi) $$当用数字基带信号去分别控制正弦载波信号的幅值$U_m$、角频率$\omega$、相位$\varphi$这三个参数的任意一个参数时，便分别实现了振幅键控、移频键控及移相键控的调制方式。振幅键控（ASK）用幅值0和幅值$U_m$分别代表数字基带信号”0“和”1“时，其数学表达式为：$$ u(t)= \left\{ \begin{align} &0&"0"\\ &U_m\cos\omega t&"1" \end{align} \right. $$移频键控（FSK）用频率$f_1,f_2$分别代表数字基带信号”0“和”1“时，其数学表达式为：$$ u(t)= \left\{ \begin{align} &U_m\cos2\pi f_1t=U_m\cos\omega_1 t&"0"\\ &U_m\cos2\pi f_2t=U_m\cos\omega_2 t&"1" \end{align} \right. $$移相键控（PSK）用相位0和相位$\pi$分别代表数字基带信号”0“和”1“时，其数学表达式为：$$ u(t)= \left\{ \begin{align} &U_m\cos(\omega t+0)&"0"\\ &U_m\cos(\omega t+\pi)&"1" \end{align} \right. $$FSK信号的解调PSK信号的解调常用远动信道架空明线或电缆在专用有线信道中，远动信号以脉冲的幅值、极性或交流电的频率在架空明线或电缆中传送。这种信道的线路衰减大，难以将信号传送到远距离，常用作近距离传递。电力线载波通道在以传输电力为主要目的的高压输电线路上，采用高频信号传输信息的信道。优点：投资少、施工期短、设备简单、无中继通信距离长缺点：传输质量差光纤信道以光波作载波，光纤为传输介质优点：具有很强的抗干扰能力、传输速率高、调制方式简单、损耗小、保密性好微波信道利用无线电波以自由空间为信道来传输信号。优点：占有频带宽，可容纳多设备工作；通信容量大；受外部干扰少，传输质量高，误码率低；通信稳定度高；方向性强，保密性好。
概念定义设函数$f(t)$是定义在$[0,+\infty)$上的实值函数，如果对于复参数$s=\beta+j\omega$，积分$$ F(s)=\int_-^{+\infty}f(t)e^{-st}dt $$在复平面s的某一区域内收敛，则称$F(s)$是$f(t)$的拉普拉斯变换，记为$F(s)=\mathscr{L}[f(t)]$；称$f(t)$是$F(s)$的拉普拉斯逆变换，记为$f(t)=\mathscr{L}_{-1}[F(s)]$$f(t)$的拉氏变换实际上是$f(t)u(t)e^{-\beta t}$的傅里叶变换，即：首先通过单位阶跃函数使函数在$t<0$的部分充零或补零对函数在$t>0$的部分乘上一个衰减的指数函数$e^{-\beta t}$，使函数$f(t)u(t)e^{-\beta t}$满足傅里叶积分条件拉普拉斯变换存在定理设函数$f(t)$满足：在$t\ge 0$的任何有限区间上分段连续当$t\rightarrow+\infty$时，$f(t)$具有有限的增长性，即存在常数$M>0,c$使得$$ |f(t)|\le Me^{ct}(0\le t\le+\infty) $$称常数$c$为$f(t)$的增长指数。则像函数$F(s)$在半平面$\mathrm{Re}\ s>c$上一定存在且解析。性质线性性质设$F(s)=\mathscr{L}[f(t)],G(s)=\mathscr{L}[g(t)],\alpha,\beta$为常数，则$$ \mathscr{L}[\alpha f(t)+\beta g(t)]=\alpha F(s)+\beta G(s)\\ \mathscr{L}^{-1}[\alpha F(s)+\beta G(s)]=\alpha f(t)+\beta g(t) $$相似性质设$F(s)=\mathscr{L}[f(t)],a>0$，则$$ \mathscr{L}[f(at)]=\cfrac1{a}F\left(\cfrac{s}a\right) $$微分性质导数的像函数设$\mathscr{L}[f(t)]=F(s)$，则$$ \mathscr{L}[f'(t)]=sF(s)-f(0) $$一般地，有$$ \mathscr{L}[f^{(n)}(t)]=s^nF(s)-s^{n-1}f(0)-s^{n-2}f'(0)-\cdots-f^{(n-1)}(0) $$像函数的导数设$\mathscr{L}[f(t)]=F(s)$，则$$ F'(s)=-\mathscr{L}[tf(t)] $$一般地，有$$ F^{(n)}(s)=(-1)^n\mathscr[t^nf(t)] $$积分性质积分的像函数设$\mathscr{L}[f(t)]=F(s)$，则$$ \mathscr{L}\left[\int_0^tf(t)dt\right]=\cfrac1sF(s) $$一般地，有$$ \mathscr{L}\left[\underbrace{\int_0^tdt\int_0^tdt\cdots\int_0^t}_nf(t)dt\right]=\cfrac1{s^2}F(s) $$像函数的积分设$\mathscr{L}[f(t)]=F(s)$，则$$ \int_s^{\infty}F(s)ds=\mathscr{L}\left[\cfrac{f(t)}t\right] $$一般地，有$$ \underbrace{\int_s^\infty ds\int_s^\infty ds\cdots \int_s^\infty}_nF(s)ds=\mathscr{L}\left[\cfrac{f(t)}{t^n}\right] $$延迟性质设$\mathscr{L}[f(t)]=F(s)$，当$t<0$时，$f(t)=0$，则对任一非负实数$\tau$有$$ \mathscr{L}[f(t-\tau)]=e^{-s\tau}F(s) $$位移性质设$\mathscr{L}[f(t)]=F(s)$，$a$为一复常数，则有$$ \mathscr{L}[e^{at}f(t)]=F(s-a) $$周期函数的像函数设$f(t)$是$[0,+\infty)$内以$T$为周期的函数，且$f(t)$在一个周期内逐段光滑，则$$ \mathscr{L}[f(t)]=\cfrac{1}{1-e^{-sT}}\int_0^Tf(t)e^{-st}dt $$卷积定理设$\mathscr{L}[f_1(t)]=F_1(s),\mathscr{L}[f_2(t)]=F_2(s)$，则$$ \mathscr{L}[f_1(t)*f_2(t)]=F_1(s)\cdot F_2(s) $$拉普拉斯逆变换的求解反演积分公式$$ f(t)=\cfrac1{2\pi j}\int_{\beta-j\omega}^{\beta+j\omega}F(s)e^{st}ds\ \ (t>0) $$留数计算法设$F(s)$除在半平面$\mathrm{Re}\ s\le c$内有限个鼓励奇点$s_1,s_2,\cdots,s_n$外是解析的，且当$s\rightarrow\infty$时，$F(s)\rightarrow0$，则有$$ f(t)=\sum_{k=1}^n\mathrm{Res}[F(s)e^{st},s_k]\ \ (t>0) $$
傅里叶变换的概念傅里叶级数三角形式设$f_T(t)$是以$T$为周期的实值函数，且在$\left[-\cfrac T2,\cfrac T2\right]$上满足狄利克雷条件，则在$f_T(t)$的连续点处有$$ f_T(t)=\cfrac{a_0}2+\sum_{n=1}^{+\infty}(a_n\cos n\omega_0 t+b_n\sin n\omega_0 t) $$其中：$$ \omega_0=\cfrac{2\pi}T\\ a_n=\cfrac2T\int_{-\frac T2}^{\frac T2}f_T(t)\cos n\ \omega_0 t\ dt\\ b_n=\cfrac2T\int_{-\frac T2}^{\frac T2}f_T(t)\sin n\ \omega_0 t\ dt $$在间断点处，$f_T(t)$变为$\cfrac12[f_T(t+0)+f_T(t-0)]$复指数形式$$ f_T(t)=\sum_{n=-\infty}^{+\infty}c_n\ e^{jn\omega_0t}\\ c_n=\cfrac1T\int_{-\frac T2}^{\frac T2}f_T(t) e^{-jn\omega_0t}\ dt $$若令$$ A_0=\cfrac{a_0}2,An=\sqrt{a_n^2+b_n^2},\cos\theta_n=\cfrac{a_n}{A_n},\sin\theta_n=-\cfrac{-b_n}{A_n} $$则傅里叶级数的三角形式可以写为$$ \begin{aligned} f_T(t)&=A_0+\sum_{n=1}^{+\infty}A_n(\cos \theta_n\cos n\omega_0t-\sin\theta_n\sin n\omega_0t)\\ &=A_0+\sum_{n=1}^{+\infty}A_n\cos(n\omega_0t+\theta_n) \end{aligned} $$即，一个周期为T的信号可以分解为简谐波之和，这些谐波的（角）频率分别为一个基频$\omega_0$的倍数。由复指数形式可以看出：$$ c_0=A_0,\arg c_n=-\arg c_{-n}=\theta_n\\ |c_n|=|c_{-n}|=\cfrac12\sqrt{a_n^2+b_n^2}=\cfrac{A_n}2 $$称$c_n$为周期函数$f_T(t)$的离散频谱，$|c_n|$为离散振幅谱，$\arg c_n$为离散相位谱。傅里叶积分与傅里叶变换傅里叶积分公式条件：$f(t)$在$(-\infty,+\infty)$上的任一有限区间满足狄利克雷条件，且在$(-\infty,+\infty)$上绝对可积,即$\int_{-\infty}^{+\infty}|f(t)|dt<+\infty$将非周期函数$f(t)$看成是由周期函数$f_T(t)$当$T\rightarrow+\infty$时转化过来的，有$$ f(t)=\cfrac1{2\pi}\int_{-\infty}^{+\infty}\left[\int_{-\infty}^{+\infty}f(\tau)e^{-j\omega\tau}d\tau\right]e^{j\omega t}d\omega $$在间断点处，$f(t)$变为$\cfrac12[f(t+0)+f(t-0)]$傅里叶变换令$$ F(\omega)=\int_{-\infty}^{+\infty}f(t)e^{-j\omega t}dt $$则有$$ f(t)=\cfrac1{2\pi}\int_{-\infty}^{+\infty}F(\omega)e^{j\omega t}d\omega $$$F(\omega)$称为$f(t)$的像函数，$f(t)$称为$F(\omega)$的像原函数称$F(\omega)$为频率密度函数，称$|F(\omega)|$为振幅谱，$\arg F(\omega)$为相位谱抽样信号记$Sa(t)=\cfrac{\sin t}{t}$，信号$\cfrac{\alpha}{\pi}Sa(\alpha t)$（$Sa(t)$）称为抽样信号单位冲激函数概念与性质单位冲激函数$\delta(t)$满足下面两个条件：当$t\not= 0$时，$\delta(t)=0$$\int_{-\infty}^{+\infty}\delta(t)dt=1$性质1：筛选性质设$f(t)$是定义在实数域$R$上的有界函数，且在$t=0$处连续，则$$ \int_{-\infty}^{+\infty}\delta(t)f(t)dt=f(0) $$一般地，若$f(t)$在$t=t_0$点连续，则$$ \int_{-\infty}^{+\infty}\delta(t-t_0)f(t)dt=f(t_0) $$性质2$\delta$函数为偶函数，$\delta(t)=\delta(-t)$性质3设$u(t)$为单位阶跃函数$$ u(t)= \left\{ \begin{align} &1,&t>0,\\ &0,&t<0, \end{align} \right. $$有$$ \int_{-\infty}^t\delta(t)dt=u(t)\\ \cfrac{d[u(t)]}{dt}=\delta t $$$\delta$函数的傅里叶变换$$ \mathscr{F}[\delta(t)]=\int_{-\infty}^{+\infty}\delta(t)e^{-j\omega t}dt=1 $$即单位冲激函数包含各种频率分量且它们具有相等的幅度，称为均匀频谱或白色频谱显然有逆变换：$$ \mathscr{F}^{-1}[1]=\cfrac{1}{2\pi}\int_{-\infty}^{+\infty}e^{j\omega t}d\omega=\delta(t) $$设$f(t)$是以$T$为周期的实值函数，且在$\left[-\cfrac T2,\cfrac T2\right]$上满足狄利克雷条件，则$f(t)$和$F(\omega)=\sum \limits_{n=-\infty}^{+\infty}2\pi F(n\omega_0)\delta(\omega-n\omega_0)$是一对傅氏变换，其中$\omega_0=\cfrac{2\pi}T$，$F(n\omega_0)$是$f(t)$的离散频谱。傅里叶变换的性质基本性质线性性质设$F(\omega)=\mathscr{F}[F(t)],G(\omega)=\mathscr{F}[g(t)],\alpha,\beta$为常数，则$$ \mathscr{F}[\alpha f(t)+\beta g(t)]=\alpha F(\omega)+\beta G(\omega)\\ \mathscr{F}^{-1}[\alpha F(\omega)+\beta G(\omega)]=\alpha f(t)+\beta g(t) $$位移性质设$F(\omega)=\mathscr{F}[f(t)],t_0,t_\omega$为实常数，则$$ \mathscr{F}[f(t-t_0)]=e^{-j\omega t_0}F(\omega)\\ \mathscr{F}^{-1}[F(\omega-\omega_0)]=e^{j\omega_0t}f(t) $$相似性质设$F(\omega)=\mathscr{F}[f(t)],a$为非零常数，则$$ \mathscr{F}[f(at)]=\cfrac1{|a|}F\left(\cfrac{\omega}a\right) $$微分性质若$\lim \limits_{|t|\rightarrow+\infty}f(t)=0$，则$$ \mathscr{F}[f'(t)]=j\omega\mathscr{F}[f(t)] $$一般地，若$\lim \limits_{|t|\rightarrow+\infty}f^{(k)}(t)=0$，则$$ \mathscr{F}[f^{(n)}(t)]=(j\omega)^n\mathscr{F}[f(t)] $$积分性质设$g(t)=\int_{-\infty}^t f(t)dt$，若$\lim\limits_{t\rightarrow+\infty}g(t)=0$，则$$ \mathscr{F}[g(t)]=\cfrac1{j\omega}\mathscr{F}[f(t)] $$帕塞瓦尔等式设$F(\omega)=\mathscr{F}[f(t)]$，则$$ \int_{-\infty}^{+\infty}f^2(t)dt=\cfrac1{2\pi}\int_{-\infty}^{+\infty}|F(\omega)|^2d\omega $$卷积设实值函数$f_1(t),f_2(t)$在$(-\infty,+\infty)$内有定义，若反常积分$\int_{-\infty}^{+\infty}f_1(\tau)f_2(t-\tau)d\tau$对任何实数$t$收敛，则它定义了一个自变量为$t$的函数，称为$f_1(t),f_2(t)$的卷积，记为$f_1(t)*f_2(t)$：$$ f_1(t)*f_2(t)=\int_{-\infty}^{+\infty}f_1(\tau)f_2(t-\tau)d\tau $$显然，卷积满足交换律、结合律与分配律。设$F_1(\omega)=\mathscr{F}[f_1(t)],F_2(\omega)=\mathscr{F}[f_2(t)]$，则有$$ \mathscr{F}[f_1(t)*f_2(t)]=F_1(\omega)\cdot F_2(\omega)\\ \mathscr{F}[f_1(t)\cdot f_2(t)]=\cfrac1{2\pi}F_1(\omega)*F_2(\omega) $$
单相短路跳开故障单相经一定时间重合单相，若不成功再跳开三相的重合方式。特点故障相选择元件为实现单相重合闸，首先必须有故障相的选择元件。根据网络接线和运行的特点，满足以上要求的常用选相元件有以下几种：电流选相元件：在每相上装设一个过电流继电器，其启动电流按照大于最大负荷电流的原则进行整定，以保证动作的选择性。这种选相元件适于装设在电源端，且短路电流比较大的情况，它是根据故障相短路电流增大的原理的原理而动作的。低电压选相元件：用三个低电压继电器分别接于三相的相电压上，低电压继电器是根据故障相电压降低的原理而动作。它的启动电压应小于正常运行时以及非全相运行时可能出现的最低电压。这种选相元件一般适于装设在小电源侧或单侧电源线路的受电侧，因为在这一侧如用电流选相元件，则往往不能满足选择性和灵敏性的要求。阻抗选相元件、相电流差突变量选相元件等，常用于高压输电线路上，有较高的灵敏度和选相能力。动作时限的选择不论是单侧电源还是双侧电源，均应考虑两侧选相元件与继电保护以不同时限切除故障的可能性。潜供电流对灭弧所产生的影响。对单相重合闸的评价优点：能在绝大多数的故障情况下保证对用户的连续供电，从而提高供电的可靠性；当由单侧电源单回路向重要负荷供电时，对保证不间断供电更有显著的优越性双侧电源的联络线上采用单相重合闸，可以在故障时大大加强两个系统之间的联系，从而提高系统并列运行的动态稳定性。对于联系比较薄弱的系统，采用单相重合闸可以避免两系统解列缺点：需要有按相操作的断路器需要专门的选相元件与继电器保护相配合保护的接线、整定计算和调试工作复杂
单侧电源线路的三相一次自动重合闸无论本线路发生何种类型的故障，继电保护装置均将三相断路器跳开，重合闸启动，经预定延时发出重合脉冲，将三相短路器一起合上。若是瞬时性故障，因故障已经消失，重合成功，线路继续运行，若是永久性故障，继电保护再次动作跳开三相，不再重合。双侧电源线路的检同期三相一次自动重合闸双侧电源输电线路重合闸的特点线路上发生故障跳闸以后，常常存在着重合闸时两侧电源是否同步，以及是否允许非同步合闸的问题。线路上发生故障时，两侧的保护可能以不同的时限动作于跳闸，线路两侧的重合闸必须保证在两侧的断路器都跳闸以后，再进行重合。检同期自动重合闸的方式当必须满足同期条件才能合闸时，需要使用检同期重合闸。检同期重合有以下几种方法：系统的结构保证线路两侧不会失去同步。电力系统之间，在电气上有紧密的联系时，由于同时断开所有联系的可能性几乎不存在，因此，当任一条线路断开之后又进行重合闸时，都不会出现非同步合闸的问题，可以直接使用不检同步重合闸。在双回线路上检查另一线路有电流的重合方式。在没有其他旁路联系的双回线路上，当不能采用非同步重合闸时，可采用检定另一回线路上是否有电流的重合闸。当另一回线路上有电流时，即表示两侧电源仍保持联系，一般是同步的，因此可以重合。必须检定两侧电源确实同步之后，才能进行重合。重合闸时限的整定原则单侧电源线路的三相重合闸最小时间按下述原则确定：在断路器跳闸后，负荷电动机向故障点反馈电流的时间故障点的电弧熄灭并使周围介质恢复绝缘强度需要的时间在断路器动作跳闸熄弧后，其触头周围绝缘强度的恢复以及消弧室重新充满油、气需要的时间断路器操动机构恢复原状准备好再次动作需要的时间如果重合闸利用继电保护跳闸出口启动，其动作时间还应该加上断路器的跳闸时间自动重合闸与继电保护的配合重合闸前加速保护任何一条线路上发生故障时，第一次都瞬间无选择性动作予以切除优点：能够快速地切除瞬时性故障；可能使瞬时性故障来不及发展成永久性故障，从而提高重合闸的成功率能保证发电厂和重要变电所的母线电压在0.6~0.7倍额定电压以上，从而保证厂用电和重要用户的用电质量使用设备少，只需装设一套重合闸装置，简单，经济缺点：断路器工作条件恶劣，动作次数多重合于永久性故障上时，故障切除的时间可能较长如果重合闸装置或断路器拒绝合闸，则将扩大停电范围重合闸后加速保护第一次有选择性动作，重合于永久性故障则瞬时切除故障优点：第一次是有选择性地切除故障，不会扩大停电范围，特别是在重要的高压电网中，一般不允许保护无选择性地动作而后重合闸来纠正保证了永久性故障能瞬时切除使用中不受网路结构和符合条件限制缺点：每个断路器上都需要装设一套重合闸，与前加速相比略微复杂第一次切除故障可能带有延时