从零Makefile落地算法大项目,完整案例教程

从零Makefile落地算法大项目,完整案例教程

转自:从零Makefile落地算法大项目,完整案例教程

作者:手写AI

前言

  1. 在这里,你能学到基于Makefile的正式大项目的使用方式和考虑,相信我,其实可以很简单。而且写一次到处用,新项目复制即可用
  2. 本教程带你一步步完成,ppt很长是因为细,内容不多
  3. 相比cmake,Makefile更加轻量简洁,侵入性低,掌控力强。语法更少更简单
  4. 使用Makefile你可以进行更细粒度的掌控,虽然cmake简化了这些,但是对于大型项目,细节的掌控是必须的
  5. 对于算法落地,我们会面临各种库包,理清楚非常有利于降低问题的发生
  6. 这也是高级算法工程师系列课程的基础,贯穿后续课程的存在。后续会有CUDA编程、TensorRT、基于C++实现BP、流媒体等等

准备环境

  1. VSCode (Visual Studio Code),作为IDE
  2. 安装VSCode的C++插件
  3. 准备Linux系统(Ubuntu),推荐使用VSCode的SSH插件远程连接服务器(另一个电脑)进行开发。本地电脑可以是windows/mac
  4. 熟悉C++的基本语法,我们主讲Makefile但是会有C++编码部分(不多)

目录

  1. g++指令介绍
  2. C++的编译链接过程、编译时、运行时介绍
  3. Makefile基本语法,依赖关系定义
  4. 基于Makefile的标准工程结构
  5. 基于Makefile实现的完整功能项目
  6. 分析程序依赖项,readelf、ldd
  7. 配置C++的调试功能
  8. 头文件修改cpp自动编译的处理方法

GITHUB项目地址(PPT、代码均在这里)

https://github.com/shouxieai/makefile_tutorial_project

1. g++指令介绍

1.1 g++/gcc是什么,有什么区别

  • g++和gcc都是gnu推出的cpp编译器,时代不同
  • g++和gcc都可以进行cpp编译
  • g++和gcc一样,都属于driver,即驱动编译,他会调用cclplus/ccl/ld/as等指令实现编译链接等工作,他们俩只是默认选项上的处理不同
  • 这里我们采用g++而不是gcc
  • g++ 等价于 gcc -xc++ -lstdc++ -shared-libgcc
  • 参考:知乎问题

1.2 g++的编译过程

4种情况,注意指令的大小写很重要

  • 预处理:g++ -E main.cpp -o main.i
  • 汇编:g++ -S main.i -o main.s
  • 编译:g++ -c main.s -o main.o
  • 链接:g++ main.o -o main.bin

g++可以允许跨过中间步骤,例如:

  • g++ -S main.cpp -o main.s
  • g++ main.s -o main.bin
  • g++ main.cpp -o main.bin
  • 结果是等价的

比较常用的是编译-链接:

  • 编译,代码编译到二进制:g++ -c main.cpp -o main.o
  • 链接,多个二进制链接成执行程序:g++ main.o -o main.bin

预处理指令效果:g++ -E main.cpp -o main.i

在这里插入图片描述

汇编指令效果:g++ -S main.i -o main.s

在这里插入图片描述

编译指令效果:g++ -c main.s -o main.o

在这里插入图片描述

链接指令效果:g++ main.o -o out.bin

在这里插入图片描述

2. C++编译链接 / 编译时和运行时

2.1 C++编译链接流程图

在这里插入图片描述

2.2 C++的声明和实现

在这里插入图片描述

2.3 C++的编译过程-案例

2.3.1 代码结构,main.cpp和test.cpp

在这里插入图片描述

2.3.2 main.cpp的汇编代码

在这里插入图片描述

2.3.3 test.cpp的汇编代码

在这里插入图片描述

2.3.4 两者汇编代码对比

  1. main.s里面没有add函数的具体实现,只有call add操作
  2. add的具体实现在test.s里面

在这里插入图片描述

2.3.5 带有命名空间时的名字编码

在这里插入图片描述

2.4 C++编译过程

在这里插入图片描述

2.5 C++链接过程

在这里插入图片描述

2.6 C++实际的链接过程

在这里插入图片描述

2.7 若add函数在动态库,lib3rd.so中时

在这里插入图片描述

2.8 若add函数在静态库,libpkg.a中时

在这里插入图片描述

2.9 编译链接成一个完整程序的过程

在这里插入图片描述

2.10 C++链接时,查找so文件、a文件方式的方式

g++ -lpkg,这里是小写的L

在这里插入图片描述

2.11 C++运行时,查找so文件的方式

在这里插入图片描述

2.12 C++编译时,头文件的查找方式

  • 这里是大写的i,-lfolder

在这里插入图片描述

3. Makefile基础

3.1 Makefile基础-解决的问题是什么

  • 编译代码是一个很耗时的事情尤其是代码量大、CPU差时(边缘端)
  • 参考官方文档,查看更多定义:http://www.gnu.org/software/make/manual/make.html

在这里插入图片描述

3.2 Makefile基础-代码域

在这里插入图片描述

3.3 Makefile基础-语法

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 生成项可以没有依赖项,那么如果该生成项文件不存在,command将永远执行

3.2 依赖关系定义

在这里插入图片描述

  • 第一次执行make a.o时,由于a.o不存在,执行了command
  • 第二次执行make a.o时,由于a.cpp时间没有比a.o新,打印a.o is up to date,不需要编译
  • 生成项和依赖项,从来都是当成文件来看待的

3.3 编译和链接结合起来

在这里插入图片描述

  • 定义好依赖后make out.bin后,会自动查找依赖关系,并自动按照顺序执行command
  • 这是makefile为我们解决的核心问题,剩下就是如何玩的更方便罢了。比如自动检索a.cpp、b.cpp,自动定义a.o依赖a.cpp。等等

3.4 总结

  1. 变量赋值有4种方式var = 123, var := 123, var ?= 123, var += 123。其中var := 123常用,var += 123常用
  2. 取变量值有两种,$(var)${var}。小括号大括号均可以
  3. 数据类型只有字符串和字符串数组,空格隔开表示多个元素
  4. $(function arguments)是调用make内置函数的方法,具体可以参考官方文档的函数大全。但是常用的其实只有少数两个即可
  5. 依赖关系定义中,如果代码修改时间比生成的更新/生成不存在时,command会执行。否则只会打印main.o is up to date。这是makefile解决的核心问题
  6. 依赖关系可以链式的定义,即b依赖a,c依赖b,而make会自动链式的查找并根据时间执行command
  7. command是shell指令,可以使用$(var)来将变量用到其中。前面加@表示执行执行时不打印原指令内容。否则默认打印指令后再执行指令
  8. make不写具体生成名称,则会选择依赖关系中的第一项生成

还有问题

在这里插入图片描述

4. 基于Makefile的标准工程结构

4.1 Makefile工程结构

在这里插入图片描述

  • 一个标准工程,我们做如下定义:
  • 具有src目录,存放我们的代码,可能有多级,例如main.cpp,foo/foo.cpp等
  • 具有workspace目录,存放我们编译后的可执行程序、资源、数据
  • 具有objs目录,存放由cpp编译后得到的o文件等中间文件
  • .vscode目录,存放vscode的cpp配置,用于语法解析器。vscode的c++插件所使用。ctrl+shift+p后搜索c++,找到JSON那一项就是
  • Makefile文件,当前工程的Makefile代码

4.2 写代码

在这里插入图片描述

  • 这里简单定义了foo.hpp和foo.cpp,目的是链接为可执行程序后,可以执行
  • ifndef是防止重复包含

4.3 解决多级目录cpp检索问题

在这里插入图片描述

4.4 替换src/为objs/,o文件放到objs中

在这里插入图片描述

4.5 定义依赖关系,通配

在这里插入图片描述

  • objs/%.o和src/%.cpp代表了通配依赖关系,模式匹配,%相当于变量部分

4.6 为o文件创建目录

4.6.1 编译失败,因为目录不存在

在这里插入图片描述

  • 原因是,试图创建objs/foo/foo.o文件时失败。因为objs/foo这个目录不存在造成。对于高版本g++(例如9.0)不会报错并为你创建objs/foo目录。
  • 因此我们需要创建objs/foo目录,需要执行类似mkdir -p dir($@),通过dir($@)获取其目录后创建,这里的mkdir -p指多级目录也一并创建

4.6.2 使用mkdir -p $(dir $@)获取生成项目录

在这里插入图片描述

4.7 链接所有o文件生成可执行程序

在这里插入图片描述

  • 我们定义workspace/pro的生成,依赖自所有的o文件。pro是我们的可执行程序

4.8 完善一下Makefile

在这里插入图片描述

  • 添加make pro,简洁的编译程序
  • 添加make run,编译后顺便执行一下,注意: cd到workspace是为了让运行程 序后的当前工作目录在workspace中
  • 添加make clean,清理编译后的垃圾
  • 添加.PHONY,让我们作为指令存在的东西,不要被视作为文件。即make这东西时永远执行command

4.9 完整版本的Makefile

在这里插入图片描述

4.10 可以愉快的玩耍了

在这里插入图片描述

4.11 修改一个cpp后观察效果

在这里插入图片描述

  • 对,这就是我们想要的,nice!

5. 基于Makefile实现的完整功能项目

  • 这一份代码,你可以点击下载

5.1 Makefile工程-一个复杂的例子,实现http请求

  • 实现的目的:

  • 具有两个依赖,openssl、libcurl

  • 存在include、libs依赖

  • 可以锻炼一个完整的相对完善的工程案例。还可以锻炼到代码调试

  • 实现的效果:

    实现一个程序,可以从任何网站上下载东西

  • 准备:

    • 下载openssl:https://www.openssl.org/source/old/1.1.1/openssl-1.1.1j.tar.gz

      这是用于实现加密通信的加密算法库。用于访问https开头的链接

    • 下载libcurl:https://curl.se/download/curl-7.78.0.tar.gz

      这个是用于实现http/https的访问操作。如果要访问https,则依赖openssl

5.2 下载和编译libcurl/openssl

在这里插入图片描述

  • 创建build目录,用于储存下载后的文件,准备用来编译
  • 创建lean目录,用于存放编译后的结果,作为依赖项目录
  • 将下载后的.tar.gz放到 build目录下,并解压出来

5.3 编译openssl

在这里插入图片描述

cd openssl-1.1.1j
./config --prefix=/data/sxai/makefile/make7/lean/openssl-1.1.1j
make all -j16 && make install -j16
  • ./config是配置并生成Makefile,指定install到/data/sxai/makefile/make7/lean/openssl-1.1.1j目录 make all -j16 && make install -j16 这里-j16是同时16个线程执行操作,编译后,执行安装
  • 请把这里的lean目录修改为你当前自己想放的位置

5.4 编译libcurl

在这里插入图片描述

./configure --prefix=/data/sxai/makefile/make7/lean/curl7.78.0 \--with-openssl=/data/sxai/makefile/make7/lean/openssl-1.1.1j
make all -j16 && make install -j16
  • --prefix同样是为了设置安装目录,最后编译好的curl放在哪里
  • --with-openssl指定刚才我们编译安装后的目录
  • ./configure同样是为了配置curl生成Makefile文件
  • 执行make all -j16实现编译
  • 执行make install -j16实现安装

5.5 编译后结果

在这里插入图片描述

5.6 配置IntellSense和browse路径

在这里插入图片描述

  • 变量${workspaceFolder}代表了我们的当前目录,即/data/sxai/makefile/make7

5.7 配置Makefile

5.7.1 第一步

在这里插入图片描述

5.7.2 第二步

在这里插入图片描述

  • 好,我们齐活了。至此整个makefile已经非常完备了。该makefile可以通用了

给出代码:


srcs := $(shell find src -name "*.cpp")
objs := $(srcs:.cpp=.o)
objs := $(objs:src/%=objs/%)
mks  := $(objs:.o=.mk)include_paths := lean/curl7.78.0/include \lean/openssl-1.1.1j/includelibrary_paths := lean/curl7.78.0/lib     \lean/openssl-1.1.1j/lib# 把library path给拼接为一个字符串,例如a b c => a:b:c
# 然后使得LD_LIBRARY_PATH=a:b:c
empty := 
library_path_export := $(subst $(empty) $(empty),:,$(library_paths))ld_librarys   := curl ssl crypto# 把每一个头文件路径前面增加-I,库文件路径前面增加-L,链接选项前面加-l
run_paths     := $(library_paths:%=-Wl,-rpath=%)
include_paths := $(include_paths:%=-I%)
library_paths := $(library_paths:%=-L%)
ld_librarys   := $(ld_librarys:%=-l%)compile_flags := -std=c++11 -w -g -O0 $(include_paths)
link_flags := $(library_paths) $(ld_librarys) $(run_paths)# 所有的头文件依赖产生的makefile文件,进行include
# -include表示如果有异常请不要打印出来
# 这里判断,如果是clean指令,则不需要生成mk文件
ifneq ($(MAKECMDGOALS), clean)
-include $(mks)
endifobjs/%.o : src/%.cpp@echo 编译$<,生成$@,目录是:$(dir $@)@mkdir -p $(dir $@)@g++ -c $< -o $@ $(compile_flags)workspace/pro : $(objs)@echo 链接$@@g++ $^ -o $@ $(link_flags)objs/%.mk : src/%.cpp@echo 生成依赖$@@mkdir -p $(dir $@)@g++ -MM $< -MF $@ -MT $(@:.mk=.o) $(compile_flags)pro : workspace/pro@echo 编译完成run : pro@cd workspace && ./proclean :@rm -rf workspace/pro objs.PHONY : pro run debug cleanexport LD_LIBRARY_PATH:=$(LD_LIBRARY_PATH):$(library_path_export)

5.8 写代码

5.8.1 第一段

在这里插入图片描述

  • 这里写一个download函数,接收url,然后返回下载后的数据

5.8.2 第二段

  • 注意这里的地址换为:http://www.zifuture.com:1556/fs/sxai/2021/07/pro-18432c111ca44aa9bba49eab650f466c.jpg

在这里插入图片描述

  • 实现一个main函数,调用download。给定地址是一个图片下载好后储存为文件

5.9 执行并观察结果

在这里插入图片描述

  • 文件下载成功,至此。整个http的访问工程就达成了。你学会如何控制,头文件、库文件路径了吗?还有o文件存放工作目录等

6. 分析程序依赖项

6.1 使用readelf -d workspace/pro分析

在这里插入图片描述

6.2 使用ldd workspace/pro分析

在这里插入图片描述

7. 配置C++的调试功能

7.1 配置task.json

在这里插入图片描述

  • task.json是配置用来执行调试之前的编译工作。即,按下F5,编译程序,进入调试

7.2 配置launch.json

在这里插入图片描述

  • 这个文件可用通过直接按下F5后自动产生,也可以手动敲哈
  • 如果有参数,可以加到args中
  • stopAtEntry表示启动后就停止到main函数里边

7.3 进行调试

  • 好了,我们在main.cpp的29行这个文字左侧点击后后个红点,作为断点,然后按下F5键,看看会怎么样

在这里插入图片描述

7.4 界面介绍

在这里插入图片描述

7.5 恭喜

  • 到这里,恭喜你,已经掌握了如何使用
  • Makefile在linux下开发的技能了!
  • Congratulations!!!

8. 头文件修改后自动编译

  • 代码请到github上下载:https://github.com/shouxieai/makefile_tutorial_project

在这里插入图片描述

8.1 新建工程

  • 我们有如下代码。头文件a.hpp中定义了Number 888

在这里插入图片描述

在这里插入图片描述

8.2 分析原因

  • 原因:缺少a.o对hpp依赖关系的定义。makefile中没有定义a.o : a.hpp,没有要求编译a.cpp需要检查a.hpp的时间
  • 解决方案?:直接增加a.o : a.cpp a.hpp吗?是可以。强制要求 a.o生成时检查a.hpp

在这里插入图片描述

8.3 解决方案

8.3.1 使用g++ -MM a.cpp -MF a.mk -MT prefix/a.o生成makefile文件a.mk

在这里插入图片描述

在这里插入图片描述

  • g++ -MM a.cpp -MF a.mk -MT prefix/a.o生成的makefile文件

8.3.2 通过include a.mk包含生成的文件,使其生效

  • 我们使用g++ -MM a.cpp -MF a.mk -MT a.o
  • 为了使编译后的a.mk生效,我们可以通过include a.mk包含进来

在这里插入图片描述

8.3.3 整合起来

注意,这里include a.mk修改为-include a.mk就不会提示报错了

在这里插入图片描述

8.3.4 集成到项目中去

在这里插入图片描述

8.4 把代码拆分出头文件用于检验效果

在这里插入图片描述

8.5 至此,完整的Makefile工程搞定

  • 谢谢

CPP工程模版,请参见:

https://github.com/shouxieai/cpp-proj-template

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/532458.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PyTorch扩展自定义PyThonC++(CUDA)算子的若干方法总结

PyTorch扩展自定义PyThon/C(CUDA)算子的若干方法总结 转自&#xff1a;https://zhuanlan.zhihu.com/p/158643792 作者&#xff1a;奔腾的黑猫 在做毕设的时候需要实现一个PyTorch原生代码中没有的并行算子&#xff0c;所以用到了这部分的知识&#xff0c;再不总结就要忘光了 &a…

给 Python 算法插上性能的翅膀——pybind11 落地实践

给 Python 算法插上性能的翅膀——pybind11 落地实践 转自&#xff1a;https://zhuanlan.zhihu.com/p/444805518 作者&#xff1a;jesonxiang&#xff08;向乾彪&#xff09;&#xff0c;腾讯 TEG 后台开发工程师 1. 背景 目前 AI 算法开发特别是训练基本都以 Python 为主&…

chrome自动提交文件_收集文档及提交名单统计

知乎文章若有排版问题请见谅&#xff0c;原文放在个人博客中【欢迎互踩&#xff01;】文叔叔文档收集使用动机在我们的学习工作中&#xff0c;少不了要让大家集体提交文件的情况&#xff0c;举个最简单的例子&#xff1a;收作业。 传统的文件收集流程大致是&#xff1a;群内发出…

惠普800g1支持什么内存_惠普黑白激光打印机哪种好 惠普黑白激光打印机推荐【图文详解】...

打印机的出现让我们在生活和日常工作中变得越来越方便&#xff0c;不过随着科技的发展&#xff0c;打印机的类型也变得非常多&#xff0c;其中就有黑白激光打印机&#xff0c;而黑白激光打印机的品牌也有很多&#xff0c;比如我们的惠普黑白激光打印机&#xff0c;今天小编就给…

控制台输出颜色控制

控制台输出颜色控制 转自&#xff1a;https://cloud.tencent.com/developer/article/1142372 前端时间&#xff0c;写了一篇 PHP 在 Console 模式下的进度显示 &#xff0c;正好最近的一个数据合并项目需要用到控制台颜色输出&#xff0c;所以就把相关的信息整理下&#xff0c;…

idea连接跳板机_跳板机服务(jumpserver)

一、跳板机服务作用介绍1、有效管理用户权限信息2、有效记录用户登录情况3、有效记录用户操作行为二、跳板机服务架构原理三、跳板机服务安装过程第一步&#xff1a;安装跳板机依赖软件yum -y install git python-pip mariadb-devel gcc automake autoconf python-devel readl…

【详细图解】再次理解im2col

【详细图解】再次理解im2col 转自&#xff1a;https://mp.weixin.qq.com/s/GPDYKQlIOq6Su0Ta9ipzig 一句话&#xff1a;im2col是将一个[C,H,W]矩阵变成一个[H,W]矩阵的一个方法&#xff0c;其原理是利用了行列式进行等价转换。 为什么要做im2col? 减少调用gemm的次数。 重要…

反思 大班 快乐的机器人_幼儿园大班教案《快乐的桌椅》含反思

大班教案《快乐的桌椅》含反思适用于大班的体育主题教学活动当中&#xff0c;让幼儿提高协调性和灵敏性&#xff0c;创新桌椅的玩法&#xff0c;正确爬的方法&#xff0c;学会匍匐前进&#xff0c;快来看看幼儿园大班《快乐的桌椅》含反思教案吧。幼儿园大班教案《快乐的桌椅》…

DCN可形变卷积实现1:Python实现

DCN可形变卷积实现1&#xff1a;Python实现 我们会先用纯 Python 实现一个 Pytorch 版本的 DCN &#xff0c;然后实现其 C/CUDA 版本。 本文主要关注 DCN 可形变卷积的代码实现&#xff0c;不会过多的介绍其思想&#xff0c;如有兴趣&#xff0c;请参考论文原文&#xff1a; …

蓝牙耳机声音一顿一顿的_线控耳机党阵地转移成功,OPPO这款TWS耳机体验满分...

“你看到我手机里3.5mm的耳机孔了吗”&#xff0c;这可能是许多线控耳机党最想说的话了。确实&#xff0c;如今手机在做“减法”&#xff0c;而厂商们首先就拿3.5mm耳机孔“开刀”&#xff0c;我们也丧失了半夜边充电边戴耳机打游戏的乐趣。竟然如此&#xff0c;那如何在耳机、…

AI移动端优化之Im2Col+Pack+Sgemm

AI移动端优化之Im2ColPackSgemm 转自&#xff1a;https://blog.csdn.net/just_sort/article/details/108412760 这篇文章是基于NCNN的Sgemm卷积为大家介绍Im2ColPackSgemm的原理以及算法实现&#xff0c;希望对算法优化感兴趣或者做深度学习模型部署的读者带来帮助。 1. 前言 …

elementui的upload组件怎么获取上传的文本流、_抖音feed流直播间引流你还不会玩?实操讲解...

本文由艾奇在线明星优化师写作计划出品在这个全民惊恐多灾多难且带有魔幻的2020&#xff0c;一场突如其来的疫情改变了人们很多消费习惯&#xff0c;同时加速了直播电商的发展&#xff0c;现在直播已经成为商家必争的营销之地&#xff0c;直播虽然很火&#xff0c;但如果没有流…

FFmpeg 视频处理入门教程

FFmpeg 视频处理入门教程 转自&#xff1a;https://www.ruanyifeng.com/blog/2020/01/ffmpeg.html 作者&#xff1a; 阮一峰 日期&#xff1a; 2020年1月14日 FFmpeg 是视频处理最常用的开源软件。 它功能强大&#xff0c;用途广泛&#xff0c;大量用于视频网站和商业软件&…

checkbox wpf 改变框的大小_【论文阅读】倾斜目标范围框(标注)的终极方案

前言最常用的斜框标注方式是在正框的基础上加一个旋转角度θ&#xff0c;其代数表示为(x_c,y_c,w,h,θ)&#xff0c;其中(x_c,y_c )表示范围框中心点坐标&#xff0c;(w,h)表示范围框的宽和高[1,2,7]。对于该标注方式&#xff0c;如果将w和h的值互换&#xff0c;再将θ加上或者…

彻底理解BP之手写BP图像分类你也行

彻底理解BP之手写BP图像分类你也行 转自&#xff1a;https://zhuanlan.zhihu.com/p/397963213 第一节&#xff1a;用矩阵的视角&#xff0c;看懂BP的网络图 1.1、什么是BP反向传播算法 BP(Back Propagation)误差反向传播算法&#xff0c;使用反向传播算法的多层感知器又称为B…

梯度下降法和牛顿法计算开根号

梯度下降法和牛顿法计算开根号 本文将介绍如何不调包&#xff0c;只能使用加减乘除法实现对根号x的求解。主要介绍梯度下降和牛顿法者两种方法&#xff0c;并给出 C 实现。 梯度下降法 思路/步骤 转化问题&#xff0c;将 x\sqrt{x}x​ 的求解转化为最小化目标函数&#xff…

汇博工业机器人码垛机怎么写_全自动码垛机器人在企业生产中的地位越来越重要...

全自动码垛机器人在企业生产中的地位越来越重要在智能化的各种全自动生产线中&#xff0c;全自动码垛机器人成了全自动生产线的重要机械设备&#xff0c;在各种生产中发挥着不可忽视的作用。全自动码垛机器人主要用于生产线上的包装过程中&#xff0c;不仅能够提高企业的生产率…

小说中场景的功能_《流浪地球》:从小说到电影

2019年春节贺岁档冒出一匹黑马&#xff1a;国产科幻片《流浪地球》大年初一上映后口碑、票房双丰收&#xff1a;截至9日下午&#xff0c;票房已破15亿&#xff0c;并获得9.2的高评分。著名导演詹姆斯卡梅隆通过社交媒体对我国春节期间上映的科幻影片《流浪地球》发出的祝愿&…

线性回归与逻辑回归及其实现

线性回归与逻辑回归及其实现 回归与分类 预测值定性分析&#xff0c;即离散变量预测时&#xff0c;称之为分类&#xff1b;预测值定量分析&#xff0c;即连续变量预测时&#xff0c;称之为回归。 如预测一张图片是猫还是狗&#xff0c;是分类问题&#xff1b;预测明年的房价…

hbase 页面访问_HBase

HBase 特点 海量存储 Hbase 适合存储 PB 级别的海量数据&#xff0c;在 PB 级别的数据以及采用廉价 PC 存储的情况下&#xff0c;能在几十到百毫秒内返回数据。这与 Hbase 的极易扩展性息息相关。正式因为 Hbase 良好的扩展性&#xff0c;才为海量数据的存储提供了便利。 2&…