php 家政服务管理系统

设计主要要求其实现以下功能: 1.会员可以查询和搜索所有相关的家政服务项目。 2.家政服务提供者可以随时更新和删除自己的服务项目。 3.待业人员可以提交自己的简历给家政服务公司。 4.会员可以在线跟家政服务公司预约及完成交易。 在了解了基本的家政服务的服务流程之后,对管理平台的设计与实现需求进行分析,确认整个管理平台的设计与实现系统的模块的依赖关系和优先级。优先和重点完成系统设计与实现中的一些基础模块。一步一步的详细设计每个模块。 工作重点:家政服务的提供和展示、会员注册登录、家政服务的预约、订单处理、后台数据库管理等功能。 技术路线:本毕业设计采用PHP和MySQL数据库开发家政服务管理系统。本系统中解决了家政管理事务中的常用基本问题以及相关统计工作。本系统使用PHP进行网页界面的设计,使用mvc设计模式,MySQL数据库进行连接。 目 录 引 言 1 1 绪论 1 1.1 课题背景 1 1.2 课题研究的目的和意义 1 1.3 课题的可行性研究 2 1.3.1 技术可行性 2 1.3.2 经济可行性 2 1.3.3 操作可行性 2 1.3.4 法律可行性 2 2 开发技术介绍 2 2.1 B/S体系结构 2 2.2 PHP技术 3 2.3 MYSQL数据库 4 2.4 Apache 服务器 5 2.5 WAMP 6 3 系统总体设计分析 6 3.1 需求分析 6 3.2功能模块设计 8 3.3数据库设计 8 3.3.1概念设计 8 3.3.2逻辑设计 9

css第二课:外部样式link和import的运用及行内样式的介绍

一:外部样式 1.先讲用link引入外部样式: 首先我们新建一个css文件夹,放外部css样式文件,然后创建一个css文件(.css),如下图: 新建一个html文件写代码,代码,在css文件里写样式,然后用link将这个css样式引入的html中, 如下图: 结果: link属性介绍:rel=“stylesheet”、type=“text/css”为默认值不用管,href是你要写css样式的文件地址 2.用import引入外部标签 代码演示: 结果: 虽然两个都可以引入外部样式,但是还是有一些区别的,如下: 看了上面的区别,还是建议用link,不会出问题,但是注意一点:无论是link还是import都是在head里面引入的css外部样式哦 二、行内样式 行内样式,有的地方也称为内联样式、嵌入式样式 行内样式就是在要修饰的内容所在的标签里面写style,如下: 代码演示: 结果: 行内样式要修饰的每一个都要写,看起来有点乱,所以我们不经常用,当只有一个内容需要修饰的时候,才会去用,但这种情况很少存在,所以我们不经常用,我们经常用的是外部样式。 优先级问题: 当我们将三个样式都来修饰一个标签内容时,这时候就有标签优先级的问题了, 行内样式>内部样式>外部样式 此时还有一个东西就是“!important”,你将这个加载谁后面谁的优先级就是最大的,如下图所示: 结果: 所以优先级是:!important>行内样式>内部样式>外部样式 注意:这个!important是在声明的分号之前加的

GameFramework:GameFramework.dll替换GF源码

想学习GameFramework,看不到源码,代码跟踪十分不方便,一起来,解决此问题。 前言 提示:我是以官方的示例工程Starforce做演示的: GitHub地址:GameFramework 在此之前我是下载了,GameFramework库,StarForce库,UnityGameFramework库,大家最好都是最新版。 开始弄起起来。 1、UnityGameFramework库里面的删除LICENSE.md,README.md 和对应的meta文件。 2、UnityGameFramework库里面内容全部复制到StarForce\Assets\GameFramework目录下。 3、删除目录 StarForce\Assets\GameFramework\Libraries 下 GameFramework.dll和meta文件。 4、把GameFramework库里面GameFramework里面除了GameFramework.csproj文件全部复制到 StarForce\Assets\GameFramework目录下。 5、效果如下图。创建GameFramework程序集定义文件。 6、因为删除GameFramework.dll,引用丢失会有一堆报错,我们重新处理一下程序集的引用,如下图,把我们新建的GameFramework程序集定义文件 添加进去。 Runtime文件夹下去UnityGameFramework.Runtime,也是如此添加。报错就没有了。 7、运行成功了,大家可以快乐的调试源码了。

springBoot学习笔记(完结)

本文章是 👉bilibili狂神老师 springboot视频的笔记 下面是⬇️正文,目录在侧边💕 SpringBoot 简介 Spring是为了解决企业级应用开发的复杂性而创建的,简化开发。 Spring是如何简化Java开发的 为了降低Java开发的复杂性,Spring采用了以下4种关键策略: 1、基于POJO的轻量级和最小侵入性编程,所有东西都是bean; 2、通过IOC,依赖注入(DI)和面向接口实现松耦合; 3、基于切面(AOP)和惯例进行声明式编程; 4、通过切面和模版减少样式代码,RedisTemplate,xxxTemplate; 什么是SpringBoot 什么是SpringBoot呢,就是一个javaweb的开发框架,和SpringMVC类似,对比其他javaweb框架的好处,官方说是简化开发,约定大于配置, you can “just run”,能迅速的开发web应用,几行代码开发一个http接口。 所有的技术框架的发展似乎都遵循了一条主线规律:从一个复杂应用场景 衍生 一种规范框架,人们只需要进行各种配置而不需要自己去实现它,这时候强大的配置功能成了优点;发展到一定程度之后,人们根据实际生产应用情况,选取其中实用功能和设计精华,重构出一些轻量级的框架;之后为了提高开发效率,嫌弃原先的各类配置过于麻烦,于是开始提倡“约定大于配置”,进而衍生出一些一站式的解决方案。 是的这就是Java企业级应用->J2EE->spring->springboot的过程。 随着 Spring 不断的发展,涉及的领域越来越多,项目整合开发需要配合各种各样的文件,慢慢变得不那么易用简单,违背了最初的理念,甚至人称配置地狱。Spring Boot 正是在这样的一个背景下被抽象出来的开发框架,目的为了让大家更容易的使用 Spring 、更容易的集成各种常用的中间件、开源软件; Spring Boot 基于 Spring 开发,Spirng Boot 本身并不提供 Spring 框架的核心特性以及扩展功能,只是用于快速、敏捷地开发新一代基于 Spring 框架的应用程序。也就是说,它并不是用来替代 Spring 的解决方案,而是和 Spring 框架紧密结合用于提升 Spring 开发者体验的工具。Spring Boot 以约定大于配置的核心思想,默认帮我们进行了很多设置,多数 Spring Boot 应用只需要很少的 Spring 配置。同时它集成了大量常用的第三方库配置(例如 Redis、MongoDB、Jpa、RabbitMQ、Quartz 等等),Spring Boot 应用中这些第三方库几乎可以零配置的开箱即用。 简单来说就是SpringBoot其实不是什么新的框架,它默认配置了很多框架的使用方式,就像maven整合了所有的jar包,spring boot整合了所有的框架 。 Spring Boot 出生名门,从一开始就站在一个比较高的起点,又经过这几年的发展,生态足够完善,Spring Boot 已经当之无愧成为 Java 领域最热门的技术。 主要优点 Spring Boot的主要优点:

2022“杭电杯”中国大学生算法设计超级联赛(9)

1008:Problem - 7240 (hdu.edu.cn) 题意:给定一个图,求图上两点之间的最短距离,两点之间的举例为两数的最大公约数 题解:二进制容斥原理+优化 两点若互质,则距离直接为1,且无更短或重复的路径了 若不互质或者gcd为2,则需要考虑范围内 与二者都互质的数有多少,互质的数即意味着 最大公约数为1,所以我们只需要排除掉两个数的质因子所构成的所有数即可,这里求两个数的质因子也需要注意,不能算重复,存储的时候需要记录是否重复,这里通过二进制容斥可以快速求解,一定数量的质因子所能构成的数的数目,但是这里容斥原理需要优化,不能一个二进制位一个二进制位的看该位是否为1,我们可以通过lowbit(int x)函数快速得到最低位1所构成的数的大小,还需要预处理2^n,快速求解该数所对应着第几位,然后通过容斥原理,我们便可筛选掉不互质的数了。‘ 还有一点需要注意,若两数gcd为2,最后还需要考虑+1。 #include <bits/stdc++.h> using namespace std; typedef long long LL; const int N=10000100; const int maxn=1e7; int n,q; const int mod=998244353; const int NN=2e5+10; int pre[NN]; set<int>st1,st2; inline int lowbit(int x){//快速求解最低位1所对应的数字 return x&(-x); } vector<int>ve;//存储两数的质因子,注意不能重复存,会浪费时间 inline void divide(int n) {//求解质因子 for(int i=2; i<=n/i; i++) { if(n%i==0) { int s=0; while(n%i==0) { n/=i; s++; } if(!st1.count(i)) {//判重,若重复了,则不需要存了 st1.insert(i); ve.push_back(i); } } } if(n>1) { if(!

数据库基本知识

主键 主键是数据表中对数据对象能够唯一和完整标识的数据列或数据列的组合 但能唯一和完整标识的列不一定是主键 主键要满足的条件: 一个表只能有一个主键 但该主键可以由多个列组成 任意两行主键的值(或组合)都不相同不能有空值(NULL)值不允许修改或更新值不能被重用 如果某行从表中删除,它的主键不能赋给以后的新行 使用innodb作为存储引擎的数据库,表必须有主键 因为表数据文件本身就是按B+Tree组织的一个索引结构,主键索引存放的顺序就是数据存放的顺序如果没有定义主键,数据库会会自动选择一个可以唯一标识数据记录的列作为主键如果不存在这种列,则MySQL自动为InnoDB表生成一个隐含字段作为主键,这个字段长度为6个字节,类型为长整形 主键建议使用自增ID 否则会不得不为了将新记录插到合适位置而移动数据,可能造成page分裂,这降低了写入的性能同时频繁的移动、分页操作造成了大量的碎片,得到了不够紧凑的索引结构,增大了空间占用 主键尽量选择较短的数据类型 因为普通索引都会保存主键的值,较短的数据类型可以有效的减少索引的磁盘空间 索引 索引改善检索操作的性能,但降低了数据插入、修改和删除的性能索引数据可能要占用大量的存储空间索引的效率随表数据的增加或改变而变化 最好定期检查索引,并根据需要对索引进行调整 聚簇(主键)索引 聚簇索引叶子节点的值存储的就是要查找的数据,只需要一次查询主键一定是聚簇索引,修改聚簇索引其实就是修改主键 主键索引的叶子节点就是数据行,包括了所有数据字段 聚簇索引的顺序就是数据存放的顺序一个表只能创建一个聚簇索引,但可以创建多个辅助索引 辅助(二级)索引的存储和数据的存储是分离的 一般将索引存在内存中,而数据存在磁盘上辅助索引搜索需要检索两遍索引:首先检索辅助索引获得主键,然后用主键到主索引中检索获得记录(回表) 覆盖索引 当查询的列就是索引字段本身(或者主键)时,这种场景下该普通索引也可以实现一次查询,无需回表一般通过新增联合索引实现对相应字段的覆盖索引 MySQL中一张表最多可以创建 64 个非聚簇索引;而且创建非聚簇索引时,列的数量不能超过16个 联合索引 联合索引采取最左匹配原则 针对的是创建的联合索引中的顺序, 这个索引的使用顺序就很重要 如果创建了联合索引(x,y,z),如果在条件语句中只有 y 和 z,那么就用不上联合索引 MySQL 在匹配联合索引最左前缀的时候,如果遇到了范围查询,比如 <, > 和 between 等,就会停止继续匹配,后面的索引列就无法使用到索引 在多条件联合查询的时候最好创建联合索引,因为多个单列索引在多条件查询时只会生效一个索引采用 = 查询或者是 IN 查询时,MySQL 的优化器会自动帮我们调整为可以使用联合索引的形式为什么不创建一个由所有的字段组成的联合索引? 用所有的字段创建组合索引的存储成本比较高利用率比较低,完全用上的可能性几乎不存在一旦更改任何一个字段的数据,就必须要改索引,这样操作成本也比较高 自适应哈希索引 哈希索引的优点 数据检索的时候效率非常高,通常只需要 O(1) 的复杂度,也就是一次就可以完成数据的检索 哈希索引的缺点 自适应 Hash 索引 自适应指的是不需要人工来制定,系统会根据情况自动完成 如果某个索引值被使用的非常频繁时,就会将这个数据页的地址存放到 Hash 表中 自适应 Hash 索引只保存热数据,数据量并不会很大 因此自适应 Hash 也是存放到缓冲池中,这样也进一步提升了查找效率 采用自适应 Hash 索引目的是方便根据 SQL 的查询条件加速定位到叶子节点 特别是当 B+ 树比较深的时候 索引友好的SQL语句 什么时候需要创建索引: 字段的数值有唯一性的限制,比如用户名频繁作为 WHERE 查询条件的字段 包括UPDATE和DELETE操作,因为需要先检索出来这条记录,然后再对它进行更新或删除 需要经常 GROUP BY 和 ORDER BY 的列DISTINCT 字段需要创建索引 什么时候不需要索引: 起不到定位的字段通常是不需要创建索引 即WHERE 或 GROUP BY、ORDER BY 里用不到的字段 频繁更新的字段不一定要创建索引 因为更新数据的时候,也需要更新索引,如果索引太多,在更新索引的时候也会造成负担 表记录太少时不需要创建索引字段中如果有大量重复数据,也不用创建索引 索引失效场景: 对索引进行了表达式计算对索引使用函数WHERE 子句中,在 OR 前的条件列进行了索引,而在 OR 后的条件列没有进行索引使用 LIKE 进行模糊查询的时候,以_或%开头索引列与 NULL 或者NOT NULL 进行判断NOT 等负向查询条件字符串当整型使用等隐式类型转换复合索引最左匹配失败数据少时mysql觉得全表扫描更快

Linux ubuntu 1804 版 安装过程图解说明--详细

ubuntu 的内核版本很新, 比centos和rhel 更新的更快, server 版本也适合进行一些新服务的安装部署测试, 比如docker, k8s 容器等. 实际生产环境下, 作为开源Linux 的一种也很瘦欢迎. 也有大量的公司在生产环境使用. 安装ubuntu 系统 ( 在vm 虚拟机里进行安装 ) 1>. 首先安装好vm虚拟机就不多说了. ( 下载安装, 下一步下一步即可, 建议存放在较大的磁盘里. 虚拟机安装系统后占用的空间很大, 也可以系统和虚拟机分开存放 ) 到ubuntu 官网去下载镜像. ( 由于是在国外, 下载速度较慢, 推荐在国内的镜像站下载, 比如阿里, 华为云, 各大学的镜像站, 互联网公司的都可以 ) 以下是腾讯的开源镜像站 链接 ) Index of /ubuntu-releases/18.04/ (1). 创建新的虚拟机 选择典型(推荐) , 安装客户机操作系统, 选择稍后安装操作系统选项, 选择系统类型和版本 给新安装的系统起名称和选择存放位置 给新系统划分磁盘空间大小( 会从物理机 划分一块空间出来用作系统安装 ) 挂载ios文件, 并且勾选启动时连接, 否则启动后识别不到镜像文件, 会黑屏出现operating system not found , 不能继续, 切记勾选. 点击开启虚拟机 , 启动后开始安装过程

python简单程序爬取酷我音乐歌曲信息

程序自动过滤掉《歌手(artist)》部分字符串长度大于6字节的数据,使后期的表格更美观 而导致筛选后没有30条数据 程序--down_music--方法中: header部分得自己加上去 在酷我音乐中按12打开点击network,Ctrl+R刷新一下随便打开一个文件查看 Cookie: csrfHost: Referer: User-Agent: 如需要有30条数据,需要删除第39行条件判断: ''' 歌曲连接: http://www.kuwo.cn/api/www/search/searchMusicBykeyWord?key=%E6%9D%8E%E8%8D%A3%E6%B5%A9&pn=1&rn=30&httpsStatus=1&reqId=189d5b41-238d-11ed-acf4-4f6bf15618b2 ''' import requests import prettytable as pt # 制表 import time class Kuwo_music: def __init__(self, urls): self.urls = urls def get_html(self, url): header = { "Cookie": "自己加 ", "csrf": "自己加", "Host": "www.kuwo.cn", "Referer": "http://www.kuwo.cn/search/list?key=%E6%9D%8E%E8%8D%A3%E6%B5%A9", "User-Agent": "自己加" } return requests.get(url, headers=header) def down_music(self): json_data = self.get_html(self.urls).json() json_list = json_data['data']['list'] tb = pt.PrettyTable() tb.field_names = ["序号", "歌手", "歌曲", "

尝试编写一个加密程序,加密方法将明文的字母变成其后的第4个字母,**字母表首尾相连。非字母符号** 不加密。 例如输入“China“, 输出密文“Glmre“, 输入 “ab123“, 输出 “ef1

function convert(str) { // write your code here … let arr = str.split(‘’) //切割字符串 let res = ‘’ arr.map(s => { let news = s let code = s.charCodeAt() // 97 - 122 a-z // 65 - 90 A-Z if (code >= 97 && code <= 122) { // a- z 的处理 code += 4 if (code > 122) { code = 96 + code - 122 } news = String.

C++ STL vector用法详解

一:简介: vector是c++中一种非常常用的数据类型,也叫不定长数组,是STL的一种容器。我们可以随时向其中插入一个数据,在定义时也不需要指定其大小,使用方便。再加上他的很多特性,并且支持sort函数排序,深受码农们以及竞赛党喜爱。 二:头文件: #include<vector> 三:定义: vector<类型名> 变量名 //例如 vector<string> wwyz; 也可以在变量名后加入(数值)来设置一个大小为添加数值的一个数组。 vector<string> s(5); 如上面代码所示,我们就设置了一个长度为5的变量名为s的一个字符串型数组,当前s[0]-s[5]的值均为空。值得一提的是,我们虽然设置了大小,我们仍然可以在s后继续添加元素。 我们还可以在变量名后的()中设置两个数值. vector<string> s(5,"wwyz"); 这样就表示我们就在长度为5的数组中,给每一个元素都赋值了5. 四:含义: vector声明其类型为不定长数组,类型名可以为任意类型(pair<>也可以使用),变量名即为以后要操作的变量> 五:插入元素: vector常见的插入操作有两种. 一:push_back() s.push_back("booyi"); 这就表示我们在s数组末尾处添加了一个元素"booyi"。 二:insert() s.insert(s.begin(),"wwyz"); 这就表示我们在开头添加了元素"wwyz" 我们可以用insert()来在vector中任意位置插入元素,insert()第一个元素代表要插入的位置,第二个元素就是插入的元素. 六:获取元素: 我们可以把vector当做数组,直接用[]来获取元素. vector<int> s; s.push_back(111); cout<<s[0]; 这样我们就输出了s中第一个元素111. 也可以使用迭代器获取 #include<iostream> #include<vector> using namespace std; int main() { vector<string> s(5,"wwyz"); vector<string> :: iterator it; for(it=s.begin();it!=s.end();it++) cout<<*it<<endl; } 这样就从s开头到最后输出 wwyz wwyz wwyz wwyz wwyz 七:查找元素: #include<iostream> #include<vector> #include<algorithm> using namespace std; int main() { vector<int> a; a.

c++在windows、linux下获取指定文件夹下所有文件名的方法

一般来说,获取指定文件夹下的所有文件名,用python是较为方便的,直接: import os files_name = os.listdir(“一个路径”) 但也有c++程序偶尔也有这个需求,下面就直接上c++在windows和linux去读取文件夹下文件名的方法,不同的系统代码上有一些差别 Windows(vs) vs的环境,主要是用到了头文件<io.h>,还有以下的几点说明,大伙可以按需修改,我在代码中也做了详细的注释: 这个遇到文件夹会回归调用,所以如果不想让其进入,就在找到文件夹时直接continue;保存的仅仅是文件名,也可以保存绝对路径,在下面的else中改一下就好了;当然可以加个format格式参数,就只保留想要的后缀的文件,就自己去改了。 #include <iostream> #include <vector> #include <string> #include <io.h> // 可在这个函数中再加一个format格式参数,push到vector前判断下文件名后缀,仅保留指定格式 void GetAllFiles(std::string path, std::vector<std::string> &files) { // 用来存储文件信息的结构体,在头文件 <io.h> struct _finddata_t fileinfo; // _finddata_t 这是一个struct类,c++中可以不要前面的struct的 intptr_t hFile = 0; std::string p; // 不在这p(path)初始化 // 第一次查找 if ((hFile = _findfirst(p.assign(path).append("\\*").c_str(), &fileinfo)) != -1) { do { // 如果找到的是文件夹 if ((fileinfo.attrib & _A_SUBDIR)) { // 不想进入文件夹,就在这里continue if (std::strcmp(fileinfo.name, ".") != 0 && std::strcmp(fileinfo.

第一章:Python语言的基本要素

python语言的基本要素 注释 单行: # 多行: 选中后 ctrl+‘/’ 变量 由大小写字母、数字和下划线构成,中间不能有空格,长度不限,不能以数字开头。最好能够体现变量的含义。多单词的变量名,最好第一个单词小写,后面单词首字母大写。 赋值语句 变量 = 表达式 变量、数、字符串…都是“表达式” a,b,c="he",15,48 a,b,c=b,c,a #different with c print(a,b,c) =>15 48 he 字符串初步 字符串可以且必须用单引号、双引号或三单引号括起来.(括号里需要哪种,哪种放括号外。) 字符串里面不会包含变量! 字符串必须用引号括起来,用引号括起来的就是字符串! 三双引号字符串中可以包含换行符、制表符以及其他特殊字符 a="""'''he us w e'' '""" print(a) ---------------- '''he us w e'' ' 字符串的下标 有n个字符的字符串,其中的每个字符都是长度为1的字符串: 从左到右依次编号为 0,1,2… n-1 从右到左依次编号为 -1,-2…-n 编号就是下标 a='heisabigdeal ' print(a[0],a[-1]) ------------------- =>h 字符串不可修改:不可以修改字符串中的字符 a = "ABCD" a[2] = 'k' #wrong 用"+"连接字符串 a='mac' a=a+a[0] print(a) --------- =>macm 用 in , not in 判断子串

CAP-Quorum 复制机制(Quorum Replication)

Aurora使用了Quorum这种思想。接下来,我将描述一下经典的Quorum思想,它最早可以追溯到1970年代。Aurora使用的是一种经典quorum思想的变种。Quorum系统背后的思想是通过复制构建容错的存储系统,并确保即使有一些副本故障了,读请求还是能看到最近的写请求的数据。通常来说,Quorum系统就是简单的读写系统,支持Put/Get操作。它们通常不直接支持更多更高级的操作。你有一个对象,你可以读这个对象,也可以通过写请求覆盖这个对象的数值。 假设有N个副本。为了能够执行写请求,必须要确保写操作被W个副本确认,W小于N。所以你需要将写请求发送到这W个副本。如果要执行读请求,那么至少需要从R个副本得到所读取的信息。这里的W对应的数字称为Write Quorum,R对应的数字称为Read Quorum。这是一个典型的Quorum配置。 这里的关键点在于,W、R、N之间的关联。Quorum系统要求,任意你要发送写请求的W个服务器,必须与任意接收读请求的R个服务器有重叠。这意味着,R加上W必须大于N( 至少满足R + W = N + 1 ),这样任意W个服务器至少与任意R个服务器有一个重合。 假设你有3个服务器,并且假设每个服务器只存了一个对象。 我们发送了一个写请求,想将我们的对象设置成23。为了能够执行写请求,我们需要至少将写请求发送到W个服务器。我们假设在这个系统中,R和W都是2,N是3。为了执行一个写请求,我们需要将新的数值23发送到至少2个服务器上。所以,或许我们的写请求发送到了S1和S3。所以,它们现在知道了我们对象的数值是23。 如果某人发起读请求,读请求会至少检查R个服务器。在这个配置中,R也是2。这里的R个服务器可能包含了并没有看到之前写请求的服务器(S2),但同时也至少还需要一个其他服务器来凑齐2个服务器。这意味着,任何读请求都至少会包含一个看到了之前写请求的服务器。 这是Quorum系统的要求,Read Quorum必须至少与Write Quorum有一个服务器是重合的。所以任何读请求可以从至少一个看见了之前写请求的服务器得到回复。 这里还有一个关键的点,客户端读请求可能会得到R个不同的结果,现在的问题是,客户端如何知道从R个服务器得到的R个结果中,哪一个是正确的呢?通过不同结果出现的次数来投票(Vote)在这是不起作用的,因为我们只能确保Read Quorum必须至少与Write Quorum有一个服务器是重合的,这意味着客户端向R个服务器发送读请求,可能只有一个服务器返回了正确的结果。对于一个有6个副本的系统,可能Read Quorum是4,那么你可能得到了4个回复,但是只有一个与之前写请求重合的服务器能将正确的结果返回,所以这里不能使用投票。在Quorum系统中使用的是版本号(Version)。所以,每一次执行写请求,你需要将新的数值与一个增加的版本号绑定。之后,客户端发送读请求,从Read Quorum得到了一些回复,客户端可以直接使用其中的最高版本号的数值。 假设刚刚的例子中,S2有一个旧的数值20。每一个服务器都有一个版本号,S1和S3是版本3,因为它们看到了相同的写请求,所以它们的版本号是相同的。同时我们假设没有看到前一个写请求的S2的版本号是2。 之后客户端从S2和S3读取数据,得到了两个不同结果,它们有着不同的版本号,客户端会挑选版本号最高的结果。 如果你不能与Quorum数量的服务器通信,不管是Read Quorum还是Write Quorum,那么你只能不停的重试了。这是Quorum系统的规则,你只能不停的重试,直到服务器重新上线,或者重新联网。 相比Chain Replication,这里的优势是可以轻易的剔除暂时故障、失联或者慢的服务器。实际上,这里是这样工作的,当你执行写请求时,你会将新的数值和对应的版本号给所有N个服务器,但是只会等待W个服务器确认。类似的,对于读请求,你可以将读请求发送给所有的服务器,但是只等待R个服务器返回结果。因为你只需要等待R个服务器,这意味着在最快的R个服务器返回了之后,你就可以不用再等待慢服务器或者故障服务器超时。这里忽略慢服务器或者挂了的服务器的机制完全是隐式的。在这里,我们不用决定哪个服务器是在线或者是离线的,只要Quorum能达到,系统就能继续工作,所以我们可以非常平滑的处理慢服务或者挂了的服务。 除此之外,Quorum系统可以调整读写的性能。通过调整Read Quorum和Write Quorum,可以使得系统更好的支持读请求或者写请求。对于前面的例子,我们可以假设Write Quorum是3,每一个写请求必须被所有的3个服务器所确认。这样的话,Read Quorum可以只是1。所以,如果你想要提升读请求的性能,在一个3个服务器的Quorum系统中,你可以设置R为1,W为3,这样读请求会快得多,因为它只需要等待一个服务器的结果,但是代价是写请求执行的比较慢。如果你想要提升写请求的性能,可以设置R为3,W为1,这意味着可能只有1个服务器有最新的数值,但是因为客户端会咨询3个服务器,3个服务器其中一个肯定包含了最新的数值。 当R为1,W为3时,写请求就不再是容错的了,同样,当R为3,W为1时,读请求不再是容错的,因为对于读请求,所有的服务器都必须在线才能执行成功。所以在实际场景中,你不会想要这么配置,你或许会与Aurora一样,使用更多的服务器,将N变大,然后再权衡Read Quorum和Write Quorum。 为了实现上一节描述的Aurora的容错目标,也就是在一个AZ完全下线时仍然能写,在一个AZ加一个其他AZ的服务器下线时仍然能读,Aurora的Quorum系统中,N=6,W=4,R=3。W等于4意味着,当一个AZ彻底下线时,剩下2个AZ中的4个服务器仍然能完成写请求。R等于3意味着,当一个AZ和一个其他AZ的服务器下线时,剩下的3个服务器仍然可以完成读请求。当3个服务器下线了,系统仍然支持读请求,仍然可以返回当前的状态,但是却不能支持写请求。所以,当3个服务器挂了,现在的Quorum系统有足够的服务器支持读请求,并据此重建更多的副本,但是在新的副本创建出来替代旧的副本之前,系统不能支持写请求。同时,如我之前解释的,Quorum系统可以剔除暂时的慢副本。

C语言使用josn库解析数据

首先 添加好百度下载的json库: 代码演示: #include <stdio.h> /* char *requestHead = "GET /area-to-weather?area=广州 HTTP/1.1\r\n" "Host: ali-weather.showapi.com\r\n" "Authorization: APPCODE d487d937315848af80710a06f4592fee\r\n\r\n"; */ #include <sys/socket.h> #include <netinet/in.h> #include <netinet/ip.h> /* superset of previous */ #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> #include <arpa/inet.h> #include <stdio.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> //添加json 库文件 #include "cJSON.h" double get_double(cJSON *json, char *key) { cJSON *value = cJSON_GetObjectItem(json,key); return cJSON_GetNumberValue(value); } char *get_string(cJSON *json, char *key) { cJSON *value = cJSON_GetObjectItem(json,key); return cJSON_GetStringValue(value); } int main() { //1.

Qt中csv文件的导入与导出

CSV 1.简介: 全称:Comma Separated Values。 是“逗号分隔值”的英文缩写,通常是纯文本文件,一般用wordWPS或是记事本打开。 2.规则: (1)开头不留空,以行为单位。 (2)可含或不含列名,含列名则居文件第一行。 (3)一行数据部跨行,无空行。 (4)以半角逗号作分隔符,列为空也要表达其存在。 (5)列内容如存在半角逗号(即,)则用半角引号(即"")将该字段值包含起来。内容如存在半角逗号(即,)则用半角引号(即"")将该字段值包含起来。 (6)列内容如存在半角引号(即")则应替换成半角双引号("")转义,并用半角引号(即"")将该字段值包含起来。 (7)文件读写时引号,逗号操作规则互逆。 (8)内码格式不限,可为 ASCII、Unicode 或者其他。 (9)不支持特殊字符 3.使用:(csv文件的导入导出) 先看下一个基本demo的ui: (1)获取控件信息导入到csv文件中: void mainDialog::exportMsg() { //获取创建的csv文件名 QString fileName = QFileDialog::getSaveFileName(this, tr("Excel file"), qApp->applicationDirPath (), tr("Files (*.csv)")); if (fileName.isEmpty()) return; //打开.csv文件 QFile file(fileName); if(!file.open(QIODevice::WriteOnly | QIODevice::Text)) { std::cerr << "Cannot open file for writing: " << qPrintable(file.errorString()) << std::endl; return; } QTextStream out(&file); //获取数据 QString sName = ui->lineEdit->text();//姓名 Int iAge = ui->spinBox->tvalue();//年龄

Ubuntu (双系统)外接显示器无显示/无反映

系统:Ubuntu18.04 + Win10 问题描述 win10正常使用外接显示器;而切至ubuntu系统,外接显示器无显示/无反应 原因分析: 外接显示器使用电脑的独立显卡驱动,而Ubuntu的内置显示器是使用集显驱动的。 解决方案: 将系统的显卡驱动更换为独立显卡的驱动: 1)打开“软件和更新” 2)点击“附加驱动”(系统默认使用下图最后一个,每人附加驱动内容不同,根据电脑情况自行选择。我选择的是“使用NVIDIA driver metapackage 来自nvidia-driver-515(专有)”) 3)重启,显示器即有显示。 此外,显示器扩展设置如下: 设置–>设备–>显示(通过选择“显示模式”与“显示器排列”进行喜爱设置)

glibc编译时报错:configure: error:*** LD_LIBRARY_PATH shouldn‘t contain the current directory when ***

在编译glibc时,进到glibc源码里: cd glibc-source && mkdir build &&cd build 开始配置,执行了如下命令:../configure --prefix=/opt/glibc 然后报如下错误: “configure: WARNING: *** These auxiliary programs are missing or incompatible versions: makeinfo *** some features or tests will be disabled. *** Check the INSTALL file for required versions. checking LD_LIBRARY_PATH variable… contains current directory configure: error: *** LD_LIBRARY_PATH shouldn’t contain the current directory when *** building glibc. Please change the environment variable *** and run configure again. ”

2022”杭电杯“中国大学生算法设计超级联赛(9)1 3 7题解

1001-Arithmetic Subsequence 题目链接 题目大意: 对给定的序列进行重排,使得任意一个长度大于等于3的子序列不构成等差数列。 思路: 如果一个数出现3次以上就无解。 下面讨论有解的情况: 奇 偶 偶 或是 偶 偶 奇 这种排列一定是构不成等差数列的。 所以把奇数全部放到一端,偶数全部放到另一端。 但是这样只能保证奇数和偶数不会构成等差数列,奇数和奇数之间(或是偶数和偶数之间)仍然会构成等差数列。 因此对于全部是奇数的一端,将每个数字减1后除2,不改变等差的性质,但是会出现奇数和偶数,就可以继续用上面的方法进行分治。 对于全是偶数的一端,将每个数字除2,同样可以用上面的方法进行分治。 #include <bits/stdc++.h> const int N = 5e3 + 5; using namespace std; struct node { int num, x; } a[N]; vector<node> odd, even; void dfs(int l, int r) { if (r - l <= 1) return; //区间长度小于3的时候就退出,防止因为两个0进入无限循环 odd.clear(), even.clear(); for (int i = l; i <= r; i++) { if (a[i].

GNSS+IMU学习

1 以 GNSS+IMU 的紧耦合技术为基础,结合环境特征匹配 的综合方案将成为主流 我们认为,L3 级别自动驾驶的定位精度误差要控制在 30cm 以内。一方面,高精度 地图的绘制精度要求达到 10cm,定位精度应与地图精度匹配。另一方面,L3 级别 需要满足车道级定位精度。从国家颁布的城市道路标准可以得到相关数据,城市道 路、交叉路口、干线公路(包括高速公路)、路肩(高速公路紧急停车带)对应的 车道宽度分别为 3.5 米、 2.3-2.5 米、3.75 米以及 1.5-2.5 米,轿车的宽度一般约 2 米。由此,我们分析 L3 级别需要 10-30cm 的定位精度。在技术路线上,我们认为 自动驾驶的成熟定位方案,应该是以 GNSS+IMU 的紧耦合技术为基础,结合环境 特征匹配的综合方案。 2 GNSS 精度的提升主要依赖于增强系统的建设 传统的 GNSS 单点定位精度为米级,精度提升的主要路径是通过 RTK 技术以及建 立增强系统。 GNSS 的全称是全球导航卫星系统,包括 GPS、Glonass、Galileo、北斗及对应的增 强系统和区域系统。卫星定位原理是通过接收器与至少 4 颗卫星通讯来确定该接收 器的位臵,由于存在大气离层干扰,这种方法是伪距测量,精度只能达到米级。RTK 是一种利用 GPS 载波相位观测值进行实时动态相对定位的技术,流动站利用基准 站数据和 GPS 观测数据做差分处理,可以在野外实时得到厘米级定位结果。RTK 已经是一项成熟的技术,随着增强系统不断建设,在大多场景下车辆可以通过 GNSS 定位系统获得满足自动驾驶需要的精度。 自动驾驶车辆通过安装的车载 GNSS 接收机接收信号,比较基站接收的卫星信号做 差分处理得到高精度定位。最早利用单独的 GPS 做厘米级 RTK 固定解需要几分钟, 现在通过 GNSS 的多星多频联合结算,时间缩短到几十秒。 地基增强系统:通过在地面建立固定的参考站(CORS 站),来对比卫星定位坐标与 自身已知坐标的误差,将差分修正发送给接收机,最终使得卫星导航精度达到亚米 级。 星基增强系统:包含了 GNSS 系统中的五个增强系统,由地面参考基站,主控站, 上行注入站和地球同步卫星共同组成。差分站将监测导航卫星获得的原始定位数据 送至主控站,主控站计算出各卫星的定位修正信息,地球静止轨道卫星最后将注入 站发来的信息播发给广大用户。