347. 前 K 个高频元素 给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。
示例 1:
输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2:
输入: nums = [1], k = 1 输出: [1] 提示:
1 <= nums.length <= 105 k 的取值范围是 [1, 数组中不相同的元素的个数] 题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的 进阶:你所设计算法的时间复杂度 必须 优于 O(n log n) ,其中 n 是数组大小。
1 class Solution { 2 public: 3 struct cmp { 4 bool operator() (std::pair<int, int> a, std::pair<int, int> b) { 5 return a.
一、理解三次握手、四次挥手
1、什么是“3次握手,4次挥手” TCP是一种面向连接的单播协议,在发送数据前,通信双方必须在彼此间建立一条连接。所谓的“连接”,其实是客户端和服务器的内存里保存的一份关于对方的信息,如ip地址、端口号等。
TCP可以看成是一种字节流,它会处理IP层或以下的层的丢包、重复以及错误问题。在连接的建立过程中,双方需要交换一些连接的参数。这些参数可以放在TCP头部。
TCP提供了一种可靠、面向连接、字节流、传输层的服务,采用三次握手建立一个连接。采用4次挥手来关闭一个连接。
2、TCP服务模型 在了解了建立连接、关闭连接的“三次握手和四次挥手”后,我们再来看下TCP相关的东西。
一个TCP连接由一个4元组构成,分别是两个IP地址和两个端口号。一个TCP连接通常分为三个阶段:启动、数据传输、退出(关闭)。
当TCP接收到另一端的数据时,它会发送一个确认,但这个确认不会立即发送,一般会延迟一会儿。ACK是累积的,一个确认字节号N的ACK表示所有直到N的字节(不包括N)已经成功被接收了。这样的好处是如果一个ACK丢失,很可能后续的ACK就足以确认前面的报文段了。
一个完整的TCP连接是双向和对称的,数据可以在两个方向上平等地流动。给上层应用程序提供一种双工服务。一旦建立了一个连接,这个连接的一个方向上的每个TCP报文段都包含了相反方向上的报文段的一个ACK。
序列号的作用是使得一个TCP接收端可丢弃重复的报文段,记录以杂乱次序到达的报文段。因为TCP使用IP来传输报文段,而IP不提供重复消除或者保证次序正确的功能。另一方面,TCP是一个字节流协议,绝不会以杂乱的次序给上层程序发送数据。因此TCP接收端会被迫先保持大序列号的数据不交给应用程序,直到缺失的小序列号的报文段被填满。
TCP头部 源端口和目的端口在TCP层确定双方进程,序列号表示的是报文段数据中的第一个字节号,ACK表示确认号,该确认号的发送方期待接收的下一个序列号,即最后被成功接收的数据字节序列号加1,这个字段只有在ACK位被启用的时候才有效。
当新建一个连接时,从客户端发送到服务端的第一个报文段的SYN位被启用,这称为SYN报文段,这时序列号字段包含了在本次连接的这个方向上要使用的第一个序列号,即初始序列号ISN,之后发送的数据是ISN加1,因此SYN位字段会消耗一个序列号,这意味着使用重传进行可靠传输。而不消耗序列号的ACK则不是。
头部长度(图中的数据偏移)以32位字为单位,也就是以4bytes为单位,它只有4位,最大为15,因此头部最大长度为60字节,而其最小为5,也就是头部最小为20字节(可变选项为空)。
ACK —— 确认,使得确认号有效。 RST —— 重置连接(经常看到的reset by peer)就是此字段搞的鬼。 SYN —— 用于初如化一个连接的序列号。 FIN —— 该报文段的发送方已经结束向对方发送数据。
当一个连接被建立或被终止时,交换的报文段只包含TCP头部,而没有数据。
状态转换 三次握手和四次挥手的状态转换如下图。
3、为什么要“三次握手,四次挥手”
三次握手 换个易于理解的视角来看为什么要3次握手。
客户端和服务端通信前要进行连接,“3次握手”的作用就是双方都能明确自己和对方的收、发能力是正常的。
第一次握手:客户端发送网络包,服务端收到了。这样服务端就能得出结论:客户端的发送能力、服务端的接收能力是正常的。
第二次握手:服务端发包,客户端收到了。这样客户端就能得出结论:服务端的接收、发送能力,客户端的接收、发送能力是正常的。 从客户端的视角来看,我接到了服务端发送过来的响应数据包,说明服务端接收到了我在第一次握手时发送的网络包,并且成功发送了响应数据包,这就说明,服务端的接收、发送能力正常。而另一方面,我收到了服务端的响应数据包,说明我第一次发送的网络包成功到达服务端,这样,我自己的发送和接收能力也是正常的。
第三次握手:客户端发包,服务端收到了。这样服务端就能得出结论:客户端的接收、发送能力,服务端的发送、接收能力是正常的。 第一、二次握手后,服务端并不知道客户端的接收能力以及自己的发送能力是否正常。而在第三次握手时,服务端收到了客户端对第二次握手作的回应。从服务端的角度,我在第二次握手时的响应数据发送出去了,客户端接收到了。所以,我的发送能力是正常的。而客户端的接收能力也是正常的。
经历了上面的三次握手过程,客户端和服务端都确认了自己的接收、发送能力是正常的。之后就可以正常通信了。
每次都是接收到数据包的一方可以得到一些结论,发送的一方其实没有任何头绪。我虽然有发包的动作,但是我怎么知道我有没有发出去,而对方有没有接收到呢?
而从上面的过程可以看到,最少是需要三次握手过程的。两次达不到让双方都得出自己、对方的接收、发送能力都正常的结论。其实每次收到网络包的一方至少是可以得到:对方的发送、我方的接收是正常的。而每一步都是有关联的,下一次的“响应”是由于第一次的“请求”触发,因此每次握手其实是可以得到额外的结论的。比如第三次握手时,服务端收到数据包,表明看服务端只能得到客户端的发送能力、服务端的接收能力是正常的,但是结合第二次,说明服务端在第二次发送的响应包,客户端接收到了,并且作出了响应,从而得到额外的结论:客户端的接收、服务端的发送是正常的。
用表格总结一下:
四次挥手 TCP连接是双向传输的对等的模式,就是说双方都可以同时向对方发送或接收数据。当有一方要关闭连接时,会发送指令告知对方,我要关闭连接了。这时对方会回一个ACK,此时一个方向的连接关闭。但是另一个方向仍然可以继续传输数据,等到发送完了所有的数据后,会发送一个FIN段来关闭此方向上的连接。接收方发送ACK确认关闭连接。注意,接收到FIN报文的一方只能回复一个ACK, 它是无法马上返回对方一个FIN报文段的,因为结束数据传输的“指令”是上层应用层给出的,我只是一个“搬运工”,我无法了解“上层的意志”。
4、“三次握手,四次挥手”怎么完成? 其实3次握手的目的并不只是让通信双方都了解到一个连接正在建立,还在于利用数据包的选项来传输特殊的信息,交换初始序列号ISN。
3次握手是指发送了3个报文段,4次挥手是指发送了4个报文段。注意,SYN和FIN段都是会利用重传进行可靠传输的。
三次握手
客户端发送一个SYN段,并指明客户端的初始序列号,即ISN(c).
服务端发送自己的SYN段作为应答,同样指明自己的ISN(s)。为了确认客户端的SYN,将ISN(c)+1作为ACK数值。这样,每发送一个SYN,序列号就会加1. 如果有丢失的情况,则会重传。
为了确认服务器端的SYN,客户端将ISN(s)+1作为返回的ACK数值。
四次挥手 1.
Given a 0-indexed integer array nums, return the number of distinct quadruplets (a, b, c, d) such that:
nums[a] + nums[b] + nums[c] == nums[d], and a < b < c < d Example 1:
Input: nums = [1,2,3,6] Output: 1 Explanation: The only quadruplet that satisfies the requirement is (0, 1, 2, 3) because 1 + 2 + 3 == 6. Example 2:
Input: nums = [3,3,6,4,5] Output: 0 Explanation: There are no such quadruplets in [3,3,6,4,5].
装饰模式
在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。
装饰模式的特点
(1) 装饰对象和真实对象有相同的接口。这样客户端对象就能以和真实对象相同的方式和装饰对象交互。
(2) 装饰对象包含一个真实对象的引用(reference)
(3) 装饰对象接受所有来自客户端的请求。它把这些请求转发给真实的对象。
(4) 装饰对象可以在转发这些请求以前或以后增加一些附加功能。这样就确保了在运行时,不用修改给定对象的结构就可以在外部增加附加的功能。在面向对象的设计中,通常是通过继承来实现对给定类的功能扩展。
优点
Decorator模式与继承关系的目的都是要扩展对象的功能,但是Decorator可以提供比继承更多的灵活性。
通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。
缺点
这种比继承更加灵活机动的特性,也同时意味着更加多的复杂性。
装饰模式会导致设计中出现许多小类,如果过度使用,会使程序变得很复杂。
装饰模式是针对抽象组件(Component)类型编程。但是,如果你要针对具体组件编程时,就应该重新思考你的应用架构,以及装饰者是否合适。当然也可以改变Component接口,增加新的公开的行为,实现“半透明”的装饰者模式。在实际项目中要做出最佳选择。
php代码实例
抽象一个工人类具有工作方法,2个子类(水管工、木工)实现了工人接口: `interface worker{
public function doSomeWork(); } //水管工 class shuiguan implements worker{ public function doSomeWork(){ echo '修水管'; } } //木工 class mu implements worker{public function doSomeWork(){echo '修门窗';}}现在有新的需求a公司的工人(包含水管、木工)进门要求先说“您好!”,我们想在不影响基础类的情况下统一实现这个功能。我们可以使用装饰模式类实现://a公司工人
class aWorker implements worker{
//具体的工人
public $worker;
//构造函数获取工人
public function __construct($worker){
原因src不是源文件,sources root,灰色是Unmake as sourcesroot, 解决:src右键>>Mark Directory as >>sources root,变蓝即可
注意:
记录初学python的一系列小笔记,帮助自己学习,因为工作中可能需要python技术的补充。这些记录的小笔记只作为一些零散的前期准备。短期而言有学习两种语言的计划,一门前端语言,一门python,会对这两种新学语言进行自认为比较规整的整体性的技术学习记录。长期来看会一直更新技术类的文章,涵盖面主要是与自动化场景相关的一系列技术文章,技术使用方面涉及编程、网络、plc等,技术标准方面触及IEEE、IEC、RF等,技术辅助方面会接触设计,流程,编译,发布等。综上所述,两年将是一个不错的长期节点,会在这两年内尽己所能努力学习。如果这些内容能帮助到你,那是万分荣幸的。
The notes will help me to learn python that is need for my work. Perhaps the notes can be a preparations for comprehensive records of later. Short term goals : learn the two programming languages, one is front-end language and the other is python. The notes will be quite clear and complete of the two programming languages.
Long term goals : there will be publish technical notes , technical types include use, specification, assistance.
手写数字识别 复制代码后依次运行下面命令
python3 lenet5.py python3 train.py python3 test.py lenet5.py import torch.nn as nn class LeNet5(nn.Module): def __init__(self): super(LeNet5, self).__init__() self.conv1 = nn.Sequential( nn.Conv2d( # (1, 28, 28) in_channels=1, out_channels=6, kernel_size=5, stride=1, padding=2 ), # (6, 28, 28) nn.ReLU(), nn.MaxPool2d(kernel_size=2, stride=2), # (6, 14, 14) ) self.conv2 = nn.Sequential( nn.Conv2d(6, 16, 5, 1, 0), nn.ReLU(), # (16, 10, 10) nn.MaxPool2d(2, 2) # (16, 5, 5) ) self.LinNet = nn.Sequential( nn.Linear(16 * 5 * 5, 120), nn.
本篇文章主要以php语言为基础为大家讲解在php中如何实现各种常见的设计模式。
设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的;设计模式使代码编制真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样。
设计模式相关知识
一、设计模式概述
设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性...
详情点击:《设计模式概述》
二、开闭原则
开闭原则(OCP)是面向对象设计中“可复用设计”的基石,是面向对象设计中最重要的原则之一,其它很多的设计原则都是实现开闭原则的一种手段...
详情点击:《开闭原则》
三、里氏代换原则
里氏替换原则LSP讲的是基类和子类的关系。只有当这种关系存在时,里氏代换关系才存在。如果两个具体的类A,B之间的关系违反了LSP的设计...
详情点击:《里氏代换原则》
四、接口隔离原则
客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上。使用多个专门的接口比使用单一的总接口要好。一个类对另外一个类的依赖性应当是建立在最小的接口上的...
详情点击:《接口隔离原则》
创建型模式
一、工厂模式 (factory pattern)
工厂模式(factory pattern)是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式。著名的Jive论坛 ,就大量使用了工厂模式,工厂模式在Java程序系统可以说是随处可见...
详情点击:《工厂模式》
二、单例模式 (Singleton pattern)
单例模式(Singleton pattern)是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例类的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源...
详情点击:《单例模式》
三、建造者模式 (Builder Pattern)
建造模式(Builder Pattern)是对象的创建模式。它可以将一个产品的内部表象与产品的生成过程分割开来,从而可以使一个建造过程生成具有不同的内部表象的产品对象...
详情点击:《建造者模式》
四、原型模式(Prototype)
Prototype原型模式是一种创建型设计模式,Prototype模式允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建的细节,工作原理是...
详情点击:《原型模式》
结构型模式
一、适配器模式 (Adapter Pattern)
Adapter模式也叫适配器模式,是构造型模式之一,通过Adapter模式可以改变已有类(或外部类)的接口形式。适配器模式应用场景...
详情点击:《适配器模式》
二、组合模式 (Composite Pattern)
组合模式:允许客户将对象组合成树形结构来表现整体/部分”层次结构。组合能让客户以一致的方式处理个别对象以及对象组合...
详情点击:《组合模式》
三、外观模式(门面模式)
外观模式是指通过外观的包装,使应用程序只能看到外观对象,而不会看到具体的细节对象,这样无疑会降低应用程序的复杂度,并且提高了程序的可维护性...
详情点击:《外观模式》
四、代理模式
代理模式的作用和继承以及接口和组合的作用类似,都是为了聚合共用部分,减少公共部分的代码。不同的是相比起继承,他们的语境不同,继承要表达的含义是 is-a, 而代理要表达的含义更接近于接口, 是 has-a,而且使用代理的话应了一句话少用继承,多用组合...
详情点击:《代理模式》
五、装饰模式
在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象...
详情点击:《装饰模式》
一、设置主题(美化界面)1、plugin中搜索-Material Theme UI 2、Tools -> Material Theme3、设置代码字体大小:安装laravel、bootstrap 4插件二、1、Tool windows :ctrl+12、数据库管理[database]:ctrl+shift+d3、终端窗口:terminal:ctrl+`4、Remote Host 远程主机面板 ctrl+shift+h5、Reformat代码格式化 ctrl+shift+l6、Run Command 切换命令控制台 ctrl+shift+m7、File Structure 查找文件定义的方法 ctrl+shift+o8、Navigate>File 查找文件 ctrl+p9、Recent Files 查找文件最近打开的文件 ctrl+e10、Editor Tabs>Close 关闭文件 ctrl+w,关闭所有:ctrl+alt+w11、Code>Generate 快捷创建 ctrl+enter
一、Lambda 表达式 是什么? Lambda读音:拉姆达。
Lambda是一个匿名函数,匿名函数就是一个没有名字的函数。 Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。 Lambda 表达式可以使代码变的更加简洁紧凑。 语法
lambda 表达式的语法格式如下:
(parameters) -> expression 或 (parameters) ->{ statements; } Java8 中引入了一个新的操作符 ->, 该操作符称为箭头操作符或 Lambda 操作符。
箭头操作符将 Lambda 表达式拆分成两部分:
左侧 : Lambda 表达式的参数。
右侧 : Lambda 表达式中所需执行的操作, 即 Lambda 体。
lambda表达式的重要特征:
可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。 可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。 可选的大括号:如果主体只有一个语句,可以不需要使用大括号。 可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定表达式返回了一个数值。 二、Lambda 表达式实例 Lambda 表达式的简单例子:
// 1. 无参数,无返回值 () -> System.out.print(Hello Lambda); // 2. 无参数,有返回值,返回值 5 () -> 5; // 3. 一个参数(箭头左侧括号可以省略),返回“参数+1”后的值 x -> x + 1 // 4.