可编程的SQL是什么样的?

2023-05-16

背景

如果你使用传统编程语言,比如Python,那么恭喜你,你可能需要解决大部分你不需要解决的问题,用Python你相当于拿到了零部件,而不是一辆能跑的汽车。你花了大量时间去组装汽车,而不是去操控汽车去抵达自己的目的地。大部分非计算机专业的同学核心要解决的是数据操作问题,无论你是摆地摊,开餐馆,或者在办公室做个小职员,在政府机构做工作,你都需要基本的数据处理能力,这本质上是信息处理能力。 但是在操作数据前,你必须要学习诸如变量,函数,线程,分布式等等各种仅仅和语言自身相关的特性,这就变得很没有必要了。操作数据我们也可以使用 Excel(以及类似的软件),但是Excel有Excel的限制,譬如你各种点点点,还是有点低效的,有很多较为复杂的逻辑也不太好做,数据规模也有限。那什么交互最快,可扩展性最好?语言。你和计算机系统约定好的一个语言,有了语言交流,总是比点点点更高效的。这个语言是啥呢?就是SQL。

但是SQL也有些毛病,首先他最早为了关系型数据库设计的,适合查询而非ETL,但是现在人们慢慢把他扩展到ETL, 流式处理,甚至AI上,他就有点吃力了。 第二个问题是,他是声明式的,导致缺乏可编程性。所谓可编程性是指,我们应该具备创建小型、可理解、可重用的逻辑片段,并且这些逻辑片段还要被测试、被命名、被组织成包,而这些包之后可以用来构造更多有用的逻辑片段,这样的工作流程才是合理又便捷的。更进一步的,这些“高阶”能力应该是可选的,我们总是希望用户一开始去使用最简单的方式来完成手头的工作而不是显摆一些高阶技巧。

所以最后的结论是,我们希望:

  1. 保留SQL的所有原有优势,简洁易懂,上手就可以干活。
  2. 允许用户进阶,提供更多可编程能力,但是以一种SQL Style的方式提供。

保留原有SQL精髓

我们仅仅对SQL做了丢丢调整,在每条SQL 语句结尾增加了一个表名,也就是任何一条SQL语句的结果集都可以命名为一张新的表。

load hive.`raw.stripe_discounts` as discounts;
load hive.`raw.stripe_invoice_items` as invoice_items;
select
        invoice_items.*,
        case
            when discounts.discount_type = 'percent'
                then amount * (1.0 - discounts.discount_value::float / 100)
            else amount - discounts.discount_value
        end as discounted_amount

    from invoice_items

    left outer join discounts
        on invoice_items.customer_id = discounts.customer_id
        and invoice_items.invoice_date > discounts.discount_start
        and (invoice_items.invoice_date < discounts.discount_end
             or discounts.discount_end is null) as joined;


select

        id,
        invoice_id,
        customer_id,
        coalesce(discounted_amount, amount) as discounted_amount,
        currency,
        description,
        created_at,
        deleted_at

    from joined as final;

select * from final as output;

大家看到,每条SQL的执行结果都被取名为一张新表,然后下一条SQL可以引用前面SQL产生的表,相比传统我们需要insert 然后再读取,会简单很多,也更自然,速度更快。而且对于数据处理,我们也无需在一条SQL语句里写复杂的嵌套子查询和Join了,我们可以将SQL展开来书写,校本化,更加易于阅读和使用。

支持更多数据源

传统SQL是假定你在一个数据源中的,因为你只能按库表方式去使用,在普通Web开发里,是你配置的数据库。而在大数据里,一般是数据仓库或者数据湖。 但是随着联邦查询越来越多,越来越普及,我们希望给SQL提供更多的加载和保存多种数据源的能力。我们通过提供load语句来完成。

load excel.`./example-data/excel/hello_world.xlsx` 
where header="true" 
as hello_world;


select hello from hello_world as output;

在上面的示例可以看到,我们加载了一个excel文件,然后映射成一张表,之后可以用标准的SQL进行处理。
如果要将结果保存到数仓也很简单:

save overwrite hello_word as hive.`tmp.excel_table`;

变量

变量是一个编程语言里,一般你会接触到的第一个概念。我们也给SQL增加了这种能力。比如:

-- It takes effect since the declaration in the same cell.
set world="world";


select "hello ${world}" as title 
as output;

在可编程SQL中,变量支持多种类型,诸如sql,shell,conf,defaultParam等等去满足各种需求和场景。下面是一个典型的例子:

set date=`select date_sub(CAST(current_timestamp() as DATE), 1) as dt` 
where type="sql";


select "${date}" as dt as output;

后面我们会有更多变量的介绍。

调用外部模块的代码

传统编程语言如Java,Python,他们的生态都是靠第三方模块来提供的。第三方模块会被打包成诸如如Jar ,Pip 然后让其他项目引用。 原生的SQL是很难复用的,所以没有形成类似的机制,更多的是随用随写。 但是随着SQL能力的扩展,在流,在批,在机器学习上的应用越来越多,能写越来越复杂的逻辑,也慢慢有了更多的可复用诉求。

我们通过引入include 关键字,可以引入本项目或者github上的SQL代码。https://github.com/allwefantasy/lib-core 是我们使用可编程SQL写的一个第三方模块。假设我们要引用里面定义的一个UDF 函数 hello,第一步是引入模块:

include lib.`github.com/allwefantasy/lib-core`
where 
-- libMirror="gitee.com" and  -- 配置代理
-- commit="" and              -- 配置commit点
alias="libCore";

第二步就是引入相应的udf包,然后在SQL中使用:

include local.`libCore.udf.hello`;
select hello() as name as output;

是不是很酷?

宏函数

函数是代码复用的基础。几乎任何语言都有函数的概念。我们在SQL中也引入的宏函数的概念。但这个宏函数和 原生的SQL中的函数比如 split, concat 等等是不一样的。他是SQL语言级别的函数。我们来看看示例:

set loadExcel = '''
load excel.`{0}` 
where header="true" 
as {1}
''';


!loadExcel ./example-data/excel/hello_world.xlsx helloTable;

在这段代码中,

  1. 我们申明了一个变量 loadExcel,并且给他设置了一段代码。
  2. loadExcel 有诸如 {0}, {1}的占位符。这些会被后续调用时的参数动态替换。
  3. 使用功能 ! 将loadExcel变量转化为宏函数进行调用。参数传递类似命令行。

我们也支持命名参数:

set loadExcel = '''
load excel.`${path}` 
where header="true" 
as ${tableName}
''';


!loadExcel _ -path ./example-data/excel/hello_world.xlsx -tableName helloTable;

原生SQL函数的动态扩展

像传统关系型数据库,几乎无法扩展SQL的内置函数。在Hive/Spark中,通常需要以Jar包形式提供,可能涉及到重启应用,比较繁琐,比较重。 现在,我们把SQL UDF 书写变成和书写SQL一样。 我们来看一个例子:

register ScriptUDF.`` as arrayLast 
where lang="scala"
and code='''def apply(a:Seq[String])={
      a.last
}'''
and udfType="udf";


select arrayLast(array("a","b")) as lastChar as output;

在上面的代码中,我们通过register语法注册了一个函数叫 arrayLast,功能是拿到数组的最后一个值。 我们使用scala代码书写这段逻辑。之后我们可以立马在SQL中使用功能这个函数。是不是随写随用?

当然,通过模块的能力,你也可以把这些函数集中在一起,然后通过include引入。

分支语法

SQL最大的欠缺就是没有分支语句,这导致了一个啥问题呢?他需要寄生在其他语言之中,利用其他语言的分支语句。现在,我们原生的给SQL 加上了这个能力。 看如下代码:

set a = "wow,jack";


!if ''' split(:a,",")[0] == "jack" ''';
   select 1 as a as b;
!else;
   select 2 as a as b;
!fi;


select * from b as output;

在分支语句中的条件表达式中,你可以使用一切内置、或者我们扩展的原生函数。比如在上面的例子里,我们在if 语句中使用了 split函数。
还有一个大家用得非常多的场景,就是我先查一张表,根据条件决定接着执行什么样的逻辑。这个有了分支语法以后也会变得很简单,比如:

select 1 as a as mockTable;
set b_count=`select count(*) from mockTable ` where type="sql" and mode="runtime";


!if ''':b_count > 11 ''';
    
    select 1 as a from b as final_table;
!else;    
    select 2 as a from b as final_table;
!fi;    


select * from final_table as output;

在上面的代码示例中,我们先查询 mockTable里有多少数据,如果大于11条,执行 A语句,否则执行B 语句,执行完成后的结果继续被后面的SQL 处理。

机器学习(内置算法)

SQL表达机器学习其实是比较困难的。但是别忘了我们是可编程的SQL呀。我们来看看示例,第一步我们准备一些数据:

include project.`./src/common/mock_data.mlsql`;
-- create mock/validate/test dataset.
select vec_dense(features) as features, label as label from mock_data as mock_data;
select * from mock_data as mock_data_validate;
select * from mock_data as mock_data_test;

接着我们就可以引入一个内置的算法来完成模型的训练。

train mock_data as RandomForest.`/tmp/models/randomforest` where

keepVersion="true" 

and evaluateTable="mock_data_validate"

and `fitParam.0.labelCol`="label"
and `fitParam.0.featuresCol`="features"
and `fitParam.0.maxDepth`="2"
;

这个语句表达的含义是什么呢? 对mock_data表的数据使用RandomForest进行训练,训练时的参数来自where语句中,训练后的模型保存在路径/tmp/models/randomforest 里。是不是非常naive!

之后你马上可以进行批量预测:

predict mock_data_test as RandomForest.`/tmp/models/randomforest`  as predicted_table;

或者将模型注册成UDF函数,使用Select语句进行预测:

register RandomForest.`/tmp/models/randomforest` as model_predict;
select vec_array(model_predict(features)) as predicted_value from mock_data as output;

Python脚本支持

在可编程SQL里, SQL是一等公民, Python只是一些字符串片段。下面是一段示例代码:

select 1 as a as mockTable;

!python conf "schema=st(field(a,long))";

run command as Ray.`` where 
inputTable="mockTable"
and outputTable="newMockTable"
and code='''
from pyjava.api.mlsql import RayContext

ray_context = RayContext.connect(globals(),None)

newrows = []
for row in ray_context.collect():
    row["a"] = 2
    newrows.append(row)
    
context.build_result(newrows)
''';


select * from newMockTable as output;

这段代码,我们使用功能Ray 模块执行Python脚本,这段Python脚本会对 mockTable表加工,把a字段从1修改为2,然后处理的结果可以继续被SQL处理。是不是很酷?随时随地写Python处理数据或者做机器学习,数据获取和加工则是标准的SQL来完成。

插件

可编程SQL无论语法还是内核功能应该是可以扩展的。 比如我需要一个可以产生测试数据的功能。我只要执行如下指令就可以安装具有这个功能的插件:

!plugin app add - "mlsql-mllib-3.0";

然后我就获得了一个叫SampleDatasetExt的工具,他可以产生大量的测试数据:

run command as SampleDatasetExt.`` 
where columns="id,features,label" 
and size="100000" 
and featuresSize="100" 
and labelSize="2" 
as mockData;

select * from mockData as output;

在上面的示例代码中,我们通过SampleDatasetExt 产生了一个具有三列的表,表的记录数为100000, 其中feature字段数组大小为100, label字段的数组大小为2。之后我们可以使用select语句进行查询进一步加工。

更多编程小trick

比如下面一段代码在实际生产里是常态:

select SUM( case when `id` is null or `id`='' then 1 else 0 end ) as id,
SUM( case when `diagnosis` is null or `diagnosis`='' then 1 else 0 end ) as diagnosis,
SUM( case when `radius_mean` is null or `radius_mean`='' then 1 else 0 end ) as radius_mean,
SUM( case when `texture_mean` is null or `texture_mean`='' then 1 else 0 end ) as texture_mean,
SUM( case when `perimeter_mean` is null or `perimeter_mean`='' then 1 else 0 end ) as perimeter_mean,
SUM( case when `area_mean` is null or `area_mean`='' then 1 else 0 end ) as area_mean,
SUM( case when `smoothness_mean` is null or `smoothness_mean`='' then 1 else 0 end ) as smoothness_mean,
SUM( case when `compactness_mean` is null or `compactness_mean`='' then 1 else 0 end ) as compactness_mean,
SUM( case when `concavity_mean` is null or `concavity_mean`='' then 1 else 0 end ) as concavity_mean,
SUM( case when `concave points_mean` is null or `concave points_mean`='' then 1 else 0 end ) as concave_points_mean,
SUM( case when `symmetry_mean` is null or `symmetry_mean`='' then 1 else 0 end ) as symmetry_mean,
SUM( case when `fractal_dimension_mean` is null or `fractal_dimension_mean`='' then 1 else 0 end ) as fractal_dimension_mean,
SUM( case when `radius_se` is null or `radius_se`='' then 1 else 0 end ) as radius_se,
SUM( case when `texture_se` is null or `texture_se`='' then 1 else 0 end ) as texture_se,
SUM( case when `perimeter_se` is null or `perimeter_se`='' then 1 else 0 end ) as perimeter_se,
SUM( case when `area_se` is null or `area_se`='' then 1 else 0 end ) as area_se,
SUM( case when `smoothness_se` is null or `smoothness_se`='' then 1 else 0 end ) as smoothness_se,
SUM( case when `compactness_se` is null or `compactness_se`='' then 1 else 0 end ) as compactness_se,
SUM( case when `concavity_se` is null or `concavity_se`='' then 1 else 0 end ) as concavity_se,
SUM( case when `concave points_se` is null or `concave points_se`='' then 1 else 0 end ) as concave_points_se,
SUM( case when `symmetry_se` is null or `symmetry_se`='' then 1 else 0 end ) as symmetry_se,
SUM( case when `fractal_dimension_se` is null or `fractal_dimension_se`='' then 1 else 0 end ) as fractal_dimension_se,
SUM( case when `radius_worst` is null or `radius_worst`='' then 1 else 0 end ) as radius_worst,
SUM( case when `texture_worst` is null or `texture_worst`='' then 1 else 0 end ) as texture_worst,
SUM( case when `perimeter_worst` is null or `perimeter_worst`='' then 1 else 0 end ) as perimeter_worst,
SUM( case when `area_worst` is null or `area_worst`='' then 1 else 0 end ) as area_worst,
SUM( case when `smoothness_worst` is null or `smoothness_worst`='' then 1 else 0 end ) as smoothness_worst,
SUM( case when `compactness_worst` is null or `compactness_worst`='' then 1 else 0 end ) as compactness_worst,
SUM( case when `concavity_worst` is null or `concavity_worst`='' then 1 else 0 end ) as concavity_worst,
SUM( case when `concave points_worst` is null or `concave points_worst`='' then 1 else 0 end ) as concave_points_worst,
SUM( case when `symmetry_worst` is null or `symmetry_worst`='' then 1 else 0 end ) as symmetry_worst,
SUM( case when `fractal_dimension_worst` is null or `fractal_dimension_worst`='' then 1 else 0 end ) as fractal_dimension_worst,
SUM( case when `_c32` is null or `_c32`='' then 1 else 0 end ) as _c32
from data as data_id;

写的手累?那有么有办法简化呢?当然有啦。 我们毕竟是可编程是SQL呀。

一个有意思的解决方法如下:

select 
#set($colums=["id","diagnosis","fractal_dimension_worst"])
#foreach( $column in $colums )
    SUM( case when `$column` is null or `$column`='' then 1 else 0 end ) as $column,
#end
 1 as a from newTable as output;

我们可以使用内置的 #foreach 循环。先通过set设置所有字段名称,然后通过foreach循环来生成sum语句。

这就完了?就如同茴字有好多写法,我们还有其他的玩法。

set sum_tpl = '''
SUM( case when `{0}` is null or `{0}`='' then 1 else 0 end ) as {0}
''';


select ${template.get("sum_tpl","diagnosis")},
${template.get("sum_tpl","radius_mean")},
${template.get("sum_tpl","texture_mean")},
from data as output;

我们可以通过set 进行模板设置,然后在sql语句里通过template.get( 语句进行模板渲染。 对于一个很复杂的SQL 语句,里面可能存在多个类似sum /case when的重复语句,那么我们就可以使用这种方式了。而且可以做到一处修改,处处生效。不然万一你 sum里的1要改成2,那可是要改好几十个语句的。

恩,除了这些,还有非常多的好玩的玩法等待你的挖掘,SQL 再也不Boring了。

不是最后的最后

可以看到,我们给原生SQL扩展了变量,函数,多数据源支持,第三方模块,原生SQL ,原生函数动态扩展,分支语法,机器学习,python脚本支持,插件等等诸多功能。就像TypeScript给JavaScript的增强一样,大家也可以只用最基础的SQL语法。但是一旦你有需要,你就可以使用更多高阶功能满足自己的诉求。

最后

这个可编程的SQL是还在梦想中么?当然不是! 它就在这里: https://mlsql.tech 我们提供了桌面版和在线试用版本。还不快来感受下。

真的最后了

MLSQL目前支持Web版,桌面版,包括Script,Notebook等多种交互模式。参考 MLSQL 2.1.0版本的技术白皮书

现在,让我们看一段赏心悦目的MLSQL代码

  1. 下载图片tar包,并且解压
  2. 设置python环境
  3. 加载图片目录为表
  4. 使用python进行分布式图片处理
  5. 对文件名进行处理
  6. 将表以二进制图片包保存到对象存储目录中

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

可编程的SQL是什么样的? 的相关文章

  • Mac上的远程连接工具Royal TSX,比FinalShell更值得被推荐

    安装Royal TSX xff1a https blog csdn net Darling qi article details 120289137 使用Royal TSX xff1a https blog csdn net Bluffin
  • libjvm.so: ELF file OS ABI invalid

    Error dl failure on line 893 Error failed 某目录 jdk jre lib amd64 server libjvm so because 某目录 jdk jre lib amd64 server li
  • win11启用旧右键菜单(不折叠)的方案,亲测有效

    我电脑的winodws11版本如下 在以上win版本下 xff0c 测试网上说的以下几个办法都不行 1 权利与暗访时在终端运行 reg exe delete HKCU Software Classes CLSID 86ca1aa0 34aa
  • Android中的动画总结

    Android 动画 三种总结 xff1a 属性动画 xff1a 动态的改变属性产生动画效果 xff1b 改变动画的属性 xff0c 两个重要的类 xff1a 1 ValueAnimator 类是先改变值 xff0c 然后 手动赋值 给对象
  • ubuntu自动登录tty终端的最简方法

    背景 在嵌入式系统经常需要自动登录tty xff0c 以实现业务程序开机启动的效果 网上有篇文章ubuntu自动登录tty1 shell text 配置转发挺多 xff0c 但我弄明白原理后 xff0c 觉得可以进一步简化 xff0c 经测
  • git为指定项目设置用户名密码

    我们如果没有为项目设置用户名密码 xff0c 那么每次提交都会有提示账号和密码输入 xff1a 1 找到你项目的半隐藏文件 git文件夹 xff0c 通常只要git init 就会生成这样一个文件夹 xff0c 现在双击进入文件夹 xff1
  • JAVA 访问windows共享文件夹

    一 使用技术 JCIFS框架对Windows共享文件夹进行读写 xff0c 使用了SMB通信协议 xff0c 它为局域网内不同的计算机之间提供文件和打印机等资源共享服务 二 共享文件夹设置 测试共享文件夹机器windows版本为win10家
  • 前端代码调试:Webstorm调试js

    前言 目前前端开发 JavaScript的debug一般都是用chrome和firefox的开发者工具进行调试 xff0c 浏览器工具使用不方便 xff0c webstorm支持了在代码上打断点 xff0c 在编辑器里debug js代码
  • CV:基本概念和工具

    文章目录 计算机视觉像素 xff0c 颜色 xff0c 通道 xff0c 图像和颜色空间的概念图像文件后缀有损压缩和无损压缩 Python的计算机视觉库PIL xff1a python 图像处理类库载入PIL库基本操作命令 openCVop
  • OCR技术概览

    OCR技术概览 OCR Optical Character Recognition 光学字符识别技术主要分为手写体识别和印刷体识别两类 印刷体识别比手写体识别要简单 因为印刷体更规范 字体来自于计算机字库 尽管印刷过程中可能会发生不清晰 粘
  • CV:图像色彩空间及色彩处理

    文章目录 基本概念RGB空间HSV空间HSL空间 色彩变换灰度变换色彩反向 调整像素区间增强对比度直方图均衡化 图像平滑 减少噪声图像平均高斯滤波 图像梯度sobel算子 scharr算子prewitt算子Laplacian 算子 参考及更
  • OpenCV角点检测: Harris算子, ShiTomasi算子

    角点检测 角点的特征检测与匹配是Computer Vision 应用总重要的一部分 xff0c 这需要寻找图像之间的特征建立对应关系 点 xff0c 也就是图像中的特殊位置 xff0c 是很常用的一类特征 xff0c 点的局部特征也可以叫做
  • 集成学习:让算法和算法赛跑

    文章目录 集成学习的基本概念构建弱分类器 xff1a 决策树自助采样法bootstrappingbootstrapping的核心思想bootstrapping与permutation的区别 baggingboosting为何bagging会
  • backbone模型:FCN、SRN、STN

    文章目录 FCN网络CNN图像分割模型结构FCN github资源FCN的优缺点 SRN 网络什么是空间规整 spatial regularization xff09 SRN网络github资源 STN网络空间变换器localisation
  • docker部署机器学习/深度学习模型的容器化方案

    文章目录 什么是dockerdocker的优点 docker image镜像Dockerfile 文件Dockerfile配置例子 创建docker镜像 docker container 容器模型部署参考和更多阅读 docker部署机器学习
  • RNN模型训练经验总结

    文章目录 RNN模型训练经验总结数据准备 look at your data 小步试错 搭建模型设置端到端的训练评估框架 forward propagation设置激活函数dropout back propagation设置学习率 lear
  • 算法的时间复杂度和空间复杂度

    如何评价算法的性能 定义 一个算法中的语句执行次数称为 语句频度 或 时间频度 约定 检验算法的效率 xff0c 主要考虑 最坏时间复杂度 和 平均时间复杂度 一般不特别说明 xff0c 讨论的时间复杂度均是最坏情况下的时间复杂度 时间复杂
  • 【LeetCode】LCS最长公共子序列

    最长公共子序列 题目描述思路分析递归结构算法实现输出最长子序列算法实现 题目描述 思路分析 设A 61 a0 xff0c a1 xff0c xff0c am xff0c B 61 b0 xff0c b1 xff0c xff0c bn xff
  • 升级到tensorflow2.0

    目录 从tensorflow1 x升级到2 x方案一 xff1a 依然使用tf 1 x的脚本方案二 xff1a 升级项目代码到2 x tensorflow2 0推出以后 xff0c 全面拥抱keras xff0c 简化了API接口 xff0
  • tensorflow2.0系列(1):张量

    目录 tensor xff1a 张量张量的数据类型Dtype类函数tf as type xff1a 定义Dtype类型对象tf dtypes cast xff1a 将张量映射 投射为新的类型tf dtypes complex xff1a 将

随机推荐

  • tensorflow 2.0系列(3):eager execution和计算图

    目录 tf 2 0 的新特性 xff1a eager execution开启eager模式关闭eager模式 构建图默认图创建多个计算图启动会话 从公式到计算图绘制心形曲线开根号线性回归 tf 2 0 的新特性 xff1a eager ex
  • tensorflow2.0系列(2):张量的运算

    目录 张量运算tf linalg 模块tf math模块常用的代数函数tf math segment 张量运算 tensorflow定义了很多张量的基本运算 xff0c 由于张量的特殊属性 xff0c 其运算操作主要有两类 xff0c 一类
  • 那些重要但是容易被忽略的python编程基础知识

    目录 变量类型标准数据类型 字典字典的内置函数 amp 方法 字符串前符号 python很容易上手 xff0c 工具包特别多 xff0c 入门后就特别容易忽略python的基本特性 这里将特别关注python那些特别基础 xff0c 重要但
  • 常见深度神经网络模型图

    from tensorflow learn in one day by Krishna Rungta
  • tensorflow2.0系列(4): Eager Execution和Auto Graph

    目录 静态图的弊端Eager模式Eager execution的基本特性对 numpy 的支持 Auto Graph 动态图static analysis VS dynamic flow局部参数的可见域python collections
  • Eclipse离线安装ADT插件

    Eclipse安装 ADT插件 但是由于某些不可抗拒的原因连上 https dl ssl google com android eclipse 后 xff0c 始终无法更新 ADT插件 卡死在 Fetchingcontent jar上 解决
  • ubuntu在shell中把文件拷贝进U盘

    1 创建挂载位置 xff0c 例如 sudo mkdir mnt u 这个位置只要建好 xff0c 以后就可以不用再建了 2 用mount命令将U盘挂载在这个位置 sudo mount dev sdb1 mnt u 注意U盘的盘符不一定是
  • linux文件管理

    linux文件管理 计算机操作系统都采用了目录树的文件结构 linux中 xff1a 符号名称 根目录 bin常见用户口令 boot内核和启动文件 dev设备文件 home系统默认的普通用户主目录 etc系统和服务配置文件 lib系统函数库
  • C++和Windows平台的一些书籍

    从2010年学习编程以来 xff0c 到现在有差不多3年时间了 xff0c 过的真快啊 目前在深圳工作 xff0c 主要使用的是C 43 43 语言 xff0c 那么我就说说C 43 43 和Windows平台的书籍吧 1 C primer
  • ubuntu上运行C程序

    ubuntu版本为Ukylin14 04LTS 首先配置编辑器vim step1 xff1a 查看系统是否安装vim 打开终端 xff0c 输入vi xff0c 按下tab键 xff0c 如果列表里没有vim xff0c 说明系统没有安装
  • 怎么让ubuntu变得更加好用

    ubunut14 04LTS版本其实已经很好用了 但是也有一些小小的美中不足 以下设置是陆续收集 摸索到的可以让系统更好用的方法 1 在终端打开已经安装的应用程序时 xff0c 总是会显示一些错误信息 在 bin下添加x文件 xff1a c
  • linux命令(1):touch

    touch 命令 功能说明 xff1a 改变文件或目录时间 xff0c 包括存取时间和更改时间 语 法 xff1a 补充说明 xff1a 使用touch指令可更改文件或目录的日期时间 最常用用法 xff1a touch fileA 如果fi
  • bash shell命令(1);、&&、||

    xff1b 命令 按照先后顺序一次执行多个命令 xff0c 命令之间用 xff1b 分割 xff1a command 1 command 2 command 3 amp amp 命令 如果前一个命令 command 1 顺利执行 xff0c
  • linux命令(2):less

    less工具也是对文件或其它输出进行分页显示的工具 xff0c 比more的功能更强大 命令格式 xff1a less 参数 文件1 xff08 文件2 xff09 命令功能 xff1a less 与 more 类似 xff0c 但使用 l
  • [zz] linux下vi或vim操作Found a swap file by the name的原因及解决方法

    在linux下用vi或vim打开Test java文件时 root 64 localhost tmp vi Test java 出现了如下信息 xff1a E325 ATTENTION Found a swap file by the na
  • ubuntu中使用判断符号[]

    鸟哥的私房菜p270中13 3 2使用 符号有这样一个例子 xff1a vim sh06 sh 脚本内容如下 xff1a bin bash Program This program shows the user 39 s choice Hi
  • 深度学习caffe框架(1):如何快速上手caffe?

    初识caffe 安装caffe跑一个例子mnist配置caffe框架的深度学习网络结构输入数据 数据层的定义图片数据如何保存为lmdb格式 模型的保存和读取 caffe的代码层次参考 初识caffe 安装caffe 跑一个例子 mnist
  • 深度学习caffe框架(2): layer定义

    caffe的代码层次 首先让我们回顾一下caffe的代码层次 blob layer net和solver 其中blob是数据结构 layer是网络的层 net是将layer搭建成的网络 solver是网络BP时候的求解算法 本节主要介绍ca
  • 安装Qt及相关问题解决

    安装Qt及相关问题解决 Download Qt 1 Qt下载 关于Qt下载 xff0c 官网可以下载 但是需要填一大堆信息 非常麻烦 可以打开下面的链接 xff0c 里面有各版本Qt http download qt io archive
  • 可编程的SQL是什么样的?

    背景 如果你使用传统编程语言 xff0c 比如Python xff0c 那么恭喜你 xff0c 你可能需要解决大部分你不需要解决的问题 xff0c 用Python你相当于拿到了零部件 xff0c 而不是一辆能跑的汽车 你花了大量时间去组装汽