参考 https://blog.csdn.net/bitboss/article/details/62884694
面向过程&面向对象:
C是面向过程的语言,而C++是面向对象的语言。
1 面向过程是分析出 解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了;
2 面向对象是把 构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为;
3 面向对象编程的三大特点:封装、继承、多态
封装:就是隐藏对象的属性和实现细节,仅对外提供公共访问方式。
继承:使用现有类的所有功能,在无需重新编写原来的类的情况下对这些功能进行扩展。**继承的过程就是从一般到特殊的过程。
多态:将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作
动态管理内存的方法:
C使用malloc/free函数,C++除此之外还有new/delete关键字。(两者的区别是重要考点,见下一个知识点)
接下来就不得不谈到C中的struct和C++的类,C++的类是C所没有的,但是C中的struct是可以在C++中正常使用的,并且C++对struct进行了进一步的扩展,使struct在C++中可以和class一样当做类使用,而唯一和class不同的地方在于struct的成员默认访问修饰符是public,而class默认的是private;
C++支持函数重载,而C不支持函数重载,而C++支持重载的依仗就在于C++的名字修饰与C不同,例如在C++中函数int fun(int ,int)经过名字修饰之后变为 _fun_int_int ,而C是
_fun,一般是这样的,所以C++才会支持不同的参数调用不同的函数;
C++中有引用,而C没有;这样就不得不提一下引用和指针的区别(文后扩展_2);
C和C++动态管理内存的方法不一样,C是使用malloc/free函数,而C++除此之外还有new/delete关键字;(关于malooc/free与new/delete的不同又可以说一大堆,最后的扩展_1部分列出十大区别);
接下来就不得不谈到C中的struct和C++的类,C++的类是C所没有的,但是C中的struct是可以在C++中正常使用的,并且C++对struct进行了进一步的扩展,使struct在C++中可以和class一样当做类使用,而唯一和class不同的地方在于struct的成员默认访问修饰符是public,而class默认的是private;
C++支持函数重载,而C不支持函数重载,而C++支持重载的依仗就在于C++的名字修饰与C不同,例如在C++中函数int fun(int ,int)经过名字修饰之后变为 _fun_int_int ,而C是
_fun,一般是这样的,所以C++才会支持不同的参数调用不同的函数;
C++中有引用,而C没有;这样就不得不提一下引用和指针的区别(文后扩展_2);
实现多态的二种方式:覆盖和重载。
虚函数:
https://blog.csdn.net/IOT_SHUN/article/details/79674293
虚函数是指一个类中你希望重载的成员函数 ,当你用一个 基类指针或引用 指向一个继承类对象的时候,调用一个虚函数时, 实际调用的是继承类的版本。
每个类用了一个虚表,每个类的对象用了一个虚指针。
虚继承:(可以解决菱形继承的问题)
https://blog.csdn.net/tounaobun/article/details/8443228
参考:https://blog.csdn.net/tyhj_sf/article/details/53969072
派生类的虚函数
class Animal// 基类
{
public:
virtual void getWeight(){cout << "1" << endl;}
};
class Tiger:public Animal
{
public:
virtual void getWeight(){cout << "2" << endl;}
};
int main( )
{
Tiger g ;
g.getWeight();
return 0;
}
// 输出为2,即调用派生类的虚函数
参考 https://blog.csdn.net/paul123456789io/article/details/54945475
C++中数组作为形参传递给函数时把数组视为指针,并没有将数组的长度信息传递给函数,因而在函数中稍有不慎就会造成数组内存的越界访问。下面有几个解决办法:
void func(int arr[], size_t size)
{
for (size_t i = 0; i < size; i++)
// operation
}
vector<int>::iterator it;
void func(int *begin, int *end)
{
for (int *pt = begin; pt != end; pt++)
// operation
}
void func(char *cstr)
{
for (int i = 0; '\0' != cstr[i]; i++)
// operation
}
void func(int (&arr)[10])
{
for (int i = 0; i < 10; i++)
// operation
}
int main()
{
int size = 20;
int iarray[size] = {0};
func(iarray); // error
return 0;
}
题目:给一个文件,有几行数据,第一列是用户名,第二列是用户密码,第三列是ip地址,第四列是端口。让写一个脚本,根据用户名和密码一次登录到对应ip机器上去,然后还要发送文件等一系列操作。
答:面试官提示说python语言下封装了一个库,名字忘记了,回来查了一些是 paramiko,应该没有错。具体方法:
参考:https://blog.csdn.net/songfreeman/article/details/50920767
import paramiko
# h先建立一个sshclient对象
ssh = paramiko.SSHClient()
# h允许将信任的主机自动加入到host_all列表中,这一步必须在connet之前
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# h调用connet方法连接服务器
ssh.connet(hostname = '192.168.2.129", port = 22, username = 'super', password = 'super')
# h执行命令
stdin, stdout, stderr = ssh.exec_command('df -hl')
# h如果有结果放到stdout中,如果有错误放到stderr中
print(stdout.read().decode())
# h关闭连接
ssh.close()
# h先实例化一个transport对象
trans = paramiko.Transport(('192,168.2.129, 22))
# h建立连接
tran.connet(username = 'super', password = 'super')
# h将sshclient对象的transport指定为上面的trans
ssh = paramiko.SSHClient()
ssh._transport = trans
# h执行命令,和传统方法一样
stdin, stdout, stderr = ssh.exec_command('df -hl')
print(stdout.read().decode())
# h关闭连接
trans.close()
# h指定本地的RSA私钥文件,如果建立密钥对时设置有米娜,password为密码,不需要的时候password缺省即可;
pkey = paramiko.RSAKey.from_private_key_file('/home/super/.ssh/id_rsa', password = '12345')
# h建立连接
ssh = paramiko.SSHClient()
ssh.connet(hostname = '192.168.2.129',
port = 22,
username = 'super',
pkey = pkey)
# h执行命令
stdin, stdout, stderr(exec_command('df -hl))
print(stdout.read().decode())
# h关闭连接
ssh.close()
# h实例化一个trans对象
trans = paramiko.Transport(('192.168.2.190', 22))
# h建立连接
trans.connet(username = 'super', password = 'super')
# h实例化一个sftp对象,指定连接的通道
sftp = paramiko.SFTPClient.from_transport(trans)
# h发送文件
sftp.put(localpath = '/home/super/1.txt', remotepath = 'tmp/22.txt')
# h下载文件
sftp.get(remotepath, localpath)
trans.close()
题目:对于一个网站,能想到的测试用例,安全测试方面怎么考虑?
答:参考 http://www.cnblogs.com/TankXiao/p/3154017.html
首先,查找需求说明、网站设计等相关文档,分析测试需求。
登录成功后生成的 Cookie是否为httponly(否则很容易被脚本盗取)
(cookie中设置了HttpOnly属性,那么通过js脚本将无法读取到cookie信息,这样能有效的防止XSS攻击)
用户名和密码是否为加密 发送给Web服务器;
用户名和密码的验证应该是 服务器端验证,而不能是客户端用JavaScript验证;
用户名和密码的输入框,屏蔽SQL注入攻击;
(部分程序员在编写代码的时候,没有对用户输入数据的合法性进行判断,使用户可以提交一段数据库查询代码,根据程序返回的结果,获得某些他想得知的数据即SQL注入。
防御办法:
步骤一,严格检查输入变量的类型和格式;
步骤二,过滤和转义特殊字符;
步骤三,利用mysql的预编译机制:把sql语句的模板(变量采用占位符进行占位)发送给mysql服务器,mysql服务器对sql语句的模板进行编译,编译之后根据语句的优化分析对相应的索引进行优化,在最终绑定参数时把相应的参数传送给mysql服务器,直接进行执行,节省了sql查询时间,以及mysql服务器的资源,达到一次编译、多次执行的目的,除此之外,还可以防止SQL注入。具体是怎样防止SQL注入的呢?实际上当将绑定的参数传到mysql服务器,mysql服务器对参数进行编译,即填充到相应的占位符的过程中,做了转义操作。
用户名和密码的输入框,应该禁止输入脚本,防止XSS攻击;
(XSS是一种在web应用中的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中。
防御办法:
步骤1、对所有用户提交内容进行可靠的输入验证,包括对URL、查询关键字、HTTP头、POST数据等,仅接受指定长度范围内、采用适当格式、采用所预期的字符的内容提交,对其他的一律过滤。
步骤2、实现Session标记(session tokens)、CAPTCHA系统或者HTTP引用头检查,以防功能被第三方网站所执行。
步骤3、确认接收的的内容被妥善的规范化,仅包含最小的、安全的Tag(没有javascript),去掉任何对远程内容的引用(尤其是样式表和javascript),使用HTTP only的cookie。)
错误登录的次数限制,防止暴力破解
1、cookie数据存放在客户的浏览器上,session数据放在服务器上。
2、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗
考虑到安全应当使用session。
3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能
考虑到减轻服务器性能方面,应当使用COOKIE。
4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
5、所以个人建议:
将登陆信息等重要信息存放为SESSION
其他信息如果需要保留,可以放在COOKIE中
单元测试是白盒测试,就是针仅仅针对代码来说,不涉及任何工具等等。面试官问道这个问题应该是想问白盒测试的方法。参考:
https://blog.csdn.net/write6/article/details/78702977
从语句覆盖、判定覆盖、判定条件覆盖、条件组合覆盖、路径覆盖,测试用例的覆盖强度一次增强。
1、能整除4且不能整除100
2、能整除400
因为 HTTP 是明文传输的,在传输过程中,在一些路由节点中很容易被别人捕获,识别你的内容,再在传输的数据中添加一些广告代码,最后数据传到你的手机里就显示成这样了,很不爽。而 HTTPS 能很有效的解决这个现象,我们在数据传输之前,双方商量一个加密的密码,然后俩个人之间的通讯都用这个密码进行加密,即便在路由节点被第三方捕获,它没有密码,看到的也是一堆乱码,没有办法在合适的位置插入广告代码,
参考 https://www.cnblogs.com/dsj2016/p/5500204.html
提示:方式1,可以通过找规律的方式,比如1到10,1到100,1到1000分别多少个7;方式2,对每一位单独考虑,共四位,每一位出现7的概率是1/10;方式3,每次固定一位,变换其他位,比如固定千位为7,那么就有1000个,依次计算,得到最终结果4000
拥塞控制大概是指对于整个网络的拥堵情况来判断,比较全面一点。流量控制是根据接收方的窗口限制发送方的发送窗口。
慢开始:
快恢复: