首页
壁纸
留言板
友链
更多
统计归档
Search
1
TensorBoard:训练日志及网络结构可视化工具
12,588 阅读
2
主板开机跳线接线图【F_PANEL接线图】
7,050 阅读
3
Linux使用V2Ray 原生客户端
6,160 阅读
4
移动光猫获取超级密码&开启公网ipv6
4,717 阅读
5
NVIDIA 显卡限制功率
3,134 阅读
好物分享
实用教程
linux使用
wincmd
学习笔记
mysql
java学习
nginx
综合面试题
大数据
网络知识
linux
放码过来
python
javascript
java
opencv
蓝桥杯
leetcode
深度学习
开源模型
相关知识
数据集和工具
模型轻量化
语音识别
计算机视觉
杂七杂八
硬件科普
主机安全
嵌入式设备
其它
bug处理
登录
/
注册
Search
标签搜索
好物分享
学习笔记
linux
MySQL
nvidia
typero
内网穿透
webdav
vps
java
cudann
gcc
cuda
树莓派
CNN
图像去雾
ssh安全
nps
暗通道先验
阿里云
jupiter
累计撰写
354
篇文章
累计收到
71
条评论
首页
栏目
好物分享
实用教程
linux使用
wincmd
学习笔记
mysql
java学习
nginx
综合面试题
大数据
网络知识
linux
放码过来
python
javascript
java
opencv
蓝桥杯
leetcode
深度学习
开源模型
相关知识
数据集和工具
模型轻量化
语音识别
计算机视觉
杂七杂八
硬件科普
主机安全
嵌入式设备
其它
bug处理
页面
壁纸
留言板
友链
统计归档
搜索到
354
篇与
的结果
2022-09-14
操作系统高频面试题梳理
0.题目汇总线程和进程的区别?进程之间的通信方式说一说进程的状态说说僵尸进程和孤儿进程。死锁的必要条件周转时间和带权周转时间的计算页面置换算法1.线程和进程的区别?1、根本区别: 进程是操作系统资源分配和独立运行的最小单位;线程是任务调度和系统执行的最小单位。2、地址空间区别: 每个进程都有独立的地址空间,一个进程崩溃不影响其它进程;一个进程中的多个线程共享该 进程的地址空间,一个线程的非法操作会使整个进程崩溃。3、上下文切换开销区别: 每个进程有独立的代码和数据空间,进程之间上下文切换开销较大;线程组共享代码和数据空间,线程之间切换的开销较小。2.进程之间的通信方式每个进程的用户地址空间都是独立的,一般而言是不能互相访问的,但内核空间是每个进程都共享的,所以进程之间要通信必须通过内核。管道(内核中的缓冲区)管道本质上就是内核中的一个缓冲区,程序通过对缓存进行读写完成通信匿名管道:在内核中申请一块固定大小的缓冲区,程序拥有写入和读取的权利。// 创建匿名管道,并返回了两个描述符,一个是管道的读取端描述符 fd[0],另一个是管道的写入端描述符 fd[1] int fd[2]; if(pipe(fd)==-1) ERR_EXIT("pipe error");看到这,你可能会有疑问了,这两个描述符都是在一个进程里面,并没有起到进程间通信的作用,怎么样才能使得管道是跨过两个进程的呢?可以使用 fork 创建子进程,创建的子进程会复制父进程的文件描述符,这样就做到了两个进程各有两个「 fd[0] 与 fd[1]」,两个进程就可以通过各自的 fd 写入和读取同一个管道文件实现跨进程通信了。可以使用 fork 创建的两个子进程之间也可以使用匿名管道实现通信。命名管道: 在内核中申请一块固定大小的缓冲区,程序拥有写入和读取的权利,没有血缘关系的进程也可以进程间通信。mkfifo("tp",0644); int infd; infd = open("abc",o_RDONLY); if (infd ==-1)ERR_EXIT("open"); int outfd; outfd = open ("tp",O_WRONLY);优点实现简单,自带同步互斥机制缺点每个消息的最大长度是有上限的(MSGMAX)效率低下,不适合进程间频繁的交换数据半双工通信,同一时刻只有一个进程可以进行读写。(可以用两个管道实现双向通信)消息队列(内核中的队列)在内核中创建一队列,不同的进程可以通过句柄去访问这个队列,队列中每个元素是一个数据报。优点消息队列可实现双向通信。消息队列允许一个或多个进程写入或者读取消息。缺点每个消息的最大长度是有上限的(MSGMAX)消息队列的总数也有⼀个上限(MSGMNI)存在用户态和内核态之间的数据拷贝问题。进程往消息队列写入数据时,会发送用户态拷贝数据到内核态的过程,同理读取数据时会发生从内核态到用户态拷贝数据的过程。共享内存将同一块物理内存一块映射到不同的进程的虚拟地址空间中,实现不同进程间对同一资源的共享。这样一个进程写入的东西,另一个进程马上就能够看到,不需要进行拷贝。优点速度快:不需要陷入内核态或者系统调用,大大提高了通信的速度,享有最快的进程间通信方式之名缺点多进程竞争同个共享资源会造成数据的错乱:如果有多个进程同时往共享内存写入数据,有可能先写的进程的内容会被其他进程覆盖。信号量(内核中的信号量集合)在内核中创建一个信号量集合(本质是个数组),数组的元素(信号量)都是1,使用P操作进行-1,使用V操作+1,主要用于实现进程间的互斥与同步,而不是用于缓存进程间通信的数据。P(sv):如果sv的值⼤大于零,就给它减1;如果它的值为零,就挂起该进程的执⾏ 。V(sv):如果有其他进程因等待sv而被挂起,就让它恢复运⾏,如果没有进程因等待sv⽽挂起,就给它加1。信号上面说的进程间通信,都是常规状态下的工作模式。对于异常情况下的工作模式,就需要用「信号」的方式来通知进程。信号是进程间通信机制中唯一的异步通信机制。在Linux中,为了响应各种事件,提供了几十种信号,可以通过kill -l命令查看。$ kill -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1 64) SIGRTMAX运行在 shell 终端的进程,我们可以通过键盘输入某些组合键的时候,给进程发送信号。例如Ctrl+C 产生 SIGINT 信号,表示终止该进程;Ctrl+Z 产生 SIGTSTP 信号,表示停止该进程,但还未结束;如果进程在后台运行,可以通过 kill 命令的方式给进程发送信号,但前提需要知道运行中的进程 PID 号,例如:kill -9 1050 ,表示给 PID 为 1050 的进程发送 SIGKILL 信号,用来立即结束该进程;Socket前面提到的管道、消息队列、共享内存、信号量和信号都是在同一台主机上进行进程间通信,那要想跨网络与不同主机上的进程之间通信,就需要 Socket 通信了。实际上,Socket 通信不仅可以跨网络与不同主机的进程间通信,还可以在同主机上进程间通信。针对 TCP 协议通信的 socket 编程模型针对 UDP 协议通信的 socket 编程模型3.说一说进程的状态创建状态:进程在创建时需要申请一个空白PCB,向其中填写控制和管理进程的信息,完成资源分配。如果创建工作无法完成,比如资源无法满足,就无法被调度运行,把此时进程所处状态称为创建状态就绪状态:进程已经准备好,已分配到所需资源,只要分配到CPU就能够立即运行执行状态:进程处于就绪状态被调度后,进程进入执行状态阻塞状态:正在执行的进程由于某些事件(I/O请求,申请缓存区失败)而暂时无法运行,进程受到阻塞。在满足请求时进入就绪状态等待系统调用终止状态:进程结束,或出现错误,或被系统终止,进入终止状态。无法再执行4.说说僵尸进程和孤儿进程。我们知道在unix/linux中,正常情况下,子进程是通过父进程创建的,子进程在创建新的进程。子进程的结束和父进程的运行是一个异步过程,即父进程永远无法预测子进程 到底什么时候结束。 当一个 进程完成它的工作终止之后,它的父进程需要调用wait()或者waitpid()系统调用取得子进程的终止状态。孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。僵尸进程:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵尸进程。5.死锁的必要条件互斥条件:一个资源每次只能被一个进程使用; 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放;不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺;循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系;6.周转时间和带权周转时间的计算$$ 周转时间=作业完成时刻-作业到达时刻\\ 带权周转时间=\frac{周转时间}{服务时间}\\ 平均周转时间=\frac{作业周转总时间}{作业个数}\\ 平均带权周转时间=\frac{带权周转总时间}{作业个数}\\ $$7.页面置换算法在进程运行的过程当中,进程所要访问的页面不在内存中,我们就需要把这个不存在的页面调入内存,但内存已经没有空闲空间了,这时候就要求系统从内存中调出一个页面,将其移入磁盘的对换区中。将哪个页面调出来,就要通过算法来确定。我们把选择换出页面的算法就叫做页面置换算法。先进先出置换算法FIFO思想:先进先出算法总是淘汰最先进入内存的页面。出发点是近期调入的页面被再次访问的概率要大于早期调入页面的概率。例题:考虑下述页面走向:1,2,3,4,2,1,5,6,2,1,2,3,7,6,3,2,1,2,3,6。当内存块数量分别为3时,试问先进先出置换算法(FIFO)的缺页次数是多少?最近最少使用页面置换算法LRU思想:每次选择内存中离当前时刻最久未使用过的页面淘汰,依据的原理是局部性原理例题:考虑下述页面走向:1,2,3,4,2,1,5,6,2,1,2,3,7,6,3,2,1,2,3,6。当内存块数量分别为3时,试问最近最少使用页面置换算法(LRU)的缺页次数是多少?最佳置换算法OPT思想:选择的被淘汰页面是以后用不使用的,或者是在未来最长一段时间内不再被访问的页面。例题:考虑下述页面走向:1,2,3,4,2,1,5,6,2,1,2,3,7,6,3,2,1,2,3,6。当内存块数量分别为3时,试问最佳置换法(OPT)的缺页次数是多少?Clock置换算法略参考资料面试题:进程、线程及协程的区别六种进程间通信方式进程间的通信方式(六种)
2022年09月14日
335 阅读
0 评论
0 点赞
2022-09-14
MySQL高频面试题梳理
0.题目汇总mysql的数据类型有哪些数据库引擎有哪些InnoDB与MyISAM差别MySQL删除数据的方式都有哪些?delete/drop/truncate区别、谁的速度更快以及原因视图的作用是什么?有哪些好处?什么叫内连接、外连接、左连接、右连接?并发事务带来哪些问题?事务隔离级别有哪些?MySQL的默认隔离级别是?创建索引的三种方式以及删除索引mysql的权限表有哪些将一张表的部分数据更新到另一张表,该如何操作呢?说一说你对数据库事务的了解数据库范式数据库关系运算符:选择、投影、连接、除、笛卡尔积数据库语句的执行顺序1.mysql的数据类型有哪些主要包括以下五大类:整数类型BIT、BOOLTINY INT、SMALL INT、MEDIUM INT、 INT、 BIG INT浮点数类型FLOAT、DOUBLE、DECIMAL字符串类型CHAR、VARCHARTINY TEXT、TEXT、MEDIUM TEXT、LONGTEXTTINY BLOB、BLOB、MEDIUM BLOB、LONG BLOB日期类型Date、DateTime、TimeStamp、Time、Year其他数据类型BINARY、VARBINARY、ENUM、SET、Geometry、Point、MultiPoint、LineString、MultiLineString、Polygon、GeometryCollection2.数据库引擎有哪些InnoDB引擎MySQL 5.5或更高版本的默认存储引擎设计遵循ACID模型,支持事务,支持提交、回滚和紧急恢复功能来保护数据。支持行级锁定,可以提升多用户并发时的读写性能支持自动增长列AUTO_INCREMENT支持外键,保持数据的一致性和完整性拥有自己独立的缓冲池,常用的数据和索引都在缓存中$\color{red}{与传统的ISAM与MyISAM相比,InnoDB的最大特色就是 支持了ACID兼容的事务(Transaction)功能 }$InnoDB 物理文件结构为:.frm 文件:与表相关的元数据信息都存放在frm文件,包括表结构的定义信息等;.ibd 文件或 .ibdata 文件: 这两种文件都是存放 InnoDB 数据的文件,之所以有两种文件形式存放 InnoDB 的数据,是因为 InnoDB 的数据存储方式能够通过配置来决定是使用共享表空间存放存储数据,还是用独享表空间存放存储数据。独享表空间存储方式使用.ibd文件,并且每个表一个.ibd文件;共享表空间存储方式使用.ibdata文件,所有表共同使用一个.ibdata文件(或多个,可自己配置)。InnoDB存储引擎的优势在于提供了良好的事务管理、崩溃修复能力和并发控制。缺点是其读写效率稍差,占用的数据空间相对比较大。ISAM引擎(Indexed Sequential Access Method,索引顺序存取方法)索引顺序存取方法(ISAM, Indexed Sequential Access Method)最初是IBM公司发展起来的一个文件系统,可以连续地(按照他们进入的顺序)或者任意地(根据索引)记录任何访问。ISAM是一个定义明确且历经时间考验的数据表格管理方法,它在设计之时就考虑到数据库被查询的次数要远大于更新的次数。因此,ISAM执行读取操作的速度很快,而且不占用大量的内存和存储资源。ISAM的两个主要不足之处在于,它不支持事务处理,也不能够容错:如果你的硬盘崩溃了,那么数据文件就无法恢复了。如果你正在把ISAM用在关键任务应用程序里,那就必须经常备份你所有的实时数据,通过其复制特性,MYSQL能够支持这样的备份应用程序。MYISAM引擎MYISAM是MYSQL的ISAM扩展格式和缺省的数据库引擎(Mysql5.1前)。除了提供ISAM里所没有的索引和字段管理的大量功能,MYISAM还使用一种表格锁定的机制,来优化多个并发的读写操作。其代价是你需要经常运行OPTIMIZE TABLE命令,来恢复被更新机制所浪费的空间。MYISAM还有一些有用的扩展,例如用来修复数据库文件的MYISAMCHK工具和用来恢复浪费空间的MYISAMPACK工具。MYISAM强调了快速读取操作,这可能就是为什么MYSQL受到了WEB开发如此青睐的主要原因:在WEB开发中你所进行的大量数据操作都是读取操作。所以,大多数虚拟主机提供商和INTERNET平台提供商只允许使用MYISAM格式。MYISAM物理文件结构:每个MyISAM在磁盘上存储成三个文件,每一个文件的名字均以表的名字开始,扩展名指出文件类型。.frm 文件 存储 表定义;.MYD (MYData)文件 存储 表的数据;.MYI (MYIndex)文件 存储 表的索引。MEMORY存储引擎MEMORY存储引擎将表中的数据存储到内存中,为查询和引用其他表数据提供快速访问。所有的数据都在内存中,数据的处理速度快,但是安全性不高。如果需要很快的读写速度,对数据的安全性要求较低,可以选择该存储引擎。它对表的大小有要求,不能建立太大的表。所以,这类数据库只使用在相对较小的数据库表。如果该数据库需要一个用于查询的临时表,可以选择该存储引擎。HEAP引擎HEAP允许只驻留在内存里的临时表格。驻留在内存里让HEAP要比ISAM和MYISAM都快,但是它所管理的数据是不稳定的,而且如果在关机之前没有进行保存,那么所有的数据都会丢失。在数据行被删除的时候,HEAP也不会浪费大量的空间。HEAP表格在你需要使用SELECT表达式来选择和操控数据的时候非常有用。要记住,在用完表格之后就删除表格。ARCHIVE引擎适合对于不经常访问又删除不了的数据做归档储存,插入效率很高,而且占用空间小,该存储引擎只支持插入和查询操作,不支持删除和修改。3.InnoDB与MyISAM差别对比项MyISAMInnoDB主外键不支持支持事务不支持支持行表锁表锁,即使操作一条纪律也会锁住整个表,不适合高并发操作行锁,操作时只锁某一行,不对其它行有影响,适合高并发的操作表空间小大缓存只缓存索引,不缓存真实数据不仅缓存索引还要缓存真实数据,对内存要求较高,而且内存大小对性能有决定性的影响关注点性能事务是否保存表的具体行数是否InnoDB 支持事务,MyISAM 不支持事务。 这是 MySQL 将默认存储引擎从 MyISAM 变成 InnoDB 的重要原因之一;InnoDB 支持外键,而 MyISAM 不支持。 对一个包含外键的 InnoDB 表转为 MYISAM 会失败;InnoDB 不保存表的具体行数,执行select count(*) from table 时需要全表扫描。而 MyISAM 用一个变量保存了整个表的行数,执行上述语句时只需要读出该变量即可,速度很快;InnoDB 最小的锁粒度是行锁,MyISAM 最小的锁粒度是表锁。MyISAM一个更新语句会锁住整张表,导致其他查询和更新都会被阻塞,因此并发访问受限。这也是 MySQL 将默认存储引擎从 MyISAM 变成 InnoDB 的重要原因之一;InnoDB 是聚簇索引,MyISAM 是非聚簇索引。4.MySQL删除数据的方式都有哪些?delete/drop/truncate区别、谁的速度更快以及原因常用的三种删除方式:通过 delete、truncate、drop 关键字进行删除;这三种都可以用来删除数据,但场景不同可以这么理解,一本书,delete是把目录撕了,truncate是把书的内容撕下来烧了,drop是把书烧了执行速度drop > truncate >> DELETE区别详解delete1、DELETE属于数据库DML操作语言,只删除数据不删除表的结构,会走事务,执行时会触发trigger;2、在 InnoDB 中,DELETE其实并不会真的把数据删除,mysql 实际上只是给删除的数据打了个标记为已删除,因此 delete 删除表中的数据时,表文件在磁盘上所占空间不会变小,存储空间不会被释放,只是把删除的数据行设置为不可见。虽然未释放磁盘空间,但是下次插入数据的时候,仍然可以重用这部分空间(重用 → 覆盖)。3、DELETE执行时,会先将所删除数据缓存到rollback segement中,事务commit之后生效;4、delete from table_name删除表的全部数据,对于MyISAM 会立刻释放磁盘空间,InnoDB 不会释放磁盘空间;5、对于delete from table_name where xxx 带条件的删除, 不管是InnoDB还是MyISAM都不会释放磁盘空间;6、delete操作以后使用optimize table table_name会立刻释放磁盘空间。不管是InnoDB还是MyISAM 。所以要想达到释放磁盘空间的目的,delete以后执行optimize table 操作。7、delete 操作是一行一行执行删除的,并且同时将该行的的删除操作日志记录在redo和undo表空间中以便进行回滚(rollback)和重做操作,生成的大量日志也会占用磁盘空间。truncate1、truncate:属于数据库DDL定义语言,不走事务,原数据不放到 rollback segment 中,操作不触发 trigger。执行后立即生效,无法找回 执行后立即生效,无法找回 执行后立即生效,无法找回2、truncate table table_name立刻释放磁盘空间 ,不管是 InnoDB和MyISAM。truncate table其实有点类似于drop table 然后creat,只不过这个create table 的过程做了优化,比如表结构文件之前已经有了等等。所以速度上应该是接近drop table的速度;3、truncate能够快速清空一个表。并且重置auto_increment的值。小心使用 truncate,尤其没有备份的时候,如果误删除线上的表,记得及时联系中国民航,订票电话:400-806-9553Drop1、drop:属于数据库DDL定义语言,同Truncate;2、drop table table_name 立刻释放磁盘空间 ,不管是 InnoDB 和 MyISAM;drop 语句将删除表的结构被依赖的约束(constrain)、触发器(trigger)、索引(index); 依赖于该表的存储过程/函数将保留,但是变为 invalid 状态。小心使用 drop ,要删表跑路的兄弟,请在订票成功后在执行操作!订票电话:400-806-95535.视图的作用是什么?有哪些好处?视图(子查询):是从一个或多个表导出的虚拟的表,其内容由查询定义。具有普通表的结构,但是不实现数据存储。对视图的修改:单表视图一般用于查询和修改,会改变基本表的数据,多表视图一般用于查询,不会改变基本表的数据。作用:①简化了操作,把经常使用的数据定义为视图。我们在使用查询时,在很多时候我们要使用聚合函数,同时还要 显示其它字段的信息,可能还会需要关联到其它表,这时写的语句可能会很长,如果这个动作频繁发生的话,我们可以创建视图,这以后,我们只需要select * from view就可以啦,这样很方便。②安全性,用户只能查询和修改能看到的数据。因为视图是虚拟的,物理上是不存在的,只是存储了数据的集合,我们可以将基表中重要的字段信息,可以不通过视图给用户,视图是动态的数据的集合,数据是随着基表的更新而更新。同时,用户对视图不可以随意的更改和删除,可以保证数据的安全性。③逻辑上的独立性,屏蔽了真实表的结构带来的影响。视图可以使应用程序和数据库表在一定程度上独立。如果没有视图,应用一定是建立在表上的。有了视图之后,程序可以建立在视图之上,从而程序与数据库表被视图分割开来。缺点:①性能差数据库必须把视图查询转化成对基本表的查询,如果这个视图是由一个复杂的多表查询所定义,那么,即使是视图的一个简单查询,数据库也要把它变成一个复杂的结合体,需要花费一定的时间。②修改限制当用户试图修改视图的某些信息时,数据库必须把它转化为对基本表的某些信息的修改,对于简单的视图来说,这是很方便的,但是,对于比较复杂的试图,可能是不可修改的。6.什么叫内连接、外连接、左连接、右连接?7.并发事务带来哪些问题?脏读(Dirty read): 当一个事务正在访问数据并且对数据进行了修改,而这种修改还没有提交到数据库中,这时另外一个事务也访问了这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,那么另外一个事务读到的这个数据是“脏数据”,依据“脏数据”所做的操作可能是不正确的。丢失修改(Lost to modify): 指在一个事务读取一个数据时,另外一个事务也访问了该数据,那么在第一个事务中修改了这个数据后,第二个事务也修改了这个数据。这样第一个事务内的修改结果就被丢失,因此称为丢失修改。 例如:事务1读取某表中的数据A=20,事务2也读取A=20,事务1修改A=A-1,事务2也修改A=A-1,最终结果A=19,事务1的修改被丢失。不可重复读(Unrepeatableread): 指在一个事务内多次读同一数据。在这个事务还没有结束时,另一个事务也访问该数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改导致第一个事务两次读取的数据可能不太一样。这就发生了在一个事务内两次读到的数据是不一样的情况,因此称为不可重复读。幻读(Phantom read): 幻读与不可重复读类似。它发生在一个事务(T1)读取了几行数据,接着另一个并发事务(T2)插入了一些数据时。在随后的查询中,第一个事务(T1)就会发现多了一些原本不存在的记录,就好像发生了幻觉一样,所以称为幻读。8.事务隔离级别有哪些?MySQL的默认隔离级别是?read-uncommitted(读取未提交): 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读。read-committed(读取已提交): 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。repeatable-read(可重复读): 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。serializable(可串行化): 最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。隔离级别脏读不可重复读幻读幻读READ UNCOMMITTEDYYYREAD COMMITTEDNYYREPEATABLE READNNYSERIALIZABLENNNMySQL InnoDB 存储引擎的默认支持的隔离级别是 REPEATABLE-READ(可重读)。我们可以通过SELECT @@tx_isolation;命令来查看。这里需要注意的是:与 SQL 标准不同的地方在于 InnoDB 存储引擎在 repeatable-read(可重读)事务隔离级别下使用Next-Key Lock算法实现了行锁,并且不允许读取已提交的数据,所以解决了不可重复读的问题。另外,该算法(Next-Key Lock)包含了间隙锁,会锁定一个范围,因此也解决了幻读的问题。所以说InnoDB 存储引擎的默认支持的隔离级别是 repeatable-read(可重读) 已经可以完全保证事务的隔离性要求,即达到了 SQL标准的 serializable(可串行化) 隔离级别。9.创建索引的三种方式以及删除索引创建索引在执行CREATE TABLE时创建索引使用CREATE TABLE创建表时,除了可以定义列的数据类型外,还可以定义主键约束、外键约束或者唯一性约束,而不论创建哪种约束,在定义约束的同时相当于在指定列上创建了一个索引。-- 创建普通索引 create table book( book_id int, book_name varchar(50), authors varchar(50), info varchar(50), comment varchar(50), year_publication year, index idx_bname(book_name) -- 声明索引,字段为book_name ); -- 创建全文索引,全文索引在MySQL5.5及之前 MyISAM支持,InnoDB不支持 create table book1( book_id int, book_name varchar(50), authors varchar(50), info varchar(50), comment varchar(50), year_publication year, fulltext index fk_idx_cmt(comment(20)) -- 声明索引,字段为comment,长度取20,避免索引长度过长 );使用ALTER TABLE 命令去增加索引-- 创建普通索引 alter table book2 add index idx_cmt(comment); -- 创建唯一索引 alter table book2 add unique uk_idx_bname(book_name); -- 创建联合索引 alter table book2 add index mul_bid_bname_info(book_id,book_name,info);CREATE INDEX 命令创建(只能增加普通索引和UNIQUE索引)create index idx_cmt on book3(comment);-- 创建普通索引 create unique index uk_idx_bname on book3(book_name);-- 创建唯一索引 create index mul_bid_bname_info on book3(book_id,book_name,info);-- 创建联合索引删除索引使用 ALTER TABLE 删除索引--语法格式: ALTER TABLE table_name DROP INDEX index_name; --使用实例: alter table book3 drop index idx_cmt; alter table book3 drop index mul_bid_bname_info; --注意:添加 auto_increment 自增 约束字段的唯一索引不能被删除。使用 DROP INDEX 删除索引--语法格式: DROP INDEX index_name on table_name; --使用实例: drop index idx_cmt on book2; drop index mul_bid_bname_info on book2;10.mysql的权限表有哪些user表,用来记录允许连接到服务器的账号信息,该表里启用的所有权限都是全局级的,适用于所有数据库;db表,存储了用户对某个数据库的操作权限;tables_priv表,用来对单个表进行权限设置;columns_priv表,用来对单个数据列进行权限设置;procs_priv表,用于对存储过程和存储函数进行权限设置。11. 将一张表的部分数据更新到另一张表,该如何操作呢?可以采用关联更新的方式,将一张表的部分数据,更新到另一张表内。参考如下代码:update b set b.col=a.col from a,b where a.id=b.id; update b set b.col=a.col from b inner join a on a.id=b.id; update b set b.col=a.col from b left Join a on b.id = a.id;12.说一说你对数据库事务的了解事务可由一条非常简单的SQL语句组成,也可以由一组复杂的SQL语句组成。在事务中的操作,要么都执行修改,要么都不执行,这就是事务的目的,也是事务模型区别于文件系统的重要特征之一。事务需遵循ACID四个特性:Atomic(原子性):指 整个数据库事务是不可分割的工作单位。只有使数据库中所有的操作执行成功,才算整个事务成功;事务中任何一个SQL语句执行失败,那么已经执行成功的SQL语句也必须撤销,数据库状态应该退回到执行事务前的状态。Consistency(一致性):指 数据库事务不能破坏关系数据的完整性以及业务逻辑上的一致性。例如对银行转帐事务,不管事务成功还是失败,应该保证事务结束后ACCOUNTS表中Tom和Jack的存款总额为2000元。Isolation(隔离性):指的是在并发环境中,当不同的事务同时操纵相同的数据时,每个事务都有各自的完整数据空间。Durability(持久性):指的是只要事务成功结束,它对数据库所做的更新就必须永久保存下来。即使发生系统崩溃,重新启动数据库系统后,数据库还能恢复到事务成功结束时的状态。13.数据库范式1NF每个关系r的属性值为不可分的原子值2NF满足1NF,非主属性完全函数依赖于候选键(左部不可约)3NF满足2NF,消除非主属性对候选键的传递依赖BCNF满足3NF,消除每一属性对候选键的传递依赖14.数据库关系运算符:选择、投影、连接、除、笛卡尔积选择定义:在关系中选择在指定属性上有确定值的关系的子集。表示为:$$ \sigma_F{R} = \{t|t \in R \and F(t)="真"\} $$例:查询信息系(IS系)全体学生$$ σ_{Sdept='IS'}(Student) $$查询年龄小于20岁的学生$$ σ_{Sage<20}(Student) $$投影投影是选取关系中列的子集,投影的结果不是原来的关系,是R中的几列属性。表示为:$$ \pi_{A}(R)=\{t[A]|t \in R\} $$例:查询学生关系Student中都有哪些系,即查询关系Student上所在系属性上的投影$$ π_{Sdept}(Student) $$连接从两个关系的笛卡尔积中选属性间满足一定条件的元组。除设关系R除以关系S的结果为关系T,则T包含所有在R但不在S中的属性及其值,且T的元组与S的元组的所有组合都在R中例题:已知关系R和S如下,求$R ÷ S$的结果关系RABC258436392136434192关系SBCD364925第一步 :因为R÷S所得到的属性值是包含于R,但是S不包含的属性,R和S共同属性为B和C的组合,所以R÷S得到的属性列有(A),关系S在B、C上的投影为 { (3,6),(9,2)}第二步 :R在A的取值域为{1,2,3,4}第三步 : 求象集1对应的象集为 {(3,6),(9,2)}2对应的象集为 {(5,8)}3对应的象集为 {(9,2)}4对应的象集为 {(3,6),(3,4)}第四步:从第三步中可以发现,只有1 的值对应象集包含关系S的投影集,所以R÷S={1}15.数据库语句的执行顺序1、from2、where3、group by4、having5、select6、order by7、limit参考资料Github上365道Java高频面试复习题,助你拿爆大厂offer数据库引擎有哪些?视图的作用是什么?有哪些好处?(面试题)并发事务带来哪些问题?数据库基础---选择,投影,连接,除法运算
2022年09月14日
387 阅读
0 评论
0 点赞
2022-09-07
JavaSE高频面试题梳理-2.多线程与并发
0.题目汇总Java中实现多线程有几种方法如何停止一个正在运行的线程notify()和notifyAll()有什么区别?sleep()和wait()有什么区别volatile是什么?可以保证有序性吗?Thread 类中的start()和run()方法有什么区别?为什么wait, notify 和notifyAll这些方法不在thread类里面?为什么wait, notify方法要在同步块中调用?Java中interrupted和isInterruptedd方法的区别Java中synchronized和ReentrantLock有什么不同?有三个线程T1, T2, T3,如何保证顺序执行?SynchronizedMap 和 ConcurrentHashMap 有什么区别?Thread类中的yield方法有什么作用?Java线程池中submit()和execute()方法有什么区别?volatile关键字的作用?常用的线程池有哪些?简述一下你对线程池的理解Runnable接口和Callable接口的区别1.Java中实现多线程有几种方法继承 Thread 类实现 Runnable 接口实现 Callable 接口:Runnable接口是没有返回值的,Callable有返回值,可以抛出异常;Thread类并不接受Callable对象。可以使用FutureTask类实现Runnable接口和Future接口;线程池线程池的概念:线程池就是首先创建一些线程,它们的集合称为线程池。使用线程池可以很好地提高性能,线程池在系统启动时即创建大量空闲的线程,程序将一个任务传给线程池,线程池就会启动一条线程来执行这个任务,执行结束以后,该线程并不会死亡,而是再次返回线程池中成为空闲状态,等待执行下一个任务。使用线程池的原因:多线程运行时间,系统不断的启动和关闭新线程,成本非常高,会过渡消耗系统资源,以及过渡切换线程的危险,从而可能导致系统资源的崩溃。这时,线程池就是最好的选择了。2.如何停止一个正在运行的线程使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。使用stop方法强行终止,但是不推荐这个方法,因为这个方法是不安全的,而且是已被废弃的方法。使用interrupt方法中断线程3.notify()和notifyAll()有什么区别?二者都是用来用来唤醒调用wait()方法进入等待锁资源队列的线程,区别在于:notify():唤醒正在等待此对象监视器的单个线程。 如果有多个线程在等待,则选择其中一个随机唤醒(由调度器决定),唤醒的线程享有公平竞争资源的权利notifyAll():唤醒正在等待此对象监视器的所有线程,唤醒的所有线程公平竞争资源4.sleep()和wait()有什么区别sleep()和wait()都是线程暂停执行的方法。1、这两个方法来自不同的类分别是Thread和Object,sleep方法属于Thread类中的静态方法,wait属于Object的成员方法。2、sleep()是线程类(Thread)的方法,不涉及线程通信,调用时会暂停此线程指定的时间,但监控依然保持,不会释放对象锁,到时间自动恢复;wait()是Object的方法,用于线程间的通信,调用时会放弃对象锁,进入等待队列,待调用notify()/notifyAll()唤醒指定的线程或者所有线程,才进入对象锁定池准备获得对象锁进入运行状态。3、wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用(使用范围)。4、sleep()方法必须捕获异常InterruptedException,而wait()、notify()和notifyAll()不需要捕获异常。注意:sleep方法只让出了CPU,而并不会释放同步资源锁。线程执行sleep()方法后会转入阻塞状态。sleep()方法指定的时间为线程不会运行的最短时间。因此,sleep()方法不能保证该线程睡眠到期后就开始执行。5.volatile是什么?可以保证有序性吗?volatile是java并发编程的一个关键字。volatile可以保证可见性,有序性(一定程度上),但不能保证原子性因为volatile关键字能禁止指令重排,所以一定程度上保证了有序性;volatile关键字禁止指令重排的两层意思:(1)当程序执行volatile关键字进行读操作或写操作时,volatile关键字前面所有程序操作已经全部完成且结果对后面的所有操作均显示,volatile关键字后面的操作已经还没有进行。(2)进行指令优化时,不能将volatile关键字后面的语句放在volatile关键字前面执行,也不能将volatile关键字前面的语句放在volatile关键字后面执行;可见性是指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值有序性即程序执行的顺序按照代码的先后顺序执行原子性即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。volatile关键字的应用状态标记量单例模式中的double check指令重排序一般来说,处理器为了提高程序运行效率,可能会对输入代码进行优化,它不保证程序中各个语句的执行先后顺序同代码中的顺序一致,但是它会保证程序最终执行结果和代码顺序执行的结果是一致的。比如上面的代码中,语句1和语句2谁先执行对最终的程序结果并没有影响,那么就有可能在执行过程中,语句2先执行而语句1后执行。但是有依赖关系的语句不会进行重排序,如下面求圆面积的代码double pi = 4.14 //A double r = 1.0 //B double area = pi * r * r //c 程序的执行顺序只有下面这2个形式A->B->C和B->A->C,因为A和C之间存在依赖关系,同时B和C之间也存在依赖关系。因此最终执行的指令序列中C不能被重排序到A和B前面。6.Thread 类中的start()和run()方法有什么区别?start():使用start可以启动线程,创建一个新的线程,真正实现了多线程运行,在内部调用run方法且无需等待run方法体代码执行完毕而直接继续执行下面的代码。run():run()方法只是类的一个普通方法而已,使用run不会创建新线程,而是在之前的线程中执行了我们在run里面重写的内容。7.为什么wait, notify 和notifyAll这些方法不在thread类里面?Java提供的锁是对象级的而不是线程级的,每个对象都有锁,通过线程获得。简单的说,由于wait,notify,notifyAll都是锁级别的操作,所以把他们定义在object类中因为锁属于对象。8.为什么wait, notify方法要在同步块中调用?参考:面试官:为什么wait()方法要放在同步块中?9.Java中interrupted和isInterruptedd方法的区别?interruptinterrupt 方法用于中断线程。调用该方法的线程的状态为将被置为”中断”状态。注意:线程中断仅仅是置线程的中断状态位,不会停止线程。需要用户自己去监 视线程的状态为并做处理。支持线程中断的方法(也就是线程中断后会抛出 interruptedException 的方法)就是在监视线程的中断状态,一旦线程的中断状 态被置为“中断状态”,就会抛出中断异常。interrupted查询当前线程的中断状态,并且清除原状态。如果一个线程被中断了,第一次调 用 interrupted 则返回 true,第二次和后面的就返回 false 了。isInterrupted仅仅是查询当前线程的中断状态10.Java中synchronized和ReentrantLock有什么不同?用法不同:synchronized 可以用来修饰普通方法、静态方法和代码块,而 ReentrantLock 只能用于代码块(lock()和unlock()方法配合try/finally语句块来完成)。获取锁和释放锁的机制不同:synchronized 是自动加锁和释放锁的,而 ReentrantLock 需要手动加锁和释放锁。锁类型不同:synchronized 是非公平锁,而 ReentrantLock 默认为非公平锁,也可以手动指定为公平锁。响应中断不同:ReentrantLock 可以响应中断(catch InterruptedException),解决死锁的问题,而 synchronized 不能响应中断。底层实现不同:synchronized 是 JVM 层面通过监视器实现的,而 ReentrantLock 是基于 AQS 实现的。公平锁是指多个线程在等待同一个锁时,必须按照申请的时间顺序来依次获得锁;而非公平锁则不能保证这一点。非公平锁在锁被释放时,任何一个等待锁的线程都有机会获得锁。11.有三个线程T1, T2, T3,如何保证顺序执行?用线程类的join()方法在一个线程中启动另一个线程,另外一个线程完成该线程继续执行。为了确保三个线程的顺序你应该先启动最后一个(T3调用T2,T2调用T1),这样T1就会先完成而T3最后完成。12.SynchronizedMap 和 ConcurrentHashMap 有什么区别?SynchronizedMap 一次锁住整张表来保证线程安全,所以每次只能有一个线程来访问Map.ConcurrentHashMap 使用分段锁来保证在多线程下的性能。ConcurrentHashMap 中则是一次锁住一个桶。ConcurrentHashMap 默认将 hash 表分为 16 个桶,诸如get、put、remove 等常用操作只锁当前需要用到的桶。这样,原来只能一个线程进入,现在却能同时有 16 个写线程执行,并发性能的提升是显而易见的。另外 ConcurrrentHashMap 使用一种不同的迭代方式。在这种迭代方式中,当 iterator 被创建后集合再发生改变就不再是抛出 ConcurrentModificationException,取而代之的是在改变 new 新的数据从而不影响原有的数据,iterator 完成后再将头指针替换为新的数据,这样 iterator 线程可以使用原来老的数据,而写线程也可以并发的完成改变。13.Thread类中的yield方法有什么作用?yield 即 "谦让",也是 Thread 类的方法。它让掉当前线程 CPU 的时间片,使正在运行中的线程重新变成就绪状态,并重新竞争 CPU 的调度权。它可能会获取到,也有可能被其他线程获取到。yield 和 sleep 的异同1)yield, sleep 都能暂停当前线程,sleep 可以指定具体休眠的时间,而 yield 则依赖 CPU 的时间片划分。2)yield, sleep 两个在暂停过程中,如已经持有锁,则都不会释放锁资源。3)yield 不能被中断,而 sleep 则可以接受中断。14.Java线程池中submit()和execute()方法有什么区别?两个方法都可以向线程池提交任务,execute()方法的返回类型是 void,它定义在Executor 接口中。而 submit()方法可以返回持有计算结果的 Future 对象,它定义在ExecutorService 接口中,它扩展了 Executor 接口,其它线程池类像ThreadPoolExecutor 和 ScheduledThreadPoolExecutor 都有这些方法。15.volatile关键字的作用?volatile关键字的作用保证可见性;防止指令重排;16.常用的线程池有哪些?17.简述一下你对线程池的理解线程池本质上是一种池化技术,而池化技术是一种资源复用的思想。它的核心设计目标,我认为有两个:减少线程的频繁创建和销毁带来的性能开销,因为线程创建会涉及到CPU上下文切换、内存分配等工作。线程池本身会有参数来控制线程创建的数量,这样就可以避免无休止的创建线程带来的资源利用率过高的问题,起到了资源保护的作用。18.Runnable接口和Callable接口的区别Runnable需要实现run()方法Callable需要实现call()方法Runnable从jdk1.1开始加入Callable从jdk1.5开始加入区别1: 两者最大的区别,实现Callable接口的任务线程能返回执行结果,而实现Runnable接口的任务线程不能返回执行结果注意点:Callable接口支持返回执行结果,此时需要调用FutureTask.get()方法实现,此方法会阻塞线程直到获取“将来”的结果,当不调用此方法时,主线程不会阻塞区别2:Callable接口实现类中run()方法允许将异常向上抛出,也可以直接在内部处理(try…catch); 而Runnable接口实现类中run()方法的异常必须在内部处理掉,不能向上抛出参考资料Github上365道Java高频面试复习题,助你拿爆大厂offerJava 实现多线程的四种方式详解Java实现多线程的三种方式Java四种常用线程池的详细介绍notify() 和 notifyAll()方法的使用和区别并发关键字:volatile如何保证可见性和有序性?面试官:为什么wait()方法要放在同步块中?Java面试突击之synchronized和ReentrantLock有什么区别?多线程 Thread.yield 方法到底有什么用?5种常用的线程池【小明】谈谈你对线程池的理解【建议收藏】【Java面试】简述一下你对线程池的理解?
2022年09月07日
327 阅读
0 评论
0 点赞
2022-09-04
JavaSE高频面试题梳理-1.基础部分
0.题目汇总Java语言有哪些特点面向对象和面向过程的区别八种基本数据类型的大小,以及他们的封装类标识符的命名规则instanceof 关键字的作用Java自动装箱与拆箱重载和重写的区别equals与==的区别Hasheode的作用String StringBuffer和StringBuilder 的区别是什么?ArrayList和LinkedList的区别HashMap和HashTable的区别Collection包结构,与Collections的区别Java创建对象有几种方式?深拷贝和浅拷贝的区别是什么?final有哪些用法?static 都有哪些用法?3*0. 1==0. 3返回值是什么a=a+b与a+=b有什么区别吗?try catch finally; try里有return, finally还执行么?Exeption与Error包结构OOM你遇到过哪些情况,SOF你遇到过哪些情况.简述线程、程序、进程的基本概念。以及他们之间关系是什么线程有哪些基本状态?Java序列化中如果有些字段不想进行序列化,怎么办?Java中IO流Java IO与NIO的区别1. Java语言有哪些特点①跨平台/可移植性:编译器会把Java代码编码成(.class)中间代码,然后在Java虚拟机(Java Virtual Machine,JVM)上解释执行,而中间代码与平台无关,Java语言可以很好地跨平台执行,具有很好的可移植性;②面向对象:一切皆对象,然后衍生出面向对象的特点。③支持多线程;2.面向对象和面向过程的区别和优缺点区别面向过程是直接将解决问题的步骤分析出来,然后用函数把步骤一步一步实现,然后再依次调用;面向对象是将构成问题的事物,分解成若干个对象并抽象出对象的功能,通过多个对象的协作完成复杂的功能。优缺点面向过程优点:性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源; 比如单片机、嵌入式开发、 Linux/Unix等一般采用面向过程开发,性能是最重要的因素。缺点:没有面向对象易维护、易复用、易扩展面向对象优点:易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统 更加灵活、更加易于维护缺点:性能比面向过程低3.八种基本数据类型的大小,以及他们的封装类数据类型大小/字节封装类byte1Byteshort2Shortint4Integerlong8Longfloat4Floatdouble8Doublechar2Characterboolean1Boolean备注:可以通过包装类.SIZE获取占用的大小4.标识符的命名规则只能由26个字母大小写,数字0-9,_或$组成(不能有空格)不能由数字开头不能使用关键字和保留字,但是能包含关键字和保留字严格区分大小写5.instanceof 关键字的作用判断左边对象是否是右边类的实例。6.Java自动装箱与拆箱自动装箱:可以把一个基本类型的数据直接赋值给对应的包装类型;自动拆箱:可以把一个包装类型的对象直接赋值给对应的基本类型;Java语言是面向对象的语言,其设计理念是“一切皆对象”。但8种基本数据类型却出现了例外,它们不具备对象的特性。正是为了解决这个问题,Java为每个基本数据类型都定义了一个对应的引用类型,这就是包装类。Java之所以提供8种基本数据类型,主要是为了照顾程序员的传统习惯。这8种基本数据类型的确带来了一定的方便性,但在某些时候也会受到一些制约。比如,所有的引用类型的变量都继承于Object类,都可以当做Object类型的变量使用,但基本数据类型却不可以。如果某个方法需要Object类型的参数,但实际传入的值却是数字的话,就需要做特殊的处理了。有了包装类,这种问题就可以得以简化。7.重载和重写的区别重载Overloading发生在本类,指的是多个方法名相同,参数列表不同(参数类型,参数个数甚至是参数顺序),与返回值无关。重写Overriding 发生在父类与子类之间,方法名,参数列表,返回类型(除过子类中方法的返回类型是父类中返回类型的子类)必须相同,访问修饰符的限制一定要大于被重写方法的访问修饰符(public>protected>default>private)。方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。8.equals与==的区别==是java中的一个二元操作符,对于基本类型,==是比较其值是不是相等,对于引用类型,==比较两个对象(地址)是否相同。equals是超类Object中的方法,如果对象不重写equals方法,那么实际该对象的equals和"=="作用是一样的,都是比较的地址值,但是大部分类都会重写父类的equals方法,用来检测两个对象的内容是否相等,例如String就重写了equals方法,用来比较两个字符串内容是否相同。equals()没有==运行速度快。9.Hasheode的作用在散列存储结构(如Hashtable,HashMap)中快速确定对象的存储地址,提高查找的便捷性;在Set结构中初步判断对象是否相等,避免频繁使用效率较低的equals方法,对于hashCode相等的再执行equals方法进行确认。注意:如果对象的equals方法被重写,那么对象的HashCode也尽量重写(因为equals相同=>hashCode必然要相同)10. String、StringBuffer和StringBuilder 的区别String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低下,而且大量浪费有限的内存空间。StringBuffer和StringBuilder都是可变字符类,任何对它指向的字符串的操作都不会产生新的对象,StringBuilder是线程不安全的,执行速度更快,StringBuilder是线程安全的,执行速度相对更慢。11.ArrayList和LinkedList的区别ArrayList是实现了基于动态数组的数据结构,LinkedList是基于链表结构二者都会造成空间浪费,ArrayList的空间浪费主要体现在List列表的结尾预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗相当的空间对于随机访问的get和set方法,ArrayList要优于LinkedList,因为LinkedList要移动指针对于新增和删除操作add和remove,LinkedList比较占优势,因为ArrayList要移动数据12.HashMap和HashTable的区别HashTable底层数组+链表实现,无论key还是value都不能为null,线程安全,实现线程安全的方式是在修改数据时锁住整个HashTable,效率低,ConcurrentHashMap做了相关优化初始size为11,扩容:newsize = olesize*2+1HashMap底层数组+链表+红黑树实现,可以存储null键和null值,线程不安全初始size为16,扩容:newsize = oldsize*2,size一定为2的n次幂13.Collection包结构,与Collections的区别区别:Collection,是一个集合接口,提供了对集合对象进行基本操作的通用接口方法Collections,是针对集合类的一个工具类,提供了一系列静态方法以实现对各种集合的搜索、排序、线程安全化等操作。Collections类不能实例化,服务于Collection框架。14.Java创建对象有几种方式new创建新对象通过反射机制采用clone机制通过序列化机制15.深拷贝和浅拷贝的区别浅拷贝只是拷贝一层,更深层次对象级别的只拷贝引用.深拷贝拷贝多层,每一级别的数据都会拷贝.16.final有哪些用法修饰变量,修饰基本数据类型后不能修改值,修饰引用数据类型后不能修改引用的指向(可以修改引用对象的属性);修饰方法,被 final 修饰的方法不可以被重写;修饰类,被 final 修饰的类不可以被继承;17.static都有哪些用法java中static的用法有:修饰成员变量:将其变为类的成员,从而实现所有对象对于该成员的共享;修饰成员方法:将其变为类方法,可以直接使用“类名.方法名”的方式调用,常用于工具类;修饰代码块:构造静态代码块一次性地对静态成员变量进行初始化。静态导包用法,将类的方法直接导入到当前类中,从而直接使用“方法名”即可调用类方法,更加方便。18.3*0. 1==0. 3返回值是什么返回值是假,因为在计算机中浮点数的表示是误差的。所以一般情况下不进行两个浮点数是否相同的比较。而是比较两个浮点数的差点绝对值,是否小于一个很小的正数。如果条件满足,就认为这两个浮点数是相同的。19.a=a+b与a+=b有什么区别主要差异在于是否能进行数据类型自动转换,+=操作符会进行隐式自动类型转换,此处 a+=b隐式的将加操作的结果类型强制转换为运算结果转换为a的类型,而a=a+b则不会自动进行类型转换。class Solution { public static void main(String[] args) { short a = 10; int b = 20; a+=b; // 隐式类型转换为a的类型 a = a+b; // 编译错误,=两边的类型必须一致 } }20.try catch finally; try里有return, finally还执行么?不管有木有出现异常, finally 块中代码都会执行;当 try 和 catch 中有 return 时, finally 仍然会执行;finally 是在 return 后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,不管 finally 中的代码怎么样,返回的值都不会改变,任然是之前保存的值),所以函数返回值是在 finally 执行前确定的;finally 中最好不要包含 return ,否则程序会提前退出,返回值不是 try 或 catch 中保存的返回值。21.Excption与Error包结构22.OOM(Out Of Memory Error)你遇到过哪些情况,SOF(Stack Ove flow Error)你遇到过哪些情况OOM:Java Heap 溢出(内存泄漏 or 申请过大堆空间)SOF:程序递归太深而发生堆栈溢出时,抛出该错误。23.简述线程、程序、进程的基本概念以及他们之间关系程序:静态的代码。进程: 进程是一个具有一定独立功能的程序关于某个数据集合上的一次运行活动,是系统资源分配和独立运行的最小单位;线程: 线程是进程的一个执行单元,是任务调度和系统执行的最小单位;24.线程有哪些基本状态25.Java序列化中如果有些字段不想进行序列化,怎么办?对于不想进行序列化的变量,使用 transient 关键字修饰。transient 只能修饰变量,不能修饰类和方法。26.Java中IO流27.Java IO和NIO的区别IONIO面向流面向缓冲阻塞IO非阻塞IO无选择器Java NIO的选择器允许一个单独的线程来监视多个输入通道,你可以注册多个通道使用一个选择器,然后使用一个单独的线程来“选择”通道:这些通道里已经有可以处理的输入,或者选择已准备写入的通道。这种选择机制,使得一个单独的线程很容易来管理多个通道。28.Java程序是如何执行的?先把Java代码编译成字节码,也就是把 .java类型的文件编译成 .class类型的文件.这个过程的大致执行流程: Java源代码 -> 词法分析器 -> 语法分析器 -> 语义分析器 -> 字节码生成器 ->最终生成字节码,其中任何一个节点执行失败就会造成编译失败;把class文件放置到Java虚拟机,这个虚拟机通常指的是Oracle官方自带的Hotspot JVM;Java虚拟机使用类加载器(Class Loader)装载class文件;类加载完成之后,会进行字节码校验,字节码校验通过JVM解释器会把字节码翻译成机器码交由操作系统执行.但不是所有代码都是解释执行的,JVM对此做了优化, 比如, 以Hotspot虚拟机来说, 它本身提供了JIT (Just In Time)也就是我们通常所说的动态编译器,它能够在运行时将热点代码编译成机器码,这个时候字节码就变成了编译执行.参考资料Github上365道Java高频面试复习题,助你拿爆大厂offer面向对象和面向过程的区别面向对象与面向过程的本质的区别重载与重写的区别try catch finally,try里有return,finally还执行么?Java反射的作用与原理Java程序是如何执行的?
2022年09月04日
312 阅读
0 评论
0 点赞
2022-09-03
python修改支付宝步数
0.背景最近在弄支付宝的蚂蚁森林的能力,自己的步数每次都只有10000多点,攒能量攒不满,想提高积攒效率,就从网上找了找解决方案。最后发现了这个python+小米运动的实现方案1.操作步骤1.1 注册小米运动用手机号注册小米运动APP,登录,绑定微信和支付宝;1.2 修改并运行如下代码修改第144行的手机号码和第146行的密码,保存;# -*- coding: utf8 -*- # python >=3.8 import requests,time,re,json,random import os TG_BOT_TOKEN = "" # telegram bot token 自行申请 TG_USER_ID = "" # telegram 用户ID def telegram_bot(title, content): print("\n") tg_bot_token = TG_BOT_TOKEN tg_user_id = TG_USER_ID if "TG_BOT_TOKEN" in os.environ and "TG_USER_ID" in os.environ: tg_bot_token = os.environ["TG_BOT_TOKEN"] tg_user_id = os.environ["TG_USER_ID"] if not tg_bot_token or not tg_user_id: print("Telegram推送的tg_bot_token或者tg_user_id未设置!!\n取消推送") return print("Telegram 推送开始") send_data = {"chat_id": tg_user_id, "text": title + '\n\n'+content, "disable_web_page_preview": "true"} response = requests.post( url='https://api.telegram.org/bot%s/sendMessage' % (tg_bot_token), data=send_data) print(response.text) now = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) headers = { 'User-Agent': 'Dalvik/2.1.0 (Linux; U; Android 9; MI 6 MIUI/20.6.18)' } #获取登录code def get_code(location): code_pattern = re.compile("(?<=access=).*?(?=&)") code = code_pattern.findall(location)[0] return code #登录 def login(user,password): url1 = "https://api-user.huami.com/registrations/+86" + user + "/tokens" headers = { "Content-Type":"application/x-www-form-urlencoded;charset=UTF-8", "User-Agent":"MiFit/4.6.0 (iPhone; iOS 14.0.1; Scale/2.00)" } data1 = { "client_id":"HuaMi", "password":f"{password}", "redirect_uri":"https://s3-us-west-2.amazonaws.com/hm-registration/successsignin.html", "token":"access" } r1 = requests.post(url1,data=data1,headers=headers,allow_redirects=False) location = r1.headers["Location"] try: code = get_code(location) except: return 0,0 #print("access_code获取成功!")ste #print(code) url2 = "https://account.huami.com/v2/client/login" data2 = { "app_name":"com.xiaomi.hm.health", "app_version":"4.6.0", "code":f"{code}", "country_code":"CN", "device_id":"2C8B4939-0CCD-4E94-8CBA-CB8EA6E613A1", "device_model":"phone", "grant_type":"access_token", "third_name":"huami_phone", } r2 = requests.post(url2,data=data2,headers=headers).json() login_token = r2["token_info"]["login_token"] #print("login_token获取成功!") #print(login_token) userid = r2["token_info"]["user_id"] #print("userid获取成功!") #print(userid) return login_token,userid #主函数 def main(user, passwd, step): user = str(user) password = str(passwd) step = str(step) if user == '' or password == '': print ("用户名或密码填写有误!") return if step == '': print ("已设置为随机步数(20000-29999)") step = str(random.randint(20000,29999)) login_token = 0 login_token,userid = login(user,password) if login_token == 0: print("登陆失败!") return "login fail!" t = get_time() app_token = get_app_token(login_token) today = time.strftime("%F") data_json = '%5B%7B%22data_hr%22%3A%22%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F9L%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2FVv%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F0v%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F9e%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F0n%5C%2Fa%5C%2F%5C%2F%5C%2FS%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F0b%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F1FK%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2FR%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F9PTFFpaf9L%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2FR%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F0j%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F9K%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2FOv%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2Fzf%5C%2F%5C%2F%5C%2F86%5C%2Fzr%5C%2FOv88%5C%2Fzf%5C%2FPf%5C%2F%5C%2F%5C%2F0v%5C%2FS%5C%2F8%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2FSf%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2Fz3%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F0r%5C%2FOv%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2FS%5C%2F9L%5C%2Fzb%5C%2FSf9K%5C%2F0v%5C%2FRf9H%5C%2Fzj%5C%2FSf9K%5C%2F0%5C%2F%5C%2FN%5C%2F%5C%2F%5C%2F%5C%2F0D%5C%2FSf83%5C%2Fzr%5C%2FPf9M%5C%2F0v%5C%2FOv9e%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2FS%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2Fzv%5C%2F%5C%2Fz7%5C%2FO%5C%2F83%5C%2Fzv%5C%2FN%5C%2F83%5C%2Fzr%5C%2FN%5C%2F86%5C%2Fz%5C%2F%5C%2FNv83%5C%2Fzn%5C%2FXv84%5C%2Fzr%5C%2FPP84%5C%2Fzj%5C%2FN%5C%2F9e%5C%2Fzr%5C%2FN%5C%2F89%5C%2F03%5C%2FP%5C%2F89%5C%2Fz3%5C%2FQ%5C%2F9N%5C%2F0v%5C%2FTv9C%5C%2F0H%5C%2FOf9D%5C%2Fzz%5C%2FOf88%5C%2Fz%5C%2F%5C%2FPP9A%5C%2Fzr%5C%2FN%5C%2F86%5C%2Fzz%5C%2FNv87%5C%2F0D%5C%2FOv84%5C%2F0v%5C%2FO%5C%2F84%5C%2Fzf%5C%2FMP83%5C%2FzH%5C%2FNv83%5C%2Fzf%5C%2FN%5C%2F84%5C%2Fzf%5C%2FOf82%5C%2Fzf%5C%2FOP83%5C%2Fzb%5C%2FMv81%5C%2FzX%5C%2FR%5C%2F9L%5C%2F0v%5C%2FO%5C%2F9I%5C%2F0T%5C%2FS%5C%2F9A%5C%2Fzn%5C%2FPf89%5C%2Fzn%5C%2FNf9K%5C%2F07%5C%2FN%5C%2F83%5C%2Fzn%5C%2FNv83%5C%2Fzv%5C%2FO%5C%2F9A%5C%2F0H%5C%2FOf8%5C%2F%5C%2Fzj%5C%2FPP83%5C%2Fzj%5C%2FS%5C%2F87%5C%2Fzj%5C%2FNv84%5C%2Fzf%5C%2FOf83%5C%2Fzf%5C%2FOf83%5C%2Fzb%5C%2FNv9L%5C%2Fzj%5C%2FNv82%5C%2Fzb%5C%2FN%5C%2F85%5C%2Fzf%5C%2FN%5C%2F9J%5C%2Fzf%5C%2FNv83%5C%2Fzj%5C%2FNv84%5C%2F0r%5C%2FSv83%5C%2Fzf%5C%2FMP%5C%2F%5C%2F%5C%2Fzb%5C%2FMv82%5C%2Fzb%5C%2FOf85%5C%2Fz7%5C%2FNv8%5C%2F%5C%2F0r%5C%2FS%5C%2F85%5C%2F0H%5C%2FQP9B%5C%2F0D%5C%2FNf89%5C%2Fzj%5C%2FOv83%5C%2Fzv%5C%2FNv8%5C%2F%5C%2F0f%5C%2FSv9O%5C%2F0ZeXv%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F1X%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F9B%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2FTP%5C%2F%5C%2F%5C%2F1b%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F0%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F9N%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%22%2C%22date%22%3A%222021-08-07%22%2C%22data%22%3A%5B%7B%22start%22%3A0%2C%22stop%22%3A1439%2C%22value%22%3A%22UA8AUBQAUAwAUBoAUAEAYCcAUBkAUB4AUBgAUCAAUAEAUBkAUAwAYAsAYB8AYB0AYBgAYCoAYBgAYB4AUCcAUBsAUB8AUBwAUBIAYBkAYB8AUBoAUBMAUCEAUCIAYBYAUBwAUCAAUBgAUCAAUBcAYBsAYCUAATIPYD0KECQAYDMAYB0AYAsAYCAAYDwAYCIAYB0AYBcAYCQAYB0AYBAAYCMAYAoAYCIAYCEAYCYAYBsAYBUAYAYAYCIAYCMAUB0AUCAAUBYAUCoAUBEAUC8AUB0AUBYAUDMAUDoAUBkAUC0AUBQAUBwAUA0AUBsAUAoAUCEAUBYAUAwAUB4AUAwAUCcAUCYAUCwKYDUAAUUlEC8IYEMAYEgAYDoAYBAAUAMAUBkAWgAAWgAAWgAAWgAAWgAAUAgAWgAAUBAAUAQAUA4AUA8AUAkAUAIAUAYAUAcAUAIAWgAAUAQAUAkAUAEAUBkAUCUAWgAAUAYAUBEAWgAAUBYAWgAAUAYAWgAAWgAAWgAAWgAAUBcAUAcAWgAAUBUAUAoAUAIAWgAAUAQAUAYAUCgAWgAAUAgAWgAAWgAAUAwAWwAAXCMAUBQAWwAAUAIAWgAAWgAAWgAAWgAAWgAAWgAAWgAAWgAAWREAWQIAUAMAWSEAUDoAUDIAUB8AUCEAUC4AXB4AUA4AWgAAUBIAUA8AUBAAUCUAUCIAUAMAUAEAUAsAUAMAUCwAUBYAWgAAWgAAWgAAWgAAWgAAWgAAUAYAWgAAWgAAWgAAUAYAWwAAWgAAUAYAXAQAUAMAUBsAUBcAUCAAWwAAWgAAWgAAWgAAWgAAUBgAUB4AWgAAUAcAUAwAWQIAWQkAUAEAUAIAWgAAUAoAWgAAUAYAUB0AWgAAWgAAUAkAWgAAWSwAUBIAWgAAUC4AWSYAWgAAUAYAUAoAUAkAUAIAUAcAWgAAUAEAUBEAUBgAUBcAWRYAUA0AWSgAUB4AUDQAUBoAXA4AUA8AUBwAUA8AUA4AUA4AWgAAUAIAUCMAWgAAUCwAUBgAUAYAUAAAUAAAUAAAUAAAUAAAUAAAUAAAUAAAUAAAWwAAUAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAeSEAeQ8AcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcBcAcAAAcAAAcCYOcBUAUAAAUAAAUAAAUAAAUAUAUAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcCgAeQAAcAAAcAAAcAAAcAAAcAAAcAYAcAAAcBgAeQAAcAAAcAAAegAAegAAcAAAcAcAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcCkAeQAAcAcAcAAAcAAAcAwAcAAAcAAAcAIAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcCIAeQAAcAAAcAAAcAAAcAAAcAAAeRwAeQAAWgAAUAAAUAAAUAAAUAAAUAAAcAAAcAAAcBoAeScAeQAAegAAcBkAeQAAUAAAUAAAUAAAUAAAUAAAUAAAcAAAcAAAcAAAcAAAcAAAcAAAegAAegAAcAAAcAAAcBgAeQAAcAAAcAAAcAAAcAAAcAAAcAkAegAAegAAcAcAcAAAcAcAcAAAcAAAcAAAcAAAcA8AeQAAcAAAcAAAeRQAcAwAUAAAUAAAUAAAUAAAUAAAUAAAcAAAcBEAcA0AcAAAWQsAUAAAUAAAUAAAUAAAUAAAcAAAcAoAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAYAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcBYAegAAcAAAcAAAegAAcAcAcAAAcAAAcAAAcAAAcAAAeRkAegAAegAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAEAcAAAcAAAcAAAcAUAcAQAcAAAcBIAeQAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcBsAcAAAcAAAcBcAeQAAUAAAUAAAUAAAUAAAUAAAUBQAcBYAUAAAUAAAUAoAWRYAWTQAWQAAUAAAUAAAUAAAcAAAcAAAcAAAcAAAcAAAcAMAcAAAcAQAcAAAcAAAcAAAcDMAeSIAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcBQAeQwAcAAAcAAAcAAAcAMAcAAAeSoAcA8AcDMAcAYAeQoAcAwAcFQAcEMAeVIAaTYAbBcNYAsAYBIAYAIAYAIAYBUAYCwAYBMAYDYAYCkAYDcAUCoAUCcAUAUAUBAAWgAAYBoAYBcAYCgAUAMAUAYAUBYAUA4AUBgAUAgAUAgAUAsAUAsAUA4AUAMAUAYAUAQAUBIAASsSUDAAUDAAUBAAYAYAUBAAUAUAUCAAUBoAUCAAUBAAUAoAYAIAUAQAUAgAUCcAUAsAUCIAUCUAUAoAUA4AUB8AUBkAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAA%22%2C%22tz%22%3A32%2C%22did%22%3A%22DA932FFFFE8816E7%22%2C%22src%22%3A24%7D%5D%2C%22summary%22%3A%22%7B%5C%22v%5C%22%3A6%2C%5C%22slp%5C%22%3A%7B%5C%22st%5C%22%3A1628296479%2C%5C%22ed%5C%22%3A1628296479%2C%5C%22dp%5C%22%3A0%2C%5C%22lt%5C%22%3A0%2C%5C%22wk%5C%22%3A0%2C%5C%22usrSt%5C%22%3A-1440%2C%5C%22usrEd%5C%22%3A-1440%2C%5C%22wc%5C%22%3A0%2C%5C%22is%5C%22%3A0%2C%5C%22lb%5C%22%3A0%2C%5C%22to%5C%22%3A0%2C%5C%22dt%5C%22%3A0%2C%5C%22rhr%5C%22%3A0%2C%5C%22ss%5C%22%3A0%7D%2C%5C%22stp%5C%22%3A%7B%5C%22ttl%5C%22%3A18272%2C%5C%22dis%5C%22%3A10627%2C%5C%22cal%5C%22%3A510%2C%5C%22wk%5C%22%3A41%2C%5C%22rn%5C%22%3A50%2C%5C%22runDist%5C%22%3A7654%2C%5C%22runCal%5C%22%3A397%2C%5C%22stage%5C%22%3A%5B%7B%5C%22start%5C%22%3A327%2C%5C%22stop%5C%22%3A341%2C%5C%22mode%5C%22%3A1%2C%5C%22dis%5C%22%3A481%2C%5C%22cal%5C%22%3A13%2C%5C%22step%5C%22%3A680%7D%2C%7B%5C%22start%5C%22%3A342%2C%5C%22stop%5C%22%3A367%2C%5C%22mode%5C%22%3A3%2C%5C%22dis%5C%22%3A2295%2C%5C%22cal%5C%22%3A95%2C%5C%22step%5C%22%3A2874%7D%2C%7B%5C%22start%5C%22%3A368%2C%5C%22stop%5C%22%3A377%2C%5C%22mode%5C%22%3A4%2C%5C%22dis%5C%22%3A1592%2C%5C%22cal%5C%22%3A88%2C%5C%22step%5C%22%3A1664%7D%2C%7B%5C%22start%5C%22%3A378%2C%5C%22stop%5C%22%3A386%2C%5C%22mode%5C%22%3A3%2C%5C%22dis%5C%22%3A1072%2C%5C%22cal%5C%22%3A51%2C%5C%22step%5C%22%3A1245%7D%2C%7B%5C%22start%5C%22%3A387%2C%5C%22stop%5C%22%3A393%2C%5C%22mode%5C%22%3A4%2C%5C%22dis%5C%22%3A1036%2C%5C%22cal%5C%22%3A57%2C%5C%22step%5C%22%3A1124%7D%2C%7B%5C%22start%5C%22%3A394%2C%5C%22stop%5C%22%3A398%2C%5C%22mode%5C%22%3A3%2C%5C%22dis%5C%22%3A488%2C%5C%22cal%5C%22%3A19%2C%5C%22step%5C%22%3A607%7D%2C%7B%5C%22start%5C%22%3A399%2C%5C%22stop%5C%22%3A414%2C%5C%22mode%5C%22%3A4%2C%5C%22dis%5C%22%3A2220%2C%5C%22cal%5C%22%3A120%2C%5C%22step%5C%22%3A2371%7D%2C%7B%5C%22start%5C%22%3A415%2C%5C%22stop%5C%22%3A427%2C%5C%22mode%5C%22%3A3%2C%5C%22dis%5C%22%3A1268%2C%5C%22cal%5C%22%3A59%2C%5C%22step%5C%22%3A1489%7D%2C%7B%5C%22start%5C%22%3A428%2C%5C%22stop%5C%22%3A433%2C%5C%22mode%5C%22%3A1%2C%5C%22dis%5C%22%3A152%2C%5C%22cal%5C%22%3A4%2C%5C%22step%5C%22%3A238%7D%2C%7B%5C%22start%5C%22%3A434%2C%5C%22stop%5C%22%3A444%2C%5C%22mode%5C%22%3A3%2C%5C%22dis%5C%22%3A2295%2C%5C%22cal%5C%22%3A95%2C%5C%22step%5C%22%3A2874%7D%2C%7B%5C%22start%5C%22%3A445%2C%5C%22stop%5C%22%3A455%2C%5C%22mode%5C%22%3A4%2C%5C%22dis%5C%22%3A1592%2C%5C%22cal%5C%22%3A88%2C%5C%22step%5C%22%3A1664%7D%2C%7B%5C%22start%5C%22%3A456%2C%5C%22stop%5C%22%3A466%2C%5C%22mode%5C%22%3A3%2C%5C%22dis%5C%22%3A1072%2C%5C%22cal%5C%22%3A51%2C%5C%22step%5C%22%3A1245%7D%2C%7B%5C%22start%5C%22%3A467%2C%5C%22stop%5C%22%3A477%2C%5C%22mode%5C%22%3A4%2C%5C%22dis%5C%22%3A1036%2C%5C%22cal%5C%22%3A57%2C%5C%22step%5C%22%3A1124%7D%2C%7B%5C%22start%5C%22%3A478%2C%5C%22stop%5C%22%3A488%2C%5C%22mode%5C%22%3A3%2C%5C%22dis%5C%22%3A488%2C%5C%22cal%5C%22%3A19%2C%5C%22step%5C%22%3A607%7D%2C%7B%5C%22start%5C%22%3A489%2C%5C%22stop%5C%22%3A499%2C%5C%22mode%5C%22%3A4%2C%5C%22dis%5C%22%3A2220%2C%5C%22cal%5C%22%3A120%2C%5C%22step%5C%22%3A2371%7D%2C%7B%5C%22start%5C%22%3A500%2C%5C%22stop%5C%22%3A511%2C%5C%22mode%5C%22%3A3%2C%5C%22dis%5C%22%3A1268%2C%5C%22cal%5C%22%3A59%2C%5C%22step%5C%22%3A1489%7D%2C%7B%5C%22start%5C%22%3A512%2C%5C%22stop%5C%22%3A522%2C%5C%22mode%5C%22%3A1%2C%5C%22dis%5C%22%3A152%2C%5C%22cal%5C%22%3A4%2C%5C%22step%5C%22%3A238%7D%5D%7D%2C%5C%22goal%5C%22%3A8000%2C%5C%22tz%5C%22%3A%5C%2228800%5C%22%7D%22%2C%22source%22%3A24%2C%22type%22%3A0%7D%5D' finddate = re.compile(r'.*?date%22%3A%22(.*?)%22%2C%22data.*?') findstep = re.compile(r'.*?ttl%5C%22%3A(.*?)%2C%5C%22dis.*?') data_json = re.sub(finddate.findall(data_json)[0], today, str(data_json)) data_json = re.sub(findstep.findall(data_json)[0], step, str(data_json)) url = f'https://api-mifit-cn.huami.com/v1/data/band_data.json?&t={t}' head = { "apptoken": app_token, "Content-Type": "application/x-www-form-urlencoded" } data = f'userid={userid}&last_sync_data_time=1597306380&device_type=0&last_deviceid=DA932FFFFE8816E7&data_json={data_json}' response = requests.post(url, data=data, headers=head).json() #print(response) result = f"{user[:4]}****{user[-4:]}: [{now}] 修改步数({step})"+ response['message'] print(result) return result #获取时间戳 def get_time(): url = 'http://api.m.taobao.com/rest/api3.do?api=mtop.common.getTimestamp' response = requests.get(url,headers=headers).json() t = response['data']['t'] return t #获取app_token def get_app_token(login_token): url = f"https://account-cn.huami.com/v1/client/app_tokens?app_name=com.xiaomi.hm.health&dn=api-user.huami.com%2Capi-mifit.huami.com%2Capp-analytics.huami.com&login_token={login_token}" response = requests.get(url,headers=headers).json() app_token = response['token_info']['app_token'] #print("app_token获取成功!") #print(app_token) return app_token if __name__ == "__main__": # 用户名(单用户的格式为 13800138000 ,多用户用#隔开,例如13800138000#13800138000#13800138000) user = "13800138000" # 登录密码(用#隔开,例如123456#123456#123456) passwd = "123456" # 要修改的步数,直接输入想要修改的步数值,留空为随机步数20000至29999之间 step = "" user_list = user.split('#') passwd_list = passwd.split('#') setp_array = step.split('-') if len(user_list) == len(passwd_list): push = '' for line in range(0,len(user_list)): if len(setp_array) == 2: step = str(random.randint(int(setp_array[0]),int(setp_array[1]))) elif str(step) == '0': step = '' push += main(user_list[line], passwd_list[line], step) + '\n' telegram_bot("小米运动", push) else: print('用户名和密码数量不对')放到python的版本大于等于3.8的环境下运行:python3 xiaomiyundong.py;1.3 设置定时任务* 19 * * * /home/admin/miniconda3/bin/python3 /software/xmyd/xmyd-5775.py参考资料Python 小米运动修改脚本-python版
2022年09月03日
548 阅读
0 评论
0 点赞
2022-09-02
将PPT的图保持高分辨率粘贴到Word
0.背景写论文在使用到了PPT画图,需要将画好的图便捷的导入到Word中,并保持矢量图的分辨率,放大缩小不模糊。一般直接使用屏幕截图会使分辨率降低,图片质量很差。直接复制粘贴也会出现同样的问题1.解决方案将PPT中画好的图组合在一起,选择组合后的图复制(Ctrl+c)在Word中,选中左上角的粘贴选项--->选择性粘贴选中图片(增强型图元文件),即可在Word中得到矢量图。参考资料将PPT里的图形高质量保存至Word【小技巧】如何将PPT的图保持高分辨率导入到Word中
2022年09月02日
1,193 阅读
0 评论
0 点赞
2022-09-01
排序算法重梳理
0.复杂度和稳定性汇总版本一名词解释:n:数据规模k:"桶"的个数In-place:占用常数内存,不占用额外内存Out-place:占用额外内存稳定性:排序后 2 个相等键值的顺序和排序之前它们的顺序相同版本二 其中:k表示计数排序中最大值和最小值之间的差值;l表示桶排序中桶的个数;d表示基数排序中最大值的位数,r表示是多少进制;希尔排序的时间复杂度很大程度上取决于增量gap sequence的选择,不同的增量会有不同的时间复杂度。文中使用的“gap=length/2”和“gap=gap/2”是一种常用的方式,也被称为希尔增量,但其并不是最优的。其实希尔排序增量的选择与证明一直都是个数学难题,而下图列出的是迄今为止大部分的gap sequence选择的方案:1.逐一代码实现1.1 冒泡排序每次循环都比较前后两个元素的大小,如果前者大于后者,则将两者进行交换。这样做会将每次循环中最大的元素替换到末尾,逐渐形成有序集合。将每次循环中的最大(小)元素逐渐由队首转移到队尾的过程形似“冒泡”过程,故因此得名。一个优化冒泡排序的方法就是 如果在一次循环的过程中没有发生交换,则可以立即退出当前循环,因为此时已经排好序了(也就是时间复杂度最好情况下是$O(n)$的由来)。import java.util.Arrays; class Solution { // 交换数组元素位置 public static void swap(int[] array,int index1,int index2){ int temp = array[index1]; array[index1] = array[index2]; array[index2] = temp; } public static void bubbleSort(int[] array){ for (int i = 0; i < array.length-1; i++) { boolean flag = false;//记录本轮是否发生冒泡 for (int j = 0; j < array.length-1-i; j++) { if(array[j]>array[j+1]){ swap(array,j,j+1); flag = true; } } if (!flag) { //本轮没有发生冒泡则表示数组已经有序,可以直接break break; } } } public static void main(String[] args) { int[] array = new int[]{1,9,4,8,2,3,0,7,5,6}; bubbleSort(array); System.out.println(Arrays.toString(array)); } }1.2 选择排序每次循环都会找出当前循环中最小(大)的元素,然后和此次循环中的队首元素进行交换。import java.util.Arrays; class Solution { // 交换数组元素位置 public static void swap(int[] array,int index1,int index2){ int temp = array[index1]; array[index1] = array[index2]; array[index2] = temp; } public static void selectSort(int[] array){ for (int i = 0; i < array.length; i++) { int minIndex = i; for (int j = i+1; j < array.length; j++) { minIndex = array[j]<array[minIndex]?j:minIndex; } swap(array,i,minIndex); } } public static void main(String[] args) { int[] array = new int[]{1,9,4,8,2,3,0,7,5,6}; selectSort(array); System.out.println(Arrays.toString(array)); } }1.3 快速排序import java.util.Arrays; class Solution { // 交换数组元素位置 public static void swap(int[] array,int index1,int index2){ int temp = array[index1]; array[index1] = array[index2]; array[index2] = temp; } /** * @brief 快速排序-partition * 大体思想:把比pivot小的换到前面 */ public static int partition(int[] array,int left,int right){ // 取最后一个元素作为中心元素 int pivot = array[right]; // 遍历数组中的所有元素,将比中心元素大的放在右边,比中心元素小的放在左边---该步骤有点类似于选择排序 int i = left; for (int j = left; j < right; j++) { if (array[j] <= pivot) { swap(array,i,j);//比pivot小的,全部换到前面去 i++; } } //此时,i指向的元素一定大于等于pivot,把privot换回到中间 swap(array,i,right); return i; } /** * @brief 快速排序-递归划分 */ public static void quickSort(int[] array){ int mid = partition(array,0, array.length-1); quickSort(array,0,mid-1); quickSort(array,mid+1,right); } public static void main(String[] args) { int[] array = new int[]{1,9,4,8,2,3,0,7,5,6}; quickSort(array); System.out.println(Arrays.toString(array)); } }1.4 插入排序插入排序的精髓在于每次都会在先前排好序的子集合中插入下一个待排序的元素,每次都会判断待排序元素的上一个元素是否大于待排序元素,如果大于,则将元素右移,然后判断再上一个元素与待排序元素...以此类推。直到小于等于比较元素时就是找到了该元素的插入位置。这里的等于条件放在哪里很重要,因为它是决定插入排序稳定与否的关键。import java.util.Arrays; class Solution { // 交换数组元素位置 public static void swap(int[] array,int index1,int index2){ int temp = array[index1]; array[index1] = array[index2]; array[index2] = temp; } public static void insertSort(int[] array){ for (int i = 1; i < array.length; i++) { int curItem = array[i];//缓存下一个待排序的元素 // 把有序集合中的所有比curItem大的元素都往后移一位 int j = i-1; while (j>=0&&array[j]>curItem){ array[j+1] = array[j--]; } // 把待排序元素插入到有序序列中 array[j+1] = curItem; } } public static void main(String[] args) { int[] array = new int[]{1,9,4,8,2,3,0,7,5,6}; insertSort(array); System.out.println(Arrays.toString(array)); } }1.5 希尔排序希尔排序可以认为是插入排序的改进版本。首先按照初始增量来将数组分成多个组,每个组内部使用插入排序。然后缩小增量来重新分组,组内再次使用插入排序...重复以上步骤,直到增量变为1的时候,这个时候整个数组就是一个分组,进行最后一次完整的插入排序即可结束。在排序开始时的增量较大,分组也会较多,但是每个分组中的数据较少,所以插入排序会很快。随着每一轮排序的进行,增量和分组数会逐渐变小,每个分组中的数据会逐渐变多。但因为之前已经经过了多轮的分组排序,而此时的数组会趋近于一个有序的状态,所以这个时候的排序也是很快的。而对于数据较多且趋向于无序的数据来说,如果只是使用插入排序的话效率就并不高。所以总体来说,希尔排序的执行效率是要比插入排序高的。import java.util.Arrays; class Solution { // 交换数组元素位置 public static void swap(int[] array,int index1,int index2){ int temp = array[index1]; array[index1] = array[index2]; array[index2] = temp; } public static void shellSort(int[] array){ int gap = array.length >>> 1; // 希尔排序的初始增量 while (gap>0){ for (int i = 0; i < gap; i++) { //对根据增量划分的组执行插入排序 // 一次排序一个增量组--插入排序 for (int j = i+gap; j < array.length; j+=gap) { int curItem = array[j]; // 待排序元素 int k = j - gap; while (k>=i&&array[k]>curItem){ array[k+gap] = array[k]; k-=gap; } array[k+gap] = curItem; } } gap >>>= 1; } } public static void main(String[] args) { int[] array = new int[]{1,9,4,8,2,3,0,7,5,6}; shellSort(array); System.out.println(Arrays.toString(array)); } }1.6 堆排序堆排序的过程是首先构建一个大(小)顶堆,大顶堆首先是一棵完全二叉树,其次它保证堆中任意节点的值总是不大(小)于其父节点的值。因为大顶堆中的最大元素肯定是根节点,所以每次取出根节点即为当前大顶堆中的最大元素,取出后剩下的节点再重新构建大顶堆,再取出根节点,再重新构建…重复这个过程,直到数据都被取出,最后取出的结果即为排好序的结果。import java.util.Arrays; class Solution { // 交换数组元素位置 public static void swap(int[] array,int index1,int index2){ int temp = array[index1]; array[index1] = array[index2]; array[index2] = temp; } /** * 维护堆的性质 * @param array 存储堆的数组 * @param size 堆的大小 * @param i 待维护节点的下标 */ public static void heapify(int[] array,int size,int i ){ int largest = i; int lson = i*2+1; int rson = i*2+2; if(lson<size&&array[lson]>array[largest]) largest = lson; if(rson<size&&array[rson]>array[largest]) largest = rson; if(largest!=i){ swap(array,largest,i); heapify(array,size,largest); } } public static void heapSort(int[] array,int size){ // 建堆 for (int i = size/2-1; i>=0 ; i--) { // 从最后一个元素的父节点开始维护 heapify(array,size,i); } // 排序 for (int i = size-1; i >=0 ; i--) { swap(array,i,0); // 将堆的最后一个元素和堆顶元素进行交换 heapify(array,i,0); // 将堆顶元素移出堆,并维护堆顶元素的性质 } } public static void main(String[] args) { int[] array = new int[]{1,9,4,8,2,3,0,7,5,6}; heapSort(array, array.length); System.out.println(Arrays.toString(array)); } }1.7 归并排序归并排序使用的是分治的思想,首先将数组不断拆分,直到最后拆分成两个元素的子数组,将这两个元素进行排序合并,再向上递归。不断重复这个拆分和合并的递归过程,最后得到的就是排好序的结果。import java.util.Arrays; class Solution { // 交换数组元素位置 public static void swap(int[] array,int index1,int index2){ int temp = array[index1]; array[index1] = array[index2]; array[index2] = temp; } // 合并 public static void merge(int[] array, int left, int mid, int right) { int[] temp = new int[right - left + 1]; // 临时数组 int p1 = left; // 标记左半区第一个未排序的元素 int p2 = mid + 1; // 标记右半区第一个未排序的元素 int k = 0; //临时数组元素的下标 // 合并两个有序数组 while (p1 <= mid && p2 <= right) { if (array[p1] <= array[p2]) { temp[k++] = array[p1++]; } else { temp[k++] = array[p2++]; } } // 把剩余的数组直接放到temp数组中 while (p1 <= mid) { temp[k++] = array[p1++]; } while (p2 <= right) { temp[k++] = array[p2++]; } // 复制回原数组 for (int i = 0; i < temp.length; i++) { array[i + left] = temp[i]; } } public static void mergeSort(int[] array,int left,int right){ //如果只有一个元素,那么就不需要继续划分 //只有一个元素的区域,本生就是有序的,只需要被归并即可 if(left<right){ //找中间点,这里没有选择“(left + right) / 2”的方式,是为了防止数据溢出 int mid = left + ((right - left) >>> 1); // 递归划分左半区 mergeSort(array, left, mid); // 递归划分右半区 mergeSort(array, mid + 1, right); // 对子数组进行合并 merge(array, left, mid, right); } } public static void main(String[] args) { int[] array = new int[]{1,9,4,8,2,3,0,7,5,6}; mergeSort(array,0, array.length); System.out.println(Arrays.toString(array)); } }1.8 计数排序计数排序会创建一个临时的数组,里面存放每个数出现的次数。比如一个待排序的数组是[2,4,1,2,5,3,4,8,7],那么这个临时数组中记录的数据就是[0,1,2,1,2,1,0,1,1]。那么最后只需要遍历这个临时数组中的计数值就可以了。import java.util.Arrays; class Solution { // 交换数组元素位置 public static void swap(int[] array,int index1,int index2){ int temp = array[index1]; array[index1] = array[index2]; array[index2] = temp; } public static int[] countingSort(int[] array,int left,int right){ //记录待排序数组中的最大值 int max = array[0]; //记录待排序数组中的最小值 int min = array[0]; for (int item : array) { if (item > max) max = item; if (item < min) min = item; } //记录每个数出现的次数 int[] temp = new int[max - min + 1]; for (int item : array) { temp[item - min]++; } // 将结果复制回原数组 int index = 0; for (int i = 0; i < temp.length; i++) { //当输出一个数之后,当前位置的计数就减一,直到减到0为止 while (temp[i]-- > 0) { array[index++] = i + min; } } return array; } public static void main(String[] args) { int[] array = new int[]{1,9,4,8,2,3,0,7,5,6}; countingSort(array,0, array.length); System.out.println(Arrays.toString(array)); } }1.9 桶排序上面的计数排序在数组最大值和最小值之间的差值是多少,就会生成一个多大的临时数组,也就是生成了一个这么多的桶,而每个桶中就只插入一个数据。如果差值比较大的话,会比较浪费空间。那么我能不能在一个桶中插入多个数据呢?当然可以,而这就是桶排序的思路。桶排序类似于哈希表,通过一定的映射规则将数组中的元素映射到不同的桶中,每个桶内进行内部排序,最后将每个桶按顺序输出就行了。桶排序执行的高效与否和是否是稳定的取决于哈希散列的算法以及内部排序的结果。需要注意的是,这个映射算法并不是常规的映射算法,要求是每个桶中的所有数都要比前一个桶中的所有数都要大,这样最后输出的才是一个排好序的结果。比如说第一个桶中存1-30的数字,第二个桶中存31-60的数字,第三个桶中存61-90的数字...以此类推import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.List; class Solution { // 交换数组元素位置 public static void swap(int[] array,int index1,int index2){ int temp = array[index1]; array[index1] = array[index2]; array[index2] = temp; } public static int[] bucketSort(int[] array,int left,int right){ if (array == null || array.length < 2) { return array; } //记录待排序数组中的最大值 int max = array[0]; //记录待排序数组中的最小值 int min = array[0]; for (int i : array) { if (i > max) { max = i; } if (i < min) { min = i; } } //计算桶的数量(可以自定义实现) int bucketNumber = (max - min) / array.length + 1; List<Integer>[] buckets = new ArrayList[bucketNumber]; //计算每个桶存数的范围(可以自定义实现或者不用实现) int bucketRange = (max - min + 1) / bucketNumber; for (int value : array) { //计算应该放到哪个桶中(可以自定义实现) int bucketIndex = (value - min) / (bucketRange + 1); //延迟初始化 if (buckets[bucketIndex] == null) { buckets[bucketIndex] = new ArrayList<>(); } //放入指定的桶 buckets[bucketIndex].add(value); } int index = 0; for (List<Integer> bucket : buckets) { if (bucket == null) { continue; } //对每个桶进行内部排序,我这里使用的是快速排序,也可以使用别的排序算法,当然也可以继续递归去做桶排序 bucket.sort(new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { return o1-o2; } }); //将不为null的桶中的数据按顺序写回到array数组中 for (Integer integer : bucket) { array[index++] = integer; } } return array; } public static void main(String[] args) { int[] array = new int[]{1,9,4,8,2,3,0,7,5,6}; bucketSort(array,0, array.length); System.out.println(Arrays.toString(array)); } }1.10 基数排序基数排序不是根据一个数的整体来进行排序的,而是将数的每一位上的数字进行排序。比如说第一轮排序,我拿到待排序数组中所有数个位上的数字来进行排序;第二轮排序我拿到待排序数组中所有数十位上的数字来进行排序;第三轮排序我拿到待排序数组中所有数百位上的数字来进行排序...以此类推。每一轮的排序都会累加上一轮所有前几位上排序的结果,最终的结果就会是一个有序的数列。基数排序一般是对所有非负整数进行排序的,但是也可以有别的手段来去掉这种限制(比如都加一个固定的数或者都乘一个固定的数,排完序后再恢复等等)。基数排序和桶排序很像,桶排序是按数值的区间进行划分,而基数排序是按数的每一位的值进行划分。同时这两个排序都是需要依靠其他排序算法来实现的(如果不算递归调用桶排序本身的话)。基数排序每一轮的内部排序会使用到计数排序来实现,因为每一位上的数字无非就是0-9,是一个小范围的数,所以使用计数排序很合适。import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.List; class Solution { // 交换数组元素位置 public static void swap(int[] array,int index1,int index2){ int temp = array[index1]; array[index1] = array[index2]; array[index2] = temp; } public static void radixSort(int[] array) { //定义一个二维数组,表示10个桶,每个桶就是一个一维数组 int[][] bucket = new int[10][array.length];//很明显,基数排序使用了空间换时间 //为了记录每个桶中实际存放了多少个数据,定义一个一维数组来记录每次放入数据的个数 //比如bucketElementCounts[0]=3,意思是bucket[0]存放了3个数据 int[] bucketElementCounts = new int[10]; int digitOfElement = 0;//每次取出的元素的位数 //找到数组中最大数的位数 int max = 0; for (int i = 0; i < array.length; i++) { if (max < String.valueOf(array[i]).length()) { max = String.valueOf(array[i]).length(); } } int index = 0; for (int i = 0, n = 1; i < max; i++, n *= 10) { //第i+1轮排序(针对每个元素的位进行排序处理) for (int j = 0; j < array.length; j++) { digitOfElement = array[j] / n % 10;//取出每个元素的位 bucket[digitOfElement][bucketElementCounts[digitOfElement]] = array[j];//放入对应的桶 bucketElementCounts[digitOfElement]++; } //按照桶的顺序(一维数组的下标取出数据),放入原来的数组 index = 0; //遍历每一个桶,并将桶中数据放入原数组 for (int k = 0; k < bucketElementCounts.length; k++) { //如果桶中有数据,我们才放到原数组 if (bucketElementCounts[k] != 0) { //循环第k个桶,放入 for (int l = 0; l < bucketElementCounts[k]; l++) { array[index] = bucket[k][l]; index++; } } bucketElementCounts[k] = 0;//置零!!!!! } } } public static void main(String[] args) { int[] array = new int[]{1,9,4,8,2,3,0,7,5,6}; radixSort(array); System.out.println(Arrays.toString(array)); } }参考资料排序算法:快速排序【图解+代码】排序算法:堆排序【图解+代码】[排序算法:希尔排序【图解+代码】]()排序算法:归并排序【图解+代码】十种经典排序算法总结基数排序(Java)
2022年09月01日
813 阅读
0 评论
0 点赞
2022-08-31
Selenium:Python爬虫进阶
1.简介1.1 什么是Selenium?官网: Selenium是一个用于Web应用程序测试的工具。真实:大量用于网络爬虫,相比requests爬虫,完全模拟真人使用浏览器的流程,对于动态JS加载的网页更容易爬取1.2 Selenium的功能框架底层使用JavaScript模拟真实用户对浏览器进行操作。测试脚本执行时,浏览器自动按照脚本代码做出点击,输入,打开,验证等操作,就像真实用户所做的一样,从终端用户的角度测试应用程序。可用于较难的爬虫:动态JS加载、登录验证、表单提交等使用简单,可使用Python、Java等多种语言编写用例脚本。1.3 为什么要学习Selenium?requests爬虫局限性较大,分析困难、被封禁概率高可用于较难的爬虫伪装成真实的浏览器,被封禁的概率更低动态JS加载登录验证表单提交等1.4 Selenium的缺点相比requests,性能比较差,爬取的慢1.5 Selenium运行框架2.Selenium环境搭建1.电脑安装谷歌Chrome浏览器(其他浏览器不推荐)需要看一下当前的Chrome版本号,下载对应ChromeDriver2.下载安装 ChromeDriverhttps://www.selenium.dev/documentation/getting_started/installing_browser_drivers/windowns 放到C:\WebDriver\bin目录,这个目录加入系统PATH3.Python安装selenium库pip install selenium3.Selenium实战案例3.1 爬取电影天堂的视频真实下载地址用到selenium加载页面渲染出m3u8文件的地址from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.chrome.service import Service from selenium.webdriver.common.by import By from selenium.webdriver.support.wait import WebDriverWait from bs4 import BeautifulSoup import re # 实例化一个浏览器对象(传入浏览器的驱动程序) 通过Options实现无可视化界面的操作 chrome_options = Options() chrome_options.add_argument('--headless') # 不显示浏览器在后台运行 chrome_service = Service("chromedriver.exe"); browser = webdriver.Chrome(service=chrome_service,options=chrome_options) # 封装通过selenium获取html的方法 def get_html_by_selenium(url): # 对url发起请求 browser.get(url) # 等待页面加载完成 wait = WebDriverWait(browser, 3); # 获取页面源代码 page_html = browser.page_source return page_html # 电视剧页面地址_base base_url = "https://www.dy10000.com/wplay/68599-2-{}.html" # 生成下载脚本 for i in range(42,48): url = base_url.format(i) html = get_html_by_selenium(url) soup = BeautifulSoup(html, features='lxml') script_all = soup.body.find_all("script") for script in script_all: m3u8_search = re.search(r"http.*?m3u8", str(script)) if m3u8_search: url_m3u8 = m3u8_search.group(0).replace("\\", "") print("ffmpeg -i ", url_m3u8, " -c copy -bsf:a aac_adtstoasc " + str(i) + ".mp4") break # 退出浏览器 browser.quit()ffmpeg -i https://new.iskcd.com/20220518/FhKxDhXk/index.m3u8 -c copy -bsf:a aac_adtstoasc 42.mp4 ffmpeg -i https://new.iskcd.com/20220518/2MSrEhUz/index.m3u8 -c copy -bsf:a aac_adtstoasc 43.mp4 ffmpeg -i https://new.iskcd.com/20220519/7o5nJxJ3/index.m3u8 -c copy -bsf:a aac_adtstoasc 44.mp4 ffmpeg -i https://new.iskcd.com/20220519/BB2x9BaG/index.m3u8 -c copy -bsf:a aac_adtstoasc 45.mp4 ffmpeg -i https://new.iskcd.com/20220520/AxB2XF4T/index.m3u8 -c copy -bsf:a aac_adtstoasc 46.mp43.2 爬取电影先生的视频真实下载地址用到selenium加载页面渲染出m3u8文件的地址from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.chrome.service import Service from selenium.webdriver.common.by import By from selenium.webdriver.support.wait import WebDriverWait from bs4 import BeautifulSoup import re # 实例化一个浏览器对象(传入浏览器的驱动程序) 通过Options实现无可视化界面的操作 chrome_options = Options() chrome_options.add_argument('--headless') # 不显示浏览器在后台运行 chrome_service = Service("chromedriver.exe"); browser = webdriver.Chrome(service=chrome_service,options=chrome_options) # 封装通过selenium获取html的方法 def get_html_by_selenium(url): # 对url发起请求 browser.get(url) # 等待页面加载完成 wait = WebDriverWait(browser, 5); # 获取页面源代码 page_html = browser.page_source return page_html # 电视剧页面地址_base base_url = "https://dyxs15.com/paly-222156-5-{}/" # 生成下载脚本 for i in range(15,41): url = base_url.format(i) html = get_html_by_selenium(url) soup = BeautifulSoup(html, features='lxml') td_all = soup.body.find_all("td") for td in td_all: m3u8_search = re.search(r"http.*?m3u8", str(td)) if m3u8_search: url_m3u8 = m3u8_search.group(0).replace("\\", "") print("ffmpeg -i ", url_m3u8, " -c copy -bsf:a aac_adtstoasc " + str(i) + ".mp4") break break # 退出浏览器 browser.quit()ffmpeg -i https://new.qqaku.com/20220526/t5C1cVna/index.m3u8 -c copy -bsf:a aac_adtstoasc 15.mp4 ······ ffmpeg -i https://new.qqaku.com/20220617/Wpf7uowm/index.m3u8 -c copy -bsf:a aac_adtstoasc 40.mp4参考资料https://www.bilibili.com/video/BV1WF411z7qB自动化爬虫selenium基础教程selenium如何不显示浏览器在后台运行Python selenium的这三种等待方式一定要会!
2022年08月31日
861 阅读
0 评论
0 点赞
2022-08-30
天若OCR对接百度文字识别
0.背景在使用文字识别工具天若OCR的时候遇到搜狗、腾讯、有道等接口崩溃导致无法识别的问题,因此考虑使用百度的付费接口进行识别。1.百度文字识别API Key和Secret Key申请打开百度图文识别网站:https://console.bce.baidu.com/ai/#/ai/ocr/overview/index,输入账号密码登录;领取免费尝鲜略然后点击创建应用填写应用名称、应用归属、应用描述点击立即创建然后点击查看应用详情即可看到申请到的API Key和Secret Key2.对接天若OCR$\color{red}{!!!然后发现天若OCR修改密钥是付费版的特权}$$\color{red}{!!!再然后又发现5.0.0版本的虽然在软件里修改无法生效,但是直接修改Data/config.ini下的相关参数可以生效,感觉我的智商受到了侮辱}$[密钥_百度] secret_id=87gTF7eSNwA9z7L2OGuyaxAA secret_key=G5Yp5sA6POKKrFuGhcub21sGvzDIHaw2使用测试-真香3.自行调用-以JavaScript为例3.1 图片转换成base64格式var path = "/sdcard/pic/test01.jpg"; var imag64 = images.toBase64(images.read(path));3.2 获取access_tokenvar getTokenUrl="https://aip.baidubce.com/oauth/2.0/token"; var token_Res = http.post(getTokenUrl, { grant_type: "client_credentials", client_id: API_Key, //API Key client_secret: Secret_Key, //Secret Key }); var access_token = token_Res.body.json().access_token;3.3 调用百度ocr通用文字识别APIvar ocrUrl = "https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic"; var ocr_Res = http.post(ocrUrl, { headers: { "Content-Type": "application/x-www-form-urlencoded" }, access_token: access_token, //生成的token image: imag64, //生成的base64编码 language_type:"CHN_ENG" }); var json = ocr_Res.body.json();3.4 得到json格式结果:{ "words_result": [ {"words": "小微"}, {"words": "测试"} ], "log_id": 2471272194, "words_result_num": 2 }参考资料百度文字识别API Key和Secret Key申请及接口调用
2022年08月30日
882 阅读
0 评论
0 点赞
2022-08-29
航空器的的飞行阶段
一般航空器的的飞行阶段分为五个阶段,分别是:推出滑行、起飞离场、巡航、下降进近、落地和复飞。一、推出滑行 在上客阶段完成,机组做好了所有的航前检查和准备,飞行员就会跟机场塔台申请放行许可(ATC Clearance),同时也会申请推出和开车。管制部门许可机组推出滑行后,机组会沿着塔台指定的滑行路线从机坪滑到跑道入口外等待进一步指令。二、起飞离场机组得到塔台进跑道和起飞的指令后,就以为这架巨大银鹰马上要展翅高飞了,进跑道,对正跑道中心线,推油门,手扶方向舵,加速拉杆,飞行员一系列操作完成后,这架飞机已经离开了地面,正沿着指定的航迹和高度许可爬升高度。跑道上和起飞3分钟,落地8分钟是飞行中最危险的位置和时间,飞机诞生以来,飞行事故大多就发生在这个阶段,历史上死亡人数最多的特内里费空难就发生在跑道上,起飞阶段两架满载旅客的波音747相撞,死亡人数高达500人左右。三、巡航 当飞机的高度上升到了巡航高度,例如一万零一千米,这时,这架飞机进入了巡航阶段,如果没有天气,颠簸,冲突或其他情况,那接下来的很长一段时间飞机几乎就会保持在这个高度附近,一直沿计划航路飞行,直到快到目的地。三万英尺(一万米)左右的巡航高度接近了大气层的对流层顶部分,在这个高度飞行,飞机会相对平稳一些,美丽的空中乘务员们会利用这段时间进行客舱服务。四、下降进近 当航空器距离目的地机场200-300公里时,飞机一般要开始下降了,为保证旅客的舒适性,运输航班的下降率一般为1000-2000英尺/分钟左右,到达真高2000米左右飞机一般会开始最后进近阶段,这个阶段飞机会打开起落架轮仓,放出并锁定起落架,对正跑道,做好落地前的所有检查单和准备工作。 处。五、落地和复飞 在得到塔台的可以落地指令后,飞机继续沿无线电搭建的下滑道平稳进近,边进近边下降高度。如果突然有特殊情况发生,如跑道侵入,风切变等一系列因素导致不能继续进近,飞行员就需要操作飞机推油门拉杆,复飞爬升,重新进近或者去其他机场返航备降。平稳落地后飞机还是会按指定的路线滑回机位。参考资料分享:航空器飞行的几个飞行阶段
2022年08月29日
654 阅读
0 评论
0 点赞
2022-08-26
机架式服务器安装-以HP380为例
0.核心配件1.安装服务器上的导轨1.1 将导轨片安装在服务器两侧2.安装机架上的导轨上机架的导轨上分别标有“REAL+RIGHT”和“REAL+LEFT”,表示示这端安装在机架的后面,而标有“FRONT+RIGHT”和“FRONT+LEFT”的两端则安装在机架的前面:2.1 将标有"REAL RIGHT"的一端扣在机架后面的孔上2.2 将标有"FRONT RIGHT"的一端扣在机架前面的孔上2.3 将左右两侧导轨分别安装的机架上后,如下图所示3.组合固定3.1 将导轨里的小导片抽出3.2 将安装在服务器两侧上的导片分别插入机架的导轨片中3.3 将服务器顺着导轨推入参考资料HPDL380服务器机架安装示意图戴尔机架式服务器1U导轨安装教程戴尔服务器r730怎么安装到机架上机架服务器安装说明
2022年08月26日
765 阅读
0 评论
0 点赞
2022-08-01
航班不同子舱含义
F舱为头等舱公布价,A舱为头等舱免折、常旅客免票;C舱为公务舱公布价,D舱为公务舱免折、常旅客免票;Y舱为普通舱(经济舱)公布价,S舱为联程、缺口程等特殊舱位,B舱为普通舱9折,H舱为普通舱85折,K舱为普通舱80折,L舱为普通舱75折,M舱为普通舱70折,N舱为普通舱65折,Q舱为普通舱60折(含教师、医护人员、县级以上劳模),T舱为普通舱55折,X舱为普通舱50折(含学生、长者),U舱为普通舱45折,E舱为普通舱40折,W舱为普通舱35折,R舱为普通舱30折,O舱为普通舱25折,Z舱为代码共享留座专用舱,V舱为常旅客专用舱,G舱为普通舱免折和常旅客免票。
2022年08月01日
1,721 阅读
0 评论
0 点赞
2022-06-23
海康威视监控摄像头使用指南
1.设备连接12v电源+网线2.通过设备网络搜索软件找到设备IP下载地址https://www.hikvision.com/cn/support/Downloads/Desktop-Application/HikvisionTools/运行界面3.通过网页访问访问地址:http://10.1.9.31/首次使用需要配置用户名和密码登录用户名:admin 密码:!itrb1234.下载客户端访问下载地址https://www.hikvision.com/cn/support/Downloads/Desktop-Application/Client-Application/客户端使用
2022年06月23日
2,297 阅读
2 评论
0 点赞
2022-06-19
linux搭建ntp时间同步服务器
1.NTP简介NTP是Network Time Protocol的缩写,又称为网络时间协议。是用来使计算机时间同步化的一种协议,它可以使计算机对其服务器或时钟源(如石英钟,GPS等等)做同步化,它可以提供高精准度的时间校正(LAN上与标准间差小于1毫秒,WAN上几十毫秒),且可介由加密确认的方式来防止恶毒的协议。为用户提供授时服务,并且这些网站间应该能够相互比对,提高准确度。2.服务器配置2.1 安装sudo apt-get install ntp2.2 修改配置(利用server设定上层NTP服务器)sudo vim /etc/ntp.conf上层NTP服务器的设定方式为:server [IP OR HOSTNAME] [PREFER]常见的时间服务器server 2.cn.pool.ntp.org server 3.asia.pool.ntp.org server 0.cn.pool.ntp.org写入到配置文件启动ntp服务/etc/init.d/ntp start3.客户端使用服务同步时间sudo apt install ntpdate ntpdate ${服务器IP}root@wky:~# ntpdate amd.inat.top 19 Jun 01:02:33 ntpdate[3236]: step time server 10.1.131.250 offset 13812059.680274 sec root@wky:~# date 2022年 06月 19日 星期日 01:02:39 +09参考资料Ubuntu搭建NTP服务器ubuntu安装ntp服务器(linux配置ntp服务器)
2022年06月19日
711 阅读
0 评论
0 点赞
2022-06-17
Linux搭建搭建Hadoop环境
1.准备工作1.1 准备机器准备若干台Linux的机器(1-n),物理机虚拟机均可1.2 关闭selinux(每台机器)sudo vim /etc/sysconfig/selinuxreboot1.3 安装JDK(每台机器)下载解压jdkcd /software tar -zxvf jdk-8u201-linux-x64.tar.gz mv jdk1.8.0_201/ java修改环境变量,在末尾添加如下内容sudo vim /etc/profileexport JAVA_HOME=/software/java export PATH="$JAVA_HOME/bin:$PATH"source /etc/profile验证(注意如果是openjdk版本的把openjdk版本的删除掉)(base) [jupiter@centeros bin]$ java -version java version "1.8.0_201" Java(TM) SE Runtime Environment (build 1.8.0_201-b09) Java HotSpot(TM) 64-Bit Server VM (build 25.201-b09, mixed mode)2.搭建hadoop伪分布式(单节点)2.1 下载并解压hadoop官网:https://hadoop.apache.org/cd /software wget https://www.apache.org/dyn/closer.cgi/hadoop/common/hadoop-3.3.1/hadoop-3.3.3.tar.gz tar -xzvf hadoop-3.3.3.tar.gz mv hadoop-3.3.3 hadoop cd hadoop配置相关环境变量sudo vim /etc/profile # 加入如下内容 #HADOOP_HOME export HADOOP_HOME=/software/hadoop export PATH=$PATH:$HADOOP_HOME/bin export PATH=$PATH:$HADOOP_HOME/sbinsource /etc/profile2.2 修改hadoop相关配置主要需要配置四个文件,对应hadoop四大模块,均位于etc/hadoop下面hadoop四大模块common:core-site.xmlcommon 及核心公共模块,默认配置(core-site.xml),主要包括Hadoop常用的工具类,由原来的Hadoopcore部分更名而来。主要包括系统配置工具Configuration、远程过程调用RPC、序列化机制和Hadoop抽象文件系统FileSystem等。它们为在通用硬件上搭建云计算环境提供基本的服务,并为运行在该平台上的软件开发提供了所需的APIhdfs (hadoop distribute file system):hdfs-site.xml分布式文件系统,提供对应用程序数据的高吞吐量,高伸缩性,高容错性的访问。是Hadoop体系中数据存储管理的基础。它是一个高度容错的系统,能检测和应对硬件故障,用于在低成本的通用硬件上运行。通过流式数据访问,提供高吞吐量应用程序数据访问功能,适合带有大型数据集的应用程序。(namenode+datanode+secondarynode)mapreduce:mapred-site.xmlmapreduce 是一种分而治之思想,是一种计算模型,用以进行大数据量的计算。Hadoop的MapReduce实现,和Common、HDFS一起,构成了Hadoop发展初期的三个组件。MapReduce将应用划分为Map和Reduce两个步骤,其中Map对数据集上的独立元素进行指定的操作,生成键-值对形式中间结果。mapreduce的运行流程 input->map->shuffle->reduce->output 。input 数据输入文件分片,map负责就进数据处理,多个mapper之间并行处理,shuffle负责数据混淆分区、排序、拷贝、分组、压缩等操作,完成后将数据传给reduce进行处理,reduce负责对map阶段的数据进行汇总。yarn:yarn-site.xmlYarn是Hadoop集群的资源管理系统,由两部分功能组成资源管理和任务调度监控主要的组件,ResourceManager:Global(全局)的进程 ;NodeManager:运行在每个节点上的进程,ApplicationMaster:Application-specific(应用级别)的进程,向rm申请资源,对运行在datanode的应用进行监控;Scheduler:是ResourceManager的一个组件,Container:节点上一组CPU和内存资源容器。core-site.xml<configuration> <!-- 指定HDFS老大(namenode)的通信地址 --> <property> <name>fs.defaultFS</name> <value>hdfs://localhost:9000</value> </property> <property> <!-- 指定hadoop运行时产生文件的存储路径 --> <name>hadoop.tmp.dir</name> <value>/software/hadoop/tmp</value> </property> </configuration>hdfs-site.xml<configuration> <!--配置hdfs副本数量--> <property> <name>dfs.replication</name> <value>1</value> </property> </configuration>mapred-site.xml<configuration> <!-- 通知框架MR使用YARN --> <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> </configuration>yarn-site.xml<configuration> <!-- 通知框架MR使用YARN --> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> </configuration>2.3 运行Hadoop修改etc/hadoop/hadoop-env.shexport JAVA_HOME="/software/java"初始化HDFS系统hdfs namenode -format启动hadoop#先启动HDFS sbin/start-dfs.sh #再启动YARN sbin/start-yarn.sh查看进程信息jps(base) [jupiter@centeros hadoop]$ jps 32613 SecondaryNameNode 374 ResourceManager 903 Jps 521 NodeManager 32222 NameNode4.验证http://centeros.inat.top:9870/:HDFS管理界面http://centeros.inat.top:8088/:MapReduce管理界面3.搭建hadoop分布式(集群)参考:https://github.com/AdamJupiter/BigData/blob/master/hadoop%E9%9B%86%E7%BE%A4%E6%90%AD%E5%BB%BA/hadoop2.0%E9%9B%86%E7%BE%A4%E6%90%AD%E5%BB%BA.md参考资料centeros安装java8hadoop伪分布式环境搭建,完整的详细步骤Hadoop-单节点配置hadoop常用配置文件https://github.com/AdamJupiter/hadoop-guide
2022年06月17日
980 阅读
0 评论
0 点赞
1
...
6
7
8
...
24