Skip to content

Commit

Permalink
Update file
Browse files Browse the repository at this point in the history
  • Loading branch information
HarleysZhang committed Oct 23, 2021
1 parent ae2ad90 commit cf3ae6c
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 8 deletions.
22 changes: 21 additions & 1 deletion 2-programming_language/c-cpp/C-CPP 编程基础.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
- [STL 库描述](#stl-库描述)
- [内存中堆和栈的区别](#内存中堆和栈的区别)
- [堆栈溢出一般是由什么原因导致的?](#堆栈溢出一般是由什么原因导致的)
- [sizeof 的作用](#sizeof-的作用)
- [C++ 面向对象特点](#c-面向对象特点)
Expand All @@ -10,13 +12,25 @@
- [C++ 中的 new delete 和 C 语言中的 malloc free 有什么区别](#c-中的-new-delete-和-c-语言中的-malloc-free-有什么区别)
- [new、delete、malloc、free 区别](#newdeletemallocfree-区别)
- [static 关键字作用](#static-关键字作用)
- [类的 static 变量在什么时候初始化?函数的 static 变量在什么时候初始化?](#类的-static-变量在什么时候初始化函数的-static-变量在什么时候初始化)
- [C++ 变量作用域](#c-变量作用域)
- [C++ 指针和引用的区别](#c-指针和引用的区别)
- [C++ 中析构函数的作用](#c-中析构函数的作用)
- [C++ 静态函数和虚函数的区别](#c-静态函数和虚函数的区别)
- [++i 和 i++ 区别](#i-和-i-区别)
- [const 关键字作用](#const-关键字作用)

## STL 库描述

`STL` 库包括:容器、算法以及融合两者的迭代器。

容器分为**顺序容器**和关联容器。顺序容器比如 `vector` 是一个动态分配存储空间的容器。区别于 `C++` 中的 `array``array` 分配的空间是静态的,分配之后不能被改变,而 `vector` 会自动重分配(扩展)空间。

## 内存中堆和栈的区别

- 栈内存:由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈,都是先进后出。栈使用的是一级缓存,他们通常都是被调用时处于存储空间中,调用完毕立即释放**
- 堆内存:一般由程序员分配释放,若程序员不释放,程序结束时可能由 OS 回收。堆是存放在二级缓存中,生命周期由虚拟机的垃圾回收算法来决定(并不是一旦成为孤儿对象就能被回收)。所以调用这些对象的速度要相对来得低一些。

## 堆栈溢出一般是由什么原因导致的?

没有垃圾回收资源。
Expand All @@ -31,7 +45,8 @@

## 多态的理解

`C++` 的多态性具体体现在运行和编译两个方面:在程序运行时的多态性通过继承和虚函数来体现;在程序编译时多态性体现在函数和运算符的重载上;
- 同一函数作用于不同的对象,会对应不同的实现,从而产生不同的执行结果。在运行时,可以通过**指向基类的指针或引用**,来调用实现派生类中的方法。
- `C++` 的多态性具体体现在运行和编译两个方面:在程序运行时的多态性通过继承和虚函数来体现;在程序编译时多态性体现在函数和运算符的重载上;

## 虚函数的理解

Expand Down Expand Up @@ -175,6 +190,10 @@ Base2 destory
+ **类的静态成员**:在类中,静态成员可以实现多个对象之间的数据共享,即静态成员是类的所有对象中共享的成员,而不是某个对象成员。并且使用静态数据成员不会破坏隐藏的原则,保证了数据的安全性。
+ **类的静态函数**:把函数成员声明为静态的,就可以把函数与类的任何特定对象独立开来。`静态成员函数即使在类对象不存在的情况下也能被调用`,静态函数只要使用类名加范围解析运算符 `::` 就可以访问(`<类名>::<静态成员函数名>(<参数表>)`)

## 类的 static 变量在什么时候初始化?函数的 static 变量在什么时候初始化?

类的静态成员变量在类实例化之前就已经存在了,并且分配了内存。函数的`static` 变量在执行此函数时进行初始化。

## C++ 变量作用域

作用域即是程序的一个区域,在程序中变量的作用域一般有三个地方:
Expand All @@ -189,6 +208,7 @@ Base2 destory
+ 不存在空引用, 引用必须链接到一块合法的内存地址;
+ 一旦引用被初始化为一个对象,就不能指向另一个对象。指针可以在任何时候指向任何一个对象;
+ 引用必须在创建时被初始化。指针可以在任何时间初始化。
+ 指针可以有多级,但是引用只能是一级(`int **p`;合法 而 `int &&a` 是不合法的)。

## C++ 中析构函数的作用

Expand Down
32 changes: 32 additions & 0 deletions 3-data_structure-algorithm/binary_search/二分查找.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,35 @@ int BinarySearch(int a[], int n, int value){
二分查找的核心思想理解起来非常简单,有点类似分治思想。即每次都通过跟区间中的中间元素对比,将待查找的区间缩小为一半,直到找到要查找的元素,或者区间被缩小为 `0`。其代码有三个容易出错的地方:循环退出条件、`mid` 的取值,`low``high` 的更新。

凡是用二分查找能解决的,绝大部分我们更倾向于用散列表或者二叉查找树。即便是二分查找在内存使用上更节省,但是毕竟内存如此紧缺的情况并不多。二分查找**更适合用在“近似”查找问题**,在这类问题上,二分查找的优势更加明显。

### 四,二分查找算法解题模板

二分查找模板1

将区间 [l, r] 划分成 [l, mid][mid+1, r] 时,其更新操作是 r = mid 或 l = mid + 1;,计算 mid 时不需要加1.

```cpp
int bsearch_1(int l, int r){
while (l < r){
int mid = (l + r) >> 1; // (l + r)/2 向下取整
if(check(mid)) r = mid;
else l = mid + 1;
}
return l;
}
```
二分查找模板2
将区间 [l, r] 划分成 [l, mid-1] 和 [mid, r] 时,其更新操作是 r = mid - 1 或 l = mid;,为了防止死循环,计算 mid 时需要加1.
```cpp
int bsearch_1(int l, int r){
while (l < r){
int mid = (l + r + 1) >> 1; // (l + r)/2 向上取整
if(check(mid)) l = mid;
else r = mid - 1;
}
return l;
}
```
3 changes: 1 addition & 2 deletions 3-data_structure-algorithm/剑指offer题解.md
Original file line number Diff line number Diff line change
Expand Up @@ -1202,7 +1202,7 @@ caseout += FirstAppearingOnce()
如果当前字符流没有存在出现一次的字符,返回 `#` 字符。
**解题思路:**
**解题思路**(参考牛客网题解):
1. 对于“重复问题”,惯性思维应该想到哈希或者set。对于“字符串问题”,大多会用到哈希。因此一结合,应该可以想到,判断一个字符是否重复,可以选择用哈希,在 `c++` 中,可以选择用 `unordered_map<char, int>`
2. 对于字符流,源源不断的往池子中添加字符,然后还要返回第一个满足什么条件的字符,显然设计到了“顺序”,也就是先来的先服务,这种先进先出的数据结构不就是队列嘛。因此,这里可以用队列 `queue`
Expand All @@ -1213,7 +1213,6 @@ caseout += FirstAppearingOnce()
2. 对于 `void Insert(char ch)` 字符插入函数的实现,当且仅当 `ch` 是第一次出现,则将 `ch` 添加到队列中;同时,不管 `ch` 是不是第一次出现,都需要在 `mp` 中更新一下字符的出现次数,方便后续判断字符是否是第一次出现。
3. 对于 `char FirstAppearingOnce()` 函数,通过哈希表 `mp` 判断队列 `q` 的头部元素的出现次数,如果是 `1` 则返回对应字符 `ch`;如果不是 `1`,则队列 `pop()` 弹出头部元素继续判断下一个字符。
```cpp
class Solution
{
Expand Down
1 change: 1 addition & 0 deletions 5-deep_learning/1-深度学习基础.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#### 1.1,余弦相似度

通过对两个文本分词,`TF-IDF` 算法向量化,利用空间中两个向量的夹角,来判断这两个向量的相似程度:(`计算夹角的余弦,取值 0-1`)

+ 当两个向量夹角越大,距离越远,最大距离就是两个向量夹角 180°;
+ 夹角越小,距离越近,最小距离就是两个向量夹角 0°,完全重合。
+ 夹角越小相似度越高,但由于有可能一个文章的特征向量词特别多导致整个向量维度很高,使得计算的代价太大不适合大数据量的计算。
Expand Down
25 changes: 20 additions & 5 deletions 8-interview_summary/社招面经.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,26 @@ b_h = p_{h}e^{t_h} $$
2,普通卷积层、分组卷积、深度可分离卷积的 FLOPs 计算公式。
3,普通卷积层、分组卷积、深度可分离卷积的 MAC 计算公式。
4,详细描述下你知道的轻量级网络:MobileNetV1、ShuffleNetv1-v2。
5,L2 正则化(权重衰减)原理,为什么它能防止模型过拟合?系数 $\lambda $ 如何取值?
6,L1 正则化原理,系数 $\lambda $ 如何取值?
7,Pytorch 的 conv2d 函数的参数有哪些?以及模型输出大小计算公式,并解释为什么公式是这样。
8,Pytorch 的 DataLoader 原理。
9,普通卷积过程描述下。

5,何谓正则化?

通过给模型的代价函数(损失函数)添加被称为正则化项(`regularizer`)的惩罚,这称为将模型(学习函数为 $f(x; θ)$)正则化。正则化是一种思想(策略),**给代价函数添加惩罚**只是其中一种方法。

6,`L2` 正则化(权重衰减)原理,为什么它能防止模型过拟合?系数 $\lambda $ 如何取值?

`L2` 正则化(权重衰减)是另外一种正则化技术,通过加入的正则项对参数数值进行衰减,得到更小的权值。**当 $\lambda$ 较大时,会使得一些权重几乎衰减到零,相当于去掉了这一项特征,类似于减少特征维度**。假设待正则的网络参数为 $w$,`L2` 正则化为各个元素平方和的 $1/2$ 次方,其形式为:

$$L2 = \frac{1}{2}\lambda ||w||^{2}_{2}$$

实际使用时,一般将正则项加入目标函数,通过整体目标函数的误差反向传播,从而实现正则化影响和指导模型训练的目的。

7,L1 正则化原理,系数 $\lambda $ 如何取值?

L1 范数: 为向量 x 各个元素绝对值之和。`L1` 正则化可以使权值参数稀疏,方便特征提取。

8,Pytorch 的 conv2d 函数的参数有哪些?以及模型输出大小计算公式,并解释为什么公式是这样。
9,Pytorch 的 DataLoader 原理。
10,普通卷积过程描述下。

### 2.3,模型部署相关

Expand Down

0 comments on commit cf3ae6c

Please sign in to comment.