热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

19纯虚函数和抽象类

纯虚函数和抽象类纯虚函数和抽象类基本概念案例抽象类在多继承中的应用面向抽象类编程socket库c模型设计和实现C语言回调函数和函数指针1.基本概念2.案例#include<io

纯虚函数和抽象类

  • 纯虚函数和抽象类
    • 基本概念
    • 案例
    • 抽象类在多继承中的应用
    • 面向抽象类编程
    • socket库c模型设计和实现
    • C语言回调函数和函数指针

1.基本概念

2.案例


#include
using namespace std;

////面向抽象类编程(面向一套预先定义好的接口编程)

//解耦合 ....模块的划分


class Figure //抽象类
{
public:
//阅读一个统一的界面(接口),让子类使用,让子类必须去实现
virtual void getArea() = 0 ; //纯虚函数
protected:
private:
};

class Circle : public Figure
{
public:
Circle(int a, int b)
{
this->a = a;
this->b = b;
}
virtual void getArea()
{
cout<<"圆形的面积: "<<3.14*a*a<
}

private:
int a;
int b;
};

class Tri : public Figure
{
public:
Tri(int a, int b)
{
this->a = a;
this->b = b;
}
virtual void getArea()
{
cout<<"三角形的面积: "<2< }

private:
int a;
int b;
};


class Square : public Figure
{
public:
Square(int a, int b)
{
this->a = a;
this->b = b;
}
virtual void getArea()
{
cout<<"四边形的面积: "< }

private:
int a;
int b;
};


void objplay(Figure *base)
{
base->getArea(); //会发生多态
}


void main511()
{

//Figure f; //抽象类不能被实例化

Figure *base = NULL; //抽象类不能被实例化

Circle c1(10, 20);
Tri t1(20, 30);
Square s1(50, 60);

//面向抽象类编程(面向一套预先定义好的接口编程)

objplay(&c1);
objplay(&t1);
objplay(&s1);

//c1.getArea();

cout<<"hello..."< system("pause");
return ;
}

3.抽象类在多继承中的应用

C++中没有Java中的接口概念,抽象类可以模拟Java中的接口类。(接口和协议)

  • 工程上的多继承

    • 被实际开发经验抛弃的多继承
    • 工程开发中真正意义上的多继承是几乎不被使用的
    • 多重继承带来的代码复杂性远多于其带来的便利
    • 多重继承对代码维护性上的影响是灾难性的
    • 在设计方法上,任何多继承都可以用单继承代替
  • 多继承中的二义性和多继承不能解决的问题

  • C++没有接口只有多继承和抽象类
    • 绝大多数面向对象语言都不支持多继承
    • 绝大多数面向对象语言都支持接口的概念
    • C++中没有接口的概念
    • C++中可以使用纯虚函数实现接口
    • 接口类中只有函数原型定(纯虚函数)义,没有任何数据的定义。
class Interface
{
public:
virtual void func1() = 0;
virtual void func2(int i) = 0;
virtual void func3(int i) = 0;
};
  • 实际工程经验证明

    • 多重继承接口不会带来二义性和复杂性等问题
    • 多重继承可以通过精心设计用单继承和接口来代替
    • 接口类只是一个功能说明,而不是功能实现。
    • 子类需要根据功能说明定义功能实现。
  • 多继承的二义性


#include
using namespace std;

class B
{
public:
int b;
protected:
private:
};

class B1 : virtual public B
{
public:
int b1;
protected:
private:
};

class B2 : virtual public B
{
public:
int b2;
protected:
private:
};

class C : public B1, public B2
{
public:
int c;
protected:
private:
};



void main61()
{

C myc;
myc.c = 10;
myc.b = 100;//二义性 error C2385: 对“b”的访问不明确

cout<<"hello..."< system("pause");
return ;
}
  • 抽象类和多继承更配哦

#include
using namespace std;

class Interface1
{
public:
virtual int add(int a, int b) = 0;
virtual void print() = 0;
};

class Interface2
{
public:
virtual int mult(int a, int b) = 0;
virtual void print() = 0;
};

class Parent
{
public:
int getA()
{
a = 0;
return a;
}
protected:
private:
int a;
};

class Child : public Parent, public Interface1, public Interface2
{
public:
virtual int add(int a, int b)
{
cout<<"Child: add()已经执行\n";
return a + b;
}

virtual void print()
{
cout<<"Child: print()已经执行\n";
}

virtual int mult(int a, int b)
{
cout<<"Child: mult()已经执行\n";
return a*b;
}
protected:
private:
};

void main71()
{

Child c1;
c1.print();

Interface1 *it1 = &c1;
it1->add(1, 2);

Interface2 *it2 = &c1;
it2->mult(3, 6);


cout<<"hello..."< system("pause");
return ;
}

4.面向抽象类编程

  • 计算程序猿工资
#include 
using namespace std;

class programer{
public:
virtual int getSal() = 0;
};

class junior_programer :public programer
{
private:
char *name;
char *obj;
int sal;
public:
junior_programer(char *_name,char *_obj,int _sal)
{
name = _name;
obj = _obj;
sal = _sal;
}

virtual int getSal()
{
cout <" " <": " < return sal;
}
protected:
};

class mid_programer :public programer
{
private:
char *name;
char *obj;
int sal;
public:
mid_programer(char *_name, char *_obj, int _sal)
{
name = _name;
obj = _obj;
sal = _sal;
}

virtual int getSal()
{
cout <" " <": " < return sal;
}
protected:
};


class adv_programer :public programer
{
private:
char *name;
char *obj;
int sal;
public:
adv_programer(char *_name, char *_obj, int _sal)
{
name = _name;
obj = _obj;
sal = _sal;
}

virtual int getSal()
{
cout <" " <": " < return sal;
}
protected:
};


class arch_programer :public programer
{
private:
char *name;
char *obj;
int sal;
public:
arch_programer(char *_name, char *_obj, int _sal)
{
name = _name;
obj = _obj;
sal = _sal;
}

virtual int getSal()
{
cout <" " <": " < return sal;
}
protected:
};

void CalProgSal(programer *base)
{
base->getSal();
}

int main(void)
{
junior_programer jp("小王", "初级", 4000);

mid_programer mp("小张", "中级", 8600);
adv_programer ap("小李", "高级", 15000);

//系统扩展
arch_programer ar("高水平学员", "架构师", 24000);

CalProgSal(&jp);
CalProgSal(&mp);
CalProgSal(&ap);
CalProgSal(&ar);

cout<<"Hello!"< system("pause");
return 0;
}

5.socket库c++模型设计和实现

企业信息系统框架集成第三方产品

  • 案例背景:一般的企业信息系统都有成熟的框架。软件框架一般不发生变化,能自由的集成第三方厂商的产品。

  • 案例需求:请你在企业信息系统框架中集成第三方厂商的Socket通信产品和第三方厂商加密产品。

    • 第三方厂商的Socket通信产品:完成两点之间的通信;
    • 第三方厂商加密产品:完成数据发送时加密;数据解密时解密。

案例要求:
1)能支持多个厂商的Socket通信产品入围
2)能支持多个第三方厂商加密产品的入围
3)企业信息系统框架不轻易发生框架

需求实现

  • 思考1:企业信息系统框架、第三方产品如何分层
  • 思考2:企业信息系统框架,如何自由集成第三方产品
    (软件设计:模块要求松、接口要求紧)
  • 思考3:软件分成以后,开发企业信息系统框架的程序员,应该做什么?第三方产品入围应该做什么?

编码实现

分析有多少个类 CSocketProtocol CSckFactoryImp1 CSckFactoryImp2
CEncDesProtocol HwEncdes ciscoEncdes

1、 定义 CSocketProtocol 抽象类
2、 编写框架函数
3、 编写框架测试函数
4、 厂商1(CSckFactoryImp1)实现CSocketProtocol、厂商2(CSckFactoryImp1)实现CSocketProtoco
5、 抽象加密接口(CEncDesProtocol)、加密厂商1(CHwImp)、加密厂商2(CCiscoImp)),集成实现业务模型
6、 框架(c语言函数方式,框架函数;c++类方式,框架类)

几个重要的面向对象思想
* 继承-组合(强弱)
* 注入
* 控制反转 IOC
* MVC
* 面向对象思想扩展aop思想:aop思想是对继承编程思想的有力的补充

实现步骤

  1. 定义socket的抽象类和纯虚函数

#pragma once

#include
using namespace std;

class CSocketProtocol
{
public:
CSocketProtocol()
{
;
}

virtual ~CSocketProtocol() //虚析构函数的细节
{
;
}

//客户端初始化 获取handle上下
virtual int cltSocketInit( /*out*/) = 0;

//客户端发报文
virtual int cltSocketSend( unsigned char *buf /*in*/, int buflen /*in*/) = 0;

//客户端收报文
virtual int cltSocketRev( unsigned char *buf /*in*/, int *buflen /*in out*/) = 0;

//客户端释放资源
virtual int cltSocketDestory() = 0;

};

2.厂商一的功能实现

  • 类的头文件

#pragma once

#include
using namespace std;
#include "CSocketProtocol.h"

class CSckFactoryImp1 : public CSocketProtocol
{
public:

//客户端初始化 获取handle上下
virtual int cltSocketInit( /*out*/);

//客户端发报文
virtual int cltSocketSend( unsigned char *buf /*in*/, int buflen /*in*/);

//客户端收报文
virtual int cltSocketRev( unsigned char *buf /*in*/, int *buflen /*in out*/);

//客户端释放资源
virtual int cltSocketDestory();

private:
unsigned char *p;
int len ;
};
  • 类的实现文件

#include
using namespace std;

#include "CSckFactoryImp1.h"


//客户端初始化 获取handle上下
int CSckFactoryImp1::cltSocketInit( /*out*/)
{
p = NULL;
len = 0 ;
return 0;
}

//客户端发报文
int CSckFactoryImp1::cltSocketSend( unsigned char *buf /*in*/, int buflen /*in*/)
{
p = (unsigned char * ) malloc(sizeof(unsigned char) * buflen);
if (p == NULL)
{
return -1;
}
memcpy(p, buf, buflen);
len = buflen;
return 0;
}

//客户端收报文
int CSckFactoryImp1::cltSocketRev( unsigned char *buf /*in*/, int *buflen /*in out*/)
{
if (buf==NULL || buflen==NULL)
{
return -1;
}

*buflen = this->len ;
memcpy(buf, this->p, this->len);
return 0;
}

//客户端释放资源
int CSckFactoryImp1::cltSocketDestory()
{
if (p != NULL)
{
free(p);
p = NULL;
len = 0;
}
return 0;
}

3.厂商二的功能实现

  • 类的头文件

#pragma once

#include
using namespace std;
#include "CSocketProtocol.h"

class CSckFactoryImp2 : public CSocketProtocol
{
public:

//客户端初始化 获取handle上下
virtual int cltSocketInit( /*out*/);

//客户端发报文
virtual int cltSocketSend( unsigned char *buf /*in*/, int buflen /*in*/);

//客户端收报文
virtual int cltSocketRev( unsigned char *buf /*in*/, int *buflen /*in out*/);

//客户端释放资源
virtual int cltSocketDestory();

private:
unsigned char *p;
int len ;
};
  • 类的实现文件

#include
using namespace std;

#include "CSckFactoryImp2.h"


//客户端初始化 获取handle上下
int CSckFactoryImp2::cltSocketInit( /*out*/)
{
p = NULL;
len = 0 ;
return 0;
}

//客户端发报文
int CSckFactoryImp2::cltSocketSend( unsigned char *buf /*in*/, int buflen /*in*/)
{
p = (unsigned char * ) malloc(sizeof(unsigned char) * buflen);
if (p == NULL)
{
return -1;
}
memcpy(p, buf, buflen);
len = buflen;
return 0;
}

//客户端收报文
int CSckFactoryImp2::cltSocketRev( unsigned char *buf /*in*/, int *buflen /*in out*/)
{
if (buf==NULL || buflen==NULL)
{
return -1;
}

*buflen = this->len ;
memcpy(buf, this->p, this->len);
return 0;
}

//客户端释放资源
int CSckFactoryImp2::cltSocketDestory()
{
if (p != NULL)
{
free(p);
p = NULL;
len = 0;
}
return 0;
}

4.测试socket功能文件


#define _CRT_SECURE_NO_WARNINGS
#include
using namespace std;

#include "CSocketProtocol.h"
#include "CSckFactoryImp1.h"
#include "CSckFactoryImp2.h"

//面向抽象类编程,框架实现完毕
int SckSendAndRec01(CSocketProtocol *sp, unsigned char *in, int inlen, unsigned char *out, int *outlen)
{
int ret = 0;
ret = sp->cltSocketInit();
if (ret != 0)
{
goto End;
}

ret = sp->cltSocketSend(in, inlen);
if (ret != 0)
{
goto End;
}

ret = sp->cltSocketRev(out, outlen);
if (ret != 0)
{
goto End;
}

End:
ret = sp->cltSocketDestory();
return 0;
}


//写一个框架
int main011()
{
int ret = 0;
unsigned char in[4096];
int inlen;
unsigned char out[4096];
int outlen = 0;

strcpy((char *)in, "aadddddddddddaaaaaaaaaaa");
inlen = 9;


CSocketProtocol *sp = NULL;
//sp = new CSckFactoryImp1

sp = new CSckFactoryImp2; //

ret = SckSendAndRec01(sp, in, inlen, out, &outlen);
if (ret != 0)
{
printf("func SckSendAndRec() err:%d \n", ret);
return ret;
}
delete sp; //想通过父类指针 释放所有的子类对象的资源 ..

cout<<"hello..."< system("pause");
return ret;
}

5.加密协议抽象类的定义

#pragma once

class CEncDesProtocol
{
public:
CEncDesProtocol()
{

}
virtual ~CEncDesProtocol()
{

}
virtual int EncData(unsigned char *plain, int plainlen, unsigned char *cryptdata, int *cryptlen) = 0;
virtual int DecData(unsigned char *cryptdata, int cryptlen, unsigned char *plain, int *plainlen) = 0;

};

6.厂商一的加密功能实现

  • 类的头文件

#include
using namespace std;

#include "CEncDesProtocol.h"

class HwEncDec : public CEncDesProtocol
{
public:
virtual int EncData(unsigned char *plain, int plainlen, unsigned char *cryptdata, int *cryptlen);
virtual int DecData(unsigned char *cryptdata, int cryptlen, unsigned char *plain, int *plainlen);
};

*类的实现文件



#include
using namespace std;
#include "HwEncDec.h"
#include "des.h"


int HwEncDec::EncData(unsigned char *plain, int plainlen, unsigned char *cryptdata, int *cryptlen)
{
int ret = 0;
//用户使用的函数
ret = DesEnc(plain,plainlen, cryptdata, cryptlen);
if (ret != 0)
{
printf("func DesEnc() err:%d \n ", ret);
return ret;
}
return ret;
}

int HwEncDec::DecData(unsigned char *cryptdata, int cryptlen, unsigned char *plain, int *plainlen)
{
int ret = 0;
//用户使用函数des解密
ret = DesDec(cryptdata, cryptlen, plain, plainlen);
if (ret != 0)
{
printf("func DesDec() err:%d \n ", ret);
return ret;
}
return ret;
}

7.加密功能的测试文件


#define _CRT_SECURE_NO_WARNINGS
#include
using namespace std;

#include "CSocketProtocol.h"
#include "CSckFactoryImp1.h"
#include "CSckFactoryImp2.h"

#include "CEncDesProtocol.h"
#include "HwEncDec.h"

//面向抽象类编程,框架实现完毕
int SckSendAndRec(CSocketProtocol *sp, unsigned char *in, int inlen, unsigned char *out, int *outlen)
{
int ret = 0;
ret = sp->cltSocketInit();
if (ret != 0)
{
goto End;
}

ret = sp->cltSocketSend(in, inlen);
if (ret != 0)
{
goto End;
}

ret = sp->cltSocketRev(out, outlen);
if (ret != 0)
{
goto End;
}

End:
ret = sp->cltSocketDestory();
return 0;
}


//面向抽象类编程,框架实现完毕
//c函数
int SckSendAndRec_EncDec(CSocketProtocol *sp, CEncDesProtocol *ed, unsigned char *in, int inlen, unsigned char *out, int *outlen)
{
int ret = 0;
unsigned char data[4096];
int datalen = 0;

ret = sp->cltSocketInit();
if (ret != 0)
{
goto End;
}

ret = ed->EncData(in,inlen, data, &datalen);
if (ret != 0)
{
goto End;
}
ret = sp->cltSocketSend(data, datalen); //发送数据之前对数据加密 ..
if (ret != 0)
{
goto End;
}

ret = sp->cltSocketRev(data, &datalen); //收到的数据是密文,需要进行解密
if (ret != 0)
{
goto End;
}
ret = ed->DecData(data, datalen, out, outlen );
if (ret != 0)
{
goto End;
}

End:
ret = sp->cltSocketDestory();
return 0;
}

//写一个框架
int main022()
{
int ret = 0;
unsigned char in[4096];
int inlen;
unsigned char out[4096];
int outlen = 0;

strcpy((char *)in, "aadddddddddddaaaaaaaaaaa");
inlen = 9;


CSocketProtocol *sp = NULL;
CEncDesProtocol *ed = NULL;

//sp = new CSckFactoryImp1

sp = new CSckFactoryImp2; //
ed = new HwEncDec;

ret = SckSendAndRec_EncDec(sp, ed, in, inlen, out, &outlen);
if (ret != 0)
{
printf("func SckSendAndRec() err:%d \n", ret);
return ret;
}
delete sp; //想通过父类指针 释放所有的子类对象的资源 ..

cout<<"hello..."< system("pause");
return ret;
}

加解密的代码是des.h和des.c,可在前面“08文件操作”查看源代码。

8.将测试框架从函数形式升级为类的形式


#define _CRT_SECURE_NO_WARNINGS
#include
using namespace std;

#include "CSocketProtocol.h"
#include "CSckFactoryImp1.h"
#include "CSckFactoryImp2.h"

#include "CEncDesProtocol.h"
#include "HwEncDec.h"

//抽象类在多继承中的应用
/*
class MainOp : public CSocketProtocol, public CEncDesProtocol
{
public:
protected:
private:

};
*/


class MainOp
{
public:
MainOp()
{
this->sp = NULL;
this->ed = NULL;
}
MainOp(CSocketProtocol *sp, CEncDesProtocol *ed)
{
this->sp = sp;
this->ed = ed;
}
//

void setSp(CSocketProtocol *sp)
{
this->sp = sp;
}

void setEd(CEncDesProtocol *ed)
{
this->ed = ed;
}

public:
//面向抽象类编程,框架实现完毕
int SckSendAndRec_EncDec3(CSocketProtocol *sp, CEncDesProtocol *ed, unsigned char *in, int inlen, unsigned char *out, int *outlen)
{
int ret = 0;
unsigned char data[4096];
int datalen = 0;

ret = sp->cltSocketInit();
if (ret != 0)
{
goto End;
}

ret = ed->EncData(in,inlen, data, &datalen);
if (ret != 0)
{
goto End;
}
ret = sp->cltSocketSend(data, datalen); //发送数据之前对数据加密 ..
if (ret != 0)
{
goto End;
}

ret = sp->cltSocketRev(data, &datalen); //收到的数据是密文,需要进行解密
if (ret != 0)
{
goto End;
}
ret = ed->DecData(data, datalen, out, outlen );
if (ret != 0)
{
goto End;
}
End:
ret = sp->cltSocketDestory();
return 0;
}

int SckSendAndRec_EncDec3(unsigned char *in, int inlen, unsigned char *out, int *outlen)
{
int ret = 0;
unsigned char data[4096];
int datalen = 0;


ret = this->sp->cltSocketInit();
if (ret != 0)
{
goto End;
}

ret = this->ed->EncData(in,inlen, data, &datalen);
if (ret != 0)
{
goto End;
}
ret = this->sp->cltSocketSend(data, datalen); //发送数据之前对数据加密 ..
if (ret != 0)
{
goto End;
}

ret = sp->cltSocketRev(data, &datalen); //收到的数据是密文,需要进行解密
if (ret != 0)
{
goto End;
}
ret = ed->DecData(data, datalen, out, outlen );
if (ret != 0)
{
goto End;
}

End:
ret = sp->cltSocketDestory();
return 0;
}

private:
CSocketProtocol *sp;
CEncDesProtocol *ed;

};

//写一个框架
int main()
{
int ret = 0;
unsigned char in[4096];
int inlen;
unsigned char out[4096];
int outlen = 0;

strcpy((char *)in, "aadddddddddddaaaaaaaaaaa");
inlen = 9;


MainOp *myMainOp = new MainOp;

CSocketProtocol *sp = NULL;
CEncDesProtocol *ed = NULL;

//sp = new CSckFactoryImp1

sp = new CSckFactoryImp2; //
ed = new HwEncDec;

myMainOp->setSp(sp);
myMainOp->setEd(ed);

ret = myMainOp->SckSendAndRec_EncDec3(in, inlen, out, &outlen);
if (ret!= 0)
{
printf("myMainOp SckSendAndRec_EncDec3() err\n ", ret);
}

delete sp;
delete ed;
delete myMainOp;

cout<<"hello..."< system("pause");
return ret;
}

无非就是将之前的全局函数封装在一个测试用的类里面,然后该测试类拥有socket和加解密协议的基类对象作为该测试类的成员变量。

6.C语言回调函数和函数指针

结论:回调函数的本质:提前做了一个协议的约定(把函数的参数、函数返回值提前约定)

动态库升级为框架的编码实现

1、 动态库中定义协议,并完成任务的调用

typedef int (*EncData)(unsigned char *inData,int inDataLen,unsigned char *outData,int *outDataLen,void *Ref, int RefLen);
typedef int (*DecData)(unsigned char *inData,int inDataLen,unsigned char *outData,int *outDataLen,void *Ref, int RefLen);

2、 加密厂商完成协议函数的编写
3、 对接调试。
4、 动态库中可以缓存第三方函数的入口地址,也可以不缓存,两种实现方式。

案例总结

  • 回调函数:利用函数指针做函数参数,实现的一种调用机制,具体任务的实现者,可以不知道什么时候被调用。

  • 回调机制原理:

    • 当具体事件发生时,调用者通过函数指针调用具体函数
    • 回调机制将调用者和被调函数分开,两者互不依赖
    • 任务的实现 和 任务的调用 可以耦合 (提前进行接口的封装和设计)

推荐阅读
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • Spring常用注解(绝对经典),全靠这份Java知识点PDF大全
    本文介绍了Spring常用注解和注入bean的注解,包括@Bean、@Autowired、@Inject等,同时提供了一个Java知识点PDF大全的资源链接。其中详细介绍了ColorFactoryBean的使用,以及@Autowired和@Inject的区别和用法。此外,还提到了@Required属性的配置和使用。 ... [详细]
  • 本文介绍了ASP.NET Core MVC的入门及基础使用教程,根据微软的文档学习,建议阅读英文文档以便更好理解,微软的工具化使用方便且开发速度快。通过vs2017新建项目,可以创建一个基础的ASP.NET网站,也可以实现动态网站开发。ASP.NET MVC框架及其工具简化了开发过程,包括建立业务的数据模型和控制器等步骤。 ... [详细]
  • 2018年人工智能大数据的爆发,学Java还是Python?
    本文介绍了2018年人工智能大数据的爆发以及学习Java和Python的相关知识。在人工智能和大数据时代,Java和Python这两门编程语言都很优秀且火爆。选择学习哪门语言要根据个人兴趣爱好来决定。Python是一门拥有简洁语法的高级编程语言,容易上手。其特色之一是强制使用空白符作为语句缩进,使得新手可以快速上手。目前,Python在人工智能领域有着广泛的应用。如果对Java、Python或大数据感兴趣,欢迎加入qq群458345782。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 解决Cydia数据库错误:could not open file /var/lib/dpkg/status 的方法
    本文介绍了解决iOS系统中Cydia数据库错误的方法。通过使用苹果电脑上的Impactor工具和NewTerm软件,以及ifunbox工具和终端命令,可以解决该问题。具体步骤包括下载所需工具、连接手机到电脑、安装NewTerm、下载ifunbox并注册Dropbox账号、下载并解压lib.zip文件、将lib文件夹拖入Books文件夹中,并将lib文件夹拷贝到/var/目录下。以上方法适用于已经越狱且出现Cydia数据库错误的iPhone手机。 ... [详细]
  • springmvc学习笔记(十):控制器业务方法中通过注解实现封装Javabean接收表单提交的数据
    本文介绍了在springmvc学习笔记系列的第十篇中,控制器的业务方法中如何通过注解实现封装Javabean来接收表单提交的数据。同时还讨论了当有多个注册表单且字段完全相同时,如何将其交给同一个控制器处理。 ... [详细]
  • 在springmvc框架中,前台ajax调用方法,对图片批量下载,如何弹出提示保存位置选框?Controller方法 ... [详细]
  • 本文介绍了绕过WAF的XSS检测机制的方法,包括确定payload结构、测试和混淆。同时提出了一种构建XSS payload的方法,该payload与安全机制使用的正则表达式不匹配。通过清理用户输入、转义输出、使用文档对象模型(DOM)接收器和源、实施适当的跨域资源共享(CORS)策略和其他安全策略,可以有效阻止XSS漏洞。但是,WAF或自定义过滤器仍然被广泛使用来增加安全性。本文的方法可以绕过这种安全机制,构建与正则表达式不匹配的XSS payload。 ... [详细]
  • 恶意软件分析的最佳编程语言及其应用
    本文介绍了学习恶意软件分析和逆向工程领域时最适合的编程语言,并重点讨论了Python的优点。Python是一种解释型、多用途的语言,具有可读性高、可快速开发、易于学习的特点。作者分享了在本地恶意软件分析中使用Python的经验,包括快速复制恶意软件组件以更好地理解其工作。此外,作者还提到了Python的跨平台优势,使得在不同操作系统上运行代码变得更加方便。 ... [详细]
  • 本文介绍了互联网思维中的三个段子,涵盖了餐饮行业、淘品牌和创业企业的案例。通过这些案例,探讨了互联网思维的九大分类和十九条法则。其中包括雕爷牛腩餐厅的成功经验,三只松鼠淘品牌的包装策略以及一家创业企业的销售额增长情况。这些案例展示了互联网思维在不同领域的应用和成功之道。 ... [详细]
author-avatar
丰丰与鬼鬼_367
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有