操作起来 day1

计算机网络

综述

TCP/IP模型:应用层(用户态)、传输层(内核态)、网络层、数据链路层、物理层

传输层:为应用层提供网络支持

每个应用对应的端口号不同,例如80端口通常是Web服务器用,22端口是登录远程服务器,由操作系统分配

UDP

TCP:数据包太大时(超过TCP最大报文段即MSS)、分块,每个分块叫TCP段(会携带端口号)

网络层

常见的是IP协议,当IP报文段长度超过MTU时就会再次分片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OmSi7wo0-1646829336214)(C:\Users\yzh\AppData\Roaming\Typora\typora-user-images\image-20220309114428810.png)]

ip组成:(通过子网掩码算出)

网络号、主机号

计算规则:

网络号:将IP地址、子网掩码分别用二进制表示;进行与运算;得到的二进制转化为十进制即得网络号

主机号:将IP地址、子网掩码分别用二进制表示;先将子网掩码取反再与IP地址做与运算;得到的二进制转化为十进制

功能:

寻址 — 导航

路由 — 操作方向盘

数据链路层

当进行跨网络传输时,需要路由器,路由器如何根据IP地址找到特定的网络设备呢,

于是,需要有一个专门的层来标识网络设备,让数据在一个链路中传输

这就是数据链路层

每一个设备的网卡有一个mac地址,唯一标识设备,

路由器可以根据ARP协议由IP地址找到mac地址

物理层

数据从设备发送到网络时,需要将数据包转化为电信号,物理层就提供为数据链路层传输二进制数据的任务

HTTP

HTTP基本概念

http即hypertext transfer protocol,http是一个在计算机世界里专门在两点之间传输超文本的协议和规范

五大类状态码

1**:提示信息,当前处于中间态

2**:成功,报文已被成功处理

3**:重定向,资源发生变动,需要客户端重新请求

4**:客户端错误,请求报文有误,服务器无法处理

5**:服务器错误,服务器在处理请求时内部发生错误

http常见字段

Host字段:指定服务器的域名 www.A.com

content-length:服务器返回数据时,回应的数据长度

connection:常用于客户端要求服务器使用TCP持久连接,以便请求其他服用 eg:keep alive

content-type:用于服务器回应时,告诉客户端本次数据格式

content-encoding:表明服务器返回的数据采用了什么压缩方法

leetcode

分发饼干

错误:不应该在while里对下标进行++操作后再作为数组下标访问

int f(vector<int>& g, vector<int>& s){
    sort(g.begin(), g.end())
    int sindex = 0, gindex = 0, ans = 0;
    while(sindex < s.size()){
        if(s[sindex] >= g[gindex]){
            gindex++;
            ans++;
        }
        sindex++;
    }
    return ans;
}

使用最小花费爬楼梯

class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {
        int next, cur = 0, prev = 0;
        for(int i = 2 ; i <= cost.size() ; i++){
            next = min(cur + cost[i-1], prev + cost[i-2]);
            prev = cur;
            cur = next;
        }
        return next;
    }
};

不同路径

class Solution {
public:
    int uniquePaths(int m, int n) {
        vector<int>dp(n, 0);
        for(int j = 0; j < n; j++)  dp[j] = 1;
        for(int i = 1 ; i < m ; i++){
            for(int j = 1 ; j < n ; j++){
                dp[j] += dp[j-1];
            }
        }
        return dp[n-1];
    }
};

摆动序列 *

class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {
        int size = nums.size(), res = 1, prevdiff = 0;
        for (int i = 0; i < size - 1 ; i++) {
            int curdiff = nums[i+1] - nums[i];
            if((curdiff > 0 && prevdiff <= 0) || (curdiff < 0 && prevdiff >= 0)){
                res++;
                prevdiff = curdiff;
            }
        }
        return res;
    }
};

C++

成员变量的赋值顺序由他们在类中的声明顺序决定

类中的const成员变量初始化必须在构造函数的初始化列表中进行

为什么使用智能指针:

避免程序员申请完空间后忘记释放,智能指针能避免这个问题,当超出类的作用域之后,智能指针对象会调用析构函数释放掉自己

分类

auto_ptr

//错误用法
auto_ptr<std::string>p1 = new string("helllo");
//正确用法
auto_ptr<std::string>p1(new string("helllo"));
auto_ptr<std::string>p2;
p2 = p1;

至此auto_ptr并不会报错,但是当你想要访问p1时,程序报错,即存在潜在的内存崩溃问题

unique_ptr

unique_ptr<std::string>p1(new string("helllo"));
unique_ptr<std::string>p2;
p2 = p1;//此时会报错

unique_ptr实现独占式拥有或严格拥有概念,保证同一时间内只有一个智能指针指向该对象

shared_ptr(共享型、强引用)

多个指针可以指向相同对象,可以由unique_ptr,auto_ptr等初始化

能通过use_count()成员函数查看资源的所有者个数

weak_ptr?

weak_ptr 是⼀种不控制对象⽣命周期的智能指针,它指向⼀个 shared_ptr 管理的对象。进⾏该对象的内存管理 的是那个强引⽤的 shared_ptr。 weak_ptr 只是提供了对管理对象的⼀个访问⼿段。weak_ptr 设计的⽬的是为配合 shared_ptr ⽽引⼊的⼀种智 能指针来协助 shared_ptr ⼯作,它只可以从⼀个 shared_ptr 或另⼀个 weak_ptr 对象构造,,它的构造和析构不会 引起引⽤记数的增加或减少。 weak_ptr 是⽤来解决 shared_ptr 相互引⽤时的死锁问题,如果说两个 shared_ptr 相互引⽤,那么这两个指针的 引⽤计数永远不可能下降为0,也就是资源永远不会释放。它是对对象的⼀种弱引⽤,不会增加对象的引⽤计数, 和 shared_ptr 之间可以相互转化,shared_ptr 可以直接赋值给它,它可以通过调⽤ lock 函数来获得 shared_ptr。 当两个智能指针都是 shared_ptr 类型的时候,析构时两个资源引⽤计数会减⼀,但是两者引⽤计数还是为 1,导 致跳出函数时资源没有被释放(的析构函数没有被调⽤),解决办法:把其中⼀个改为weak_ptr就可以。

C++中内存分配情况

栈:局部变量、函数参数,由编译器管理和回收

堆:new/delete malloc\free 由程序员自行管理

全局/静态存储区:分为初始化和未初始化两个区域,分别存储初始化和未初始化的全局和静态变量

常量存储区:存储常量,一般不允许修改

代码区:存放二进制代码

形参与实参

形参:在函数定义中出现的参数可以看做是一个占位符,它没有数据,只能等到函数被调用时接收传递进来的数据,所以称为形式参数,简称形参

实参:函数被调用时给出的参数包含了实实在在的数据,会被函数内部的代码使用,所以称为实际参数,简称实参

形参和实参的区别和联系

\1) 形参变量只有在函数被调用时才会分配内存,调用结束后,立刻释放内存,所以形参变量只有在函数内部有效,不能在函数外部使用。

\2) 实参可以是常量、变量、表达式、函数等,无论实参是何种类型的数据,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参,所以应该提前用赋值、输入等办法使实参获得确定值。

\3) 实参和形参在数量上、类型上、顺序上必须严格一致,否则会发生“类型不匹配”的错误。当然,如果能够进行自动类型转换,或者进行了强制类型转换,那么实参类型也可以不同于形参类型。

\4) 函数调用中发生的数据传递是单向的,只能把实参的值传递给形参,而不能把形参的值反向地传递给实参;换句话说,一旦完成数据的传递,实参和形参就再也没有瓜葛了,所以,在函数调用过程中,形参的值发生改变并不会影响实参。

C++中的指针参数传递和引用参数传递

指针传递:创造副本,形参指针变了,实参指针不会变

引用传递:被调函数也会为形参在栈中开辟一段空间,但是存放的是实参变量的地址,别名,形参变则实参变

似乎可以使用二级指针来改变指针的引用----------C语言指针:指针作为形参如何改变其指向的地址? - 知乎 (zhihu.com)

#include<iostream>
#include<vector>
using namespace std;

int b[2] = { 1, 2 };//得是全局变量
void f1(int* *p) {

    cout << &b << endl;
    *p = b;
}

int main() {
    int a = 5;
    int* p = &a;
    cout << "p指向的变量的值" << *p << endl;
    f1(&p);
    cout << "p指向的变量的值" << p[0] << endl;
    return 0;
}
/*
p指向的变量的值5
00007FF6701AD000
p指向的变量的值1
*/


void f1(int* *p) {

cout << &b << endl;
*p = b;

}

int main() {
int a = 5;
int* p = &a;
cout << “p指向的变量的值” << p << endl;
f1(&p);
cout << “p指向的变量的值” << p[0] << endl;
return 0;
}
/

p指向的变量的值5
00007FF6701AD000
p指向的变量的值1
*/


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值