Linux网络编程(七)-第三方库-Libevent01:安装Libevent【Ubuntu20.04】_安装 libevent-程序员宅基地

技术标签: ubuntu  # Linux/网络编程  

一、安装

验证是否已经安装Libevent

[weblogic@localhost opt]$ ls -al /usr/lib | grep libevent

1.下载

下载地址:
libevent

2.解压文件

[root@localhost opt]# tar -zxvf libevent-2.1.12-stable.tar.gz

3.创建lib文件夹

/usr/local/libevent

4.配置

检测安装环境,例如内存空间是否足够,生成makefile文件。

4.1 配置时不指定安装目录

[root@localhost libevent-2.1.8-stable]# ./configure
  • 将头文件安装在“/usr/local/include”中;

  • 将库文件放在“/usr/local/lib”中;

 4.2 配置时指定安装目录

可以指定具体路径,这样安装的时候,将统一安装到指定路径 例如:./configure --prefix=/usr/local/libevent:

  • 这样的好处是以后打包安装好的文件方便;
  • 不好的地方是由于安装的目录有可能不是系统头文件或库文件的目录,使用的时候需要增加gcc选项来包含头文件路径和库文件路径,以及需要解决动态库不能加载的问题;
[root@localhost libevent-2.1.8-stable]# ./configure -prefix=/usr/local/libevent

5.编译

生成.o文件和可执行文件

[root@localhost libevent-2.1.8-stable]# make

6.安装

将必要的资源安装到系统的指定目录

[root@localhost libevent-2.1.8-stable]# make install

二、libevent安装错误及解决方式

第1~3步就不用说了,常规准备步骤而已,问题出在第4步配置的时候,此时出现错误:

configure: error: openssl is a must but can not be found. You should add the directory containing ‘openssl.pc’ to the ‘PKG_CONFIG_PATH’ environment variable, or set ‘CFLAGS’ and ‘LDFLAGS’ directly for openssl, or use `–disable-openssl’ to disable support for openssl encryption

解决方式:ubuntu 平台安装 libssl-dev

libssl-dev安装步骤

  1. Update the package index:
    # sudo apt-get update

  2. Install libssl-dev deb package:
    # sudo apt-get install libssl-dev

三、头文件、库文件(libevent-2.1.12-stable.tar.gz)

libtool: finish: PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/sbin" ldconfig -n /usr/local/libevent/lib
----------------------------------------------------------------------
Libraries have been installed in:
   /usr/local/libevent/lib

If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the '-LLIBDIR'
flag during linking and do at least one of the following:
   - add LIBDIR to the 'LD_LIBRARY_PATH' environment variable
     during execution
   - add LIBDIR to the 'LD_RUN_PATH' environment variable
     during linking
   - use the '-Wl,-rpath -Wl,LIBDIR' linker flag
   - have your system administrator add LIBDIR to '/etc/ld.so.conf'

See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------
 /usr/bin/mkdir -p '/usr/local/libevent/include'
 /usr/bin/install -c -m 644 include/evdns.h include/event.h include/evhttp.h include/evrpc.h include/evutil.h '/usr/local/libevent/include'
 /usr/bin/mkdir -p '/usr/local/libevent/include/event2'
 /usr/bin/install -c -m 644 include/event2/buffer.h include/event2/buffer_compat.h include/event2/bufferevent.h include/event2/bufferevent_compat.h include/event2/bufferevent_struct.h include/event2/dns.h include/event2/dns_compat.h include/event2/dns_struct.h include/event2/event.h include/event2/event_compat.h include/event2/event_struct.h include/event2/http.h include/event2/http_compat.h include/event2/http_struct.h include/event2/keyvalq_struct.h include/event2/listener.h include/event2/rpc.h include/event2/rpc_compat.h include/event2/rpc_struct.h include/event2/tag.h include/event2/tag_compat.h include/event2/thread.h include/event2/util.h include/event2/visibility.h include/event2/bufferevent_ssl.h '/usr/local/libevent/include/event2'
 /usr/bin/mkdir -p '/usr/local/libevent/include/event2'
 /usr/bin/install -c -m 644 include/event2/event-config.h '/usr/local/libevent/include/event2'
 /usr/bin/mkdir -p '/usr/local/libevent/lib/pkgconfig'
 /usr/bin/install -c -m 644 libevent.pc libevent_core.pc libevent_extra.pc libevent_pthreads.pc libevent_openssl.pc '/usr/local/libevent/lib/pkgconfig'
make[2]: Leaving directory '/home/libevent-2.1.12-stable'
make[1]: Leaving directory '/home/libevent-2.1.12-stable'
root@iZm5e9phbzdxx0lysrv9t2Z:/home/libevent-2.1.12-stable# 

如果在配置阶段没有指定安装目录,则

  • 头文件目录”:/usr/local/include
  • ”的路径:/usr/local/lib

如果在配置阶段没有指定安装目录,例如:./configure --prefix=/usr/local/libevent,则

  • 头文件目录”:/usr/local/libevent/include
  • ”的路径:/usr/local/libevent/lib

添加动态链接库:

root@iZm5e9phbzdxx0lysrv9t2Z:/home/libevent-2.1.12-stable# export LD_LIBRARY_PATH=/usr/local/libevent/lib

三、测试是否安装成功

cd sample ,进入安装文件夹的samle目录,随便测试一个demo,这里测试helloworld.c。

/*
  This example program provides a trivial server program that listens for TCP
  connections on port 9995.  When they arrive, it writes a short message to
  each client connection, and closes each connection once it is flushed.

  Where possible, it exits cleanly in response to a SIGINT (ctrl-c).
*/


#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <signal.h>
#ifndef _WIN32
#include <netinet/in.h>
# ifdef _XOPEN_SOURCE_EXTENDED
#  include <arpa/inet.h>
# endif
#include <sys/socket.h>
#endif

#include <event2/bufferevent.h>
#include <event2/buffer.h>
#include <event2/listener.h>
#include <event2/util.h>
#include <event2/event.h>

static const char MESSAGE[] = "Hello, World!\n";

static const int PORT = 9995;

static void listener_cb(struct evconnlistener *, evutil_socket_t,
    struct sockaddr *, int socklen, void *);
static void conn_writecb(struct bufferevent *, void *);
static void conn_eventcb(struct bufferevent *, short, void *);
static void signal_cb(evutil_socket_t, short, void *);

int
main(int argc, char **argv)
{
	struct event_base *base;
	struct evconnlistener *listener;
	struct event *signal_event;

	struct sockaddr_in sin = {0};
#ifdef _WIN32
	WSADATA wsa_data;
	WSAStartup(0x0201, &wsa_data);
#endif

	base = event_base_new();
	if (!base) {
		fprintf(stderr, "Could not initialize libevent!\n");
		return 1;
	}

	sin.sin_family = AF_INET;
	sin.sin_port = htons(PORT);

	listener = evconnlistener_new_bind(base, listener_cb, (void *)base,
	    LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_FREE, -1,
	    (struct sockaddr*)&sin,
	    sizeof(sin));

	if (!listener) {
		fprintf(stderr, "Could not create a listener!\n");
		return 1;
	}

	signal_event = evsignal_new(base, SIGINT, signal_cb, (void *)base);

	if (!signal_event || event_add(signal_event, NULL)<0) {
		fprintf(stderr, "Could not create/add a signal event!\n");
		return 1;
	}

	event_base_dispatch(base);

	evconnlistener_free(listener);
	event_free(signal_event);
	event_base_free(base);

	printf("done\n");
	return 0;
}

static void
listener_cb(struct evconnlistener *listener, evutil_socket_t fd,
    struct sockaddr *sa, int socklen, void *user_data)
{
	struct event_base *base = user_data;
	struct bufferevent *bev;

	bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
	if (!bev) {
		fprintf(stderr, "Error constructing bufferevent!");
		event_base_loopbreak(base);
		return;
	}
	bufferevent_setcb(bev, NULL, conn_writecb, conn_eventcb, NULL);
	bufferevent_enable(bev, EV_WRITE);
	bufferevent_disable(bev, EV_READ);

	bufferevent_write(bev, MESSAGE, strlen(MESSAGE));
}

static void
conn_writecb(struct bufferevent *bev, void *user_data)
{
	struct evbuffer *output = bufferevent_get_output(bev);
	if (evbuffer_get_length(output) == 0) {
		printf("flushed answer\n");
		bufferevent_free(bev);
	}
}

static void
conn_eventcb(struct bufferevent *bev, short events, void *user_data)
{
	if (events & BEV_EVENT_EOF) {
		printf("Connection closed.\n");
	} else if (events & BEV_EVENT_ERROR) {
		printf("Got an error on the connection: %s\n",
		    strerror(errno));/*XXX win32*/
	}
	/* None of the other events can happen here, since we haven't enabled
	 * timeouts */
	bufferevent_free(bev);
}

static void
signal_cb(evutil_socket_t sig, short events, void *user_data)
{
	struct event_base *base = user_data;
	struct timeval delay = { 2, 0 };

	printf("Caught an interrupt signal; exiting cleanly in two seconds.\n");

	event_base_loopexit(base, &delay);
}

gcc helloworld.c -o helloworld //error

此时会报错,因为需要加入libevent库。即完整的命令为

1、如果在配置阶段没有指定安装目录

gcc helloworld.c -o helloworld -l event //去掉lib和后缀.so(动态库)就是库名.

2、如果在配置阶段指定了安装目录,例如:./configure --prefix=/usr/local/libevent,则

gcc helloworld.c -o helloworld -I /usr/local/libevent/include/ -L /usr/local/libevent/lib -l event //去掉lib和后缀.so(动态库)就是库名.

其中:

  • “-I” 参数后面的路径指定头文件路径(/usr/local/libevent/include);
  • “-L”参数后面的路径指定了库文件的路径(/usr/local/libevent/lib);

3、启动服务端

root@iZm5e9phbzdxx0lysrv9t2Z:/home/libevent-2.1.12-stable/sample# ls
dns-example        hello-world    http-connect.c               https_client-openssl_hostname_validation.o  le-proxy.c                     signal-test.o
dns-example.c      hello-world.c  http-connect.o               http-server                                 le_proxy-le-proxy.o            time-test
dns-example.o      hello-world.o  https-client                 http-server.c                               openssl_hostname_validation.c  time-test.c
event-read-fifo    hostcheck.c    https-client.c               http-server.o                               openssl_hostname_validation.h  time-test.o
event-read-fifo.c  hostcheck.h    https_client-hostcheck.o     include.am                                  signal-test
event-read-fifo.o  http-connect   https_client-https-client.o  le-proxy                                    signal-test.c
root@iZm5e9phbzdxx0lysrv9t2Z:/home/libevent-2.1.12-stable/sample# ./hello-world 

4、客户端测试

使用下面命令模拟客户端连接到服务端

nc 127.0.0.1 9995 //libevent默认端口

至此,libevent已经成功安装完成。

如果是使用Makelist,同样的也需要指定头文件目录和链接库目录,如下:

cmake_minimum_required(VERSION 3.12)
project(mytest)
 
set(CMAKE_CXX_STANDARD 14)
 
include_directories(/usr/local/libevent/include)   #指定头文件搜索路径
 
LINK_DIRECTORIES(/usr/local/libevent/lib)  #指定库文件搜索路径
 
add_executable(mytest main.cpp)
 
target_link_libraries(mytest libevent.a)  #链接库

四、安装后验证

简单的先编译一个文件 01_getmethods.c

//01_getmethods.c
#include <event.h>
#include <stdio.h>

int main()
{
    char ** methods = event_get_supported_methods();//获取libevent后端支持的方法
    int i =0;
    for(i = 0;methods[i] != NULL ;i++)
    {
        printf("%s\n",methods[i]);
    }
    return 0;
}

编译(其中的-levent表示链接第三方的库):

root@iZm5e9phbzdxx0lysrv9t2Z:/home# ll
total 1092
drwxr-xr-x  3 root root    4096 Oct 25 21:23 ./
drwxr-xr-x 20 root root    4096 Oct 25 20:27 ../
-rw-r--r--  1 root root     289 Oct 23 21:44 01_getmethods.c
drwxr-xr-x 12 1000 1000    4096 Oct 25 20:49 libevent-2.1.12-stable/
-rw-r--r--  1 root root 1100847 Oct 23 21:40 libevent-2.1.12-stable.tar.gz
root@iZm5e9phbzdxx0lysrv9t2Z:/home# gcc 01_getmethods.c -l event
01_getmethods.c: In function ‘main’:
01_getmethods.c:7:23: warning: initialization of ‘char **’ from incompatible pointer type ‘const char **’ [-Wincompatible-pointer-types]
    7 |     char ** methods = event_get_supported_methods();//获取libevent后端支持的方法
      |                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~
root@iZm5e9phbzdxx0lysrv9t2Z:/home# 

可以忽略该警告,代表编译完成。默认生成a.out执行文件。

执行:

root@iZm5e9phbzdxx0lysrv9t2Z:/home# ls
01_getmethods.c  a.out  libevent-2.1.12-stable  libevent-2.1.12-stable.tar.gz
root@iZm5e9phbzdxx0lysrv9t2Z:/home# ./a.out
epoll
poll
select
root@iZm5e9phbzdxx0lysrv9t2Z:/home# 

 同时也能看到libevent在当前主机上后端支持的多路IO方法。

#include <event.h>
#include <stdio.h>

int main()
{
    char ** methods = event_get_supported_methods();//获取libevent后端支持的方法
    int i =0;
    for(i = 0;methods[i] != NULL ;i++)
    {
        printf("%s\n",methods[i]);
    }
	struct event_base * base = event_base_new();
	
    printf("\nlibevent在当前主机上后端支持的多路IO方法:%s\n",event_base_get_method(base));
    return 0;
}
root@iZm5e9phbzdxx0lysrv9t2Z:/home# ls
01_getmethods.c  a.out  libevent-2.1.12-stable  libevent-2.1.12-stable.tar.gz
root@iZm5e9phbzdxx0lysrv9t2Z:/home# ./a.out
epoll
poll
select

libevent在当前主机上后端支持的多路IO方法:epoll
root@iZm5e9phbzdxx0lysrv9t2Z:/home# 

6、利用libevent创建一个简单的TCP服务器

/*
  This exmple program provides a trivial server program that listens for TCP
  connections on port 9995.  When they arrive, it writes a short message to
  each client connection, and closes each connection once it is flushed.

  Where possible, it exits cleanly in response to a SIGINT (ctrl-c).
*/


#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <signal.h>
#ifndef WIN32
#include <netinet/in.h>
# ifdef _XOPEN_SOURCE_EXTENDED
#  include <arpa/inet.h>
# endif
#include <sys/socket.h>
#endif

#include <event2/bufferevent.h>
#include <event2/buffer.h>
#include <event2/listener.h>
#include <event2/util.h>
#include <event2/event.h>

static const char MESSAGE[] = "Hello, World!\n";

static const int PORT = 9995;

static void conn_readcb(struct bufferevent *bev, void *user_data);
static void listener_cb(struct evconnlistener *, evutil_socket_t,
    struct sockaddr *, int socklen, void *);
static void conn_writecb(struct bufferevent *, void *);
static void conn_eventcb(struct bufferevent *, short, void *);
static void signal_cb(evutil_socket_t, short, void *);

int
main(int argc, char **argv)
{
	struct event_base *base;
	struct evconnlistener *listener;
	struct event *signal_event;

	struct sockaddr_in sin;
#ifdef WIN32
	WSADATA wsa_data;
	WSAStartup(0x0201, &wsa_data);
#endif

	base = event_base_new();//创建event_base根节点
	if (!base) {
		fprintf(stderr, "Could not initialize libevent!\n");
		return 1;
	}

	memset(&sin, 0, sizeof(sin));
	sin.sin_family = AF_INET;
	sin.sin_port = htons(PORT);

	//创建链接侦听器
	listener = evconnlistener_new_bind(base, listener_cb, (void *)base,
	    LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_FREE, -1,
	    (struct sockaddr*)&sin,
	    sizeof(sin));

	if (!listener) {
		fprintf(stderr, "Could not create a listener!\n");
		return 1;
	}
	//创建信触发的节点
	signal_event = evsignal_new(base, SIGINT, signal_cb, (void *)base);
	//将信号节点上树
	if (!signal_event || event_add(signal_event, NULL)<0) {
		fprintf(stderr, "Could not create/add a signal event!\n");
		return 1;
	}

	event_base_dispatch(base);//循环监听

	evconnlistener_free(listener);//释放链接侦听器
	event_free(signal_event);//释放信号节点
	event_base_free(base);//释放event_base根节点

	printf("done\n");
	return 0;
}

static void
listener_cb(struct evconnlistener *listener, evutil_socket_t fd,
    struct sockaddr *sa, int socklen, void *user_data)
{
	struct event_base *base = user_data;
	struct bufferevent *bev;

	//将fd上树
	//新建一个buffervent节点
	bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
	if (!bev) {
		fprintf(stderr, "Error constructing bufferevent!");
		event_base_loopbreak(base);
		return;
	}
	//设置回调
	bufferevent_setcb(bev, conn_readcb, conn_writecb, conn_eventcb, NULL);
	bufferevent_enable(bev, EV_WRITE | EV_READ);//设置写事件使能
	//bufferevent_disable(bev, EV_READ);//设置读事件非使能

	bufferevent_write(bev, MESSAGE, strlen(MESSAGE));//给cfd发送消息 helloworld
}
static void conn_readcb(struct bufferevent *bev, void *user_data)
{
	char buf[1500]="";
	int n = bufferevent_read(bev,buf,sizeof(buf));
	printf("%s\n",buf);
	bufferevent_write(bev, buf,n);//给cfd发送消息 



}

static void
conn_writecb(struct bufferevent *bev, void *user_data)
{
	struct evbuffer *output = bufferevent_get_output(bev);//获取缓冲区类型
	if (evbuffer_get_length(output) == 0) {
		
	//	printf("flushed answer\n");
	//	bufferevent_free(bev);//释放节点 自动关闭
	}
}

static void
conn_eventcb(struct bufferevent *bev, short events, void *user_data)
{
	if (events & BEV_EVENT_EOF) {
		printf("Connection closed.\n");
	} else if (events & BEV_EVENT_ERROR) {
		printf("Got an error on the connection: %s\n",
		    strerror(errno));/*XXX win32*/
	}
	/* None of the other events can happen here, since we haven't enabled
	 * timeouts */
	bufferevent_free(bev);
}

static void
signal_cb(evutil_socket_t sig, short events, void *user_data)
{
	struct event_base *base = user_data;
	struct timeval delay = { 2, 0 };

	printf("Caught an interrupt signal; exiting cleanly in two seconds.\n");

	event_base_loopexit(base, &delay);//退出循环监听
}

01libevent库的下载与安装并且测试是否安装成功_Mango酱的博客-程序员宅基地_libevent下载

 libssl-dev安装步骤_WangEason1985的博客-程序员宅基地_windows安装libssl-dev

1 Libevent官方 · libevent深入浅出

linux安装 Libevent安装和使用_东山富哥的博客-程序员宅基地_libevent安装

Libenent: configure: error: openssl is a must but can not be found._贪心的鬼的博客-程序员宅基地

linux无法编译libevent,一直报错,但是我有装openssl - SegmentFault 思否

记录关于libevent安装错误:configure: error: openssl is a must but can not be found. You should add the direct_youngchanlll的博客-程序员宅基地_安装libevent报错

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u013250861/article/details/127504509

智能推荐

Java面试题之:Java算法(十大常见排序算法及其扩展(详细讲解))_排序 选择题 java-程序员宅基地

文章浏览阅读2.6k次,点赞12次,收藏65次。Java面试题之:Java算法一、二分查找一、二分查找  二分查找又叫折半查找,要求待查找的序列有序。每次取中间位置的值与待查关键字比较,如果中间位置的值比待查关键字大,则在前半部分循环这个查找的过程,如果中间位置的值比待查关键字小,则在后半部分循环这个查找的过程。直到查找到了为止,否则序列中没有待查的关键字。..._排序 选择题 java

MySQL ERROR 3948 (42000) ERROR 2068 (HY000)_客户端mysql报3948-程序员宅基地

文章浏览阅读2.9k次,点赞4次,收藏17次。MySQL ERROR 3948 (42000) ERROR 2068 (HY000)需要导入到MySQL的数据如下:nameownerspeciessexbirthdeathFluffyHaroldcatf1993-02-04ClawsGwencatm1994-03-17BuffyHarolddogf1989-05-13FangBennydogm1990-08-27BowserDianedogm1979_客户端mysql报3948

十八、DPM模型案例(二)-程序员宅基地

文章浏览阅读1.1w次,点赞35次,收藏115次。关于DPM模型的设置,文章十六给出了一个简单的案例,文章十七介绍了DPM离散相界面的设置,本文通过一个案例来介绍DPM模型中Injection界面的设置,主要是颗粒粒径分布的设置。1 概念介绍DPM适用条件:DPM模型只适用于颗粒相体积分数小于10%,同时不考虑颗粒体积。不考虑颗粒和颗粒之间的相互作用力,但可以考虑颗粒和流体之间的相互作用。 ..._dpm模型

@Autowired注解在非controller中注入为null的问题-程序员宅基地

文章浏览阅读516次。在SpringMVC框架中,使用@Autowired注解注入Service或者Mapper接口,我们也知道,在controller层中注入service接口,在service层中注入其它的service接口或者mapper接口都是可以的,但是如果我们要在我们自己封装的Utils工具类中或者非controller普通类中使用@Autowired注解注入Service或者Mapper接口,直接注入是不...

2.3.3 交换机的RSTP技术_交换机rstp日志-程序员宅基地

文章浏览阅读253次。为了解决网络拓扑发生变化时网络收敛所需时间比较长的问题,可以采用快速生成树技术(RSTP)。RSTP的标准为IEEE 802.1w,它改进了STP,缩短了网络的收敛时间。RSTP的收敛速度最快可以缩短到1秒之内,在拓扑发生变化时能快速恢复网络的连通性。_交换机rstp日志

数据挖掘与机器学习的关系-程序员宅基地

文章浏览阅读1.2k次,点赞17次,收藏22次。1.背景介绍数据挖掘和机器学习是两个密切相关的领域,它们共同构成了大数据分析的核心内容。数据挖掘是从大量数据中发现有价值的模式、规律和知识的过程,而机器学习则是使计算机能够从数据中自主地学习出知识和模式,进而进行决策和预测。在本文中,我们将深入探讨数据挖掘与机器学习之间的关系,涉及到的核心概念、算法原理、具体操作步骤以及数学模型公式。同时,我们还将通过具体的代码实例进行详细解释,并分析未来..._机器学习与数据挖掘

随便推点

一个java的小型WEB项目一个页面(IDEA + 前后端代码)--一些基本配置 分为三篇(第1篇)_前后端小型项目-程序员宅基地

文章浏览阅读1.5k次,点赞3次,收藏9次。以jsp前端页面完成的一个小项目,准备工作:1.新建一个项目勾选web配置一些东西点进去找到后点击我们自己创建的lib目录,这里面保存的是我们的jar包,然后会把lib勾选,点击apply,点击OK,然后配置Tomcat,我的Tomcat服务器是8.5.4版本的我的jar包:一个小技巧,修改idea的背景图片:找到设置找到background image点进去就可以选择想要替换的背景..._前后端小型项目

webshell学习第一天-程序员宅基地

文章浏览阅读79次。webshell:通过网站端口对网站服务器的某种程度上的权限,也被称为网站的后门工具。webshell是web入侵的脚本攻击工具,它是一个asp或php木马后门。在入侵一个网站后,将这些asp或php木马后门放在网站服务器的web目录中,与正常的网页文件混在一起。然后用web的方式,通过这些asp或php木马后门控制网站服务器,进行一些上传下载文件 查看数据库 执行任意程序命令。再通过dos命令..._webshell学习

Qt 对话框常见类型-程序员宅基地

文章浏览阅读1.5k次,点赞33次,收藏15次。对话框是 GUI程序设计中不可或缺的组成部分,很多不能或者不适合放入主窗口的功能组件都必须放在对话框中。

你,能保护好你的钱吗?-程序员宅基地

文章浏览阅读190次。你,能保护好你的钱吗?(为更好理解这篇文章的内容,建议新人浏览前面几篇文章打个底,它会完善你对钱的认知)前面的文章里,提过一个事实,要变得有钱,我们就要攒资产!|资产|资产是指能够不断增值,为你提供被动收入的东西。比如房子、店铺,再比如你持有的优质公司的股票或者基金。每年都能给你带来增值收益,这些都属于资产。努力赚钱,把钱变成资产,再让资产复利形成更多的资产,为自己赚钱,也就是常说的睡后收入。过去几十年,对于多数人来说,增值效果最好的两...

Machine learning in action ch02 KNN笔记_from g\2022-2023\machinelearninginaction3x-master\-程序员宅基地

文章浏览阅读157次。1.KNN算法特点描述优点:精度高、对异常值不敏感、无数据输入假定。 缺点:计算复杂度高、空间复杂度高。 适用数据范围:数值型和标称型。2.KNN思想 对于一个给定的数据集,对于未知数据分类时,总是能够通过计算该点与其他数据点的距离(这个距离可以是欧式距离,也可以是闵氏距离,不加以限定),通过寻找该点的最邻近的K个数据点中的数量最多的数据点,来确定该数据点的分类。 实际上这是一种朴素贝叶斯的_from g\2022-2023\machinelearninginaction3x-master\ch02 import knn

android cts 认证测试-程序员宅基地

文章浏览阅读1.2k次。#7.0run cts -m CtsAccessibilityServiceTestCases -t android.accessibilityservice.cts.AccessibilityWindowQueryTest#testTraverseAllWindowsrun cts -m..._ctsbionictestcase

推荐文章

热门文章

相关标签