ALSA编程总结 1. ALSA包括各种声卡的Kernel驱动,提供libasournd开发库,可以帮助开发者调用更高级的接口,而不用直接和ioctl打交道,并且可以提高兼容性,另外,alsa还提供了Plugin能力,可以扩展很多功能。2. ALSA API可以分为以下几个主要部分:a. control接口:一个通用功能,用来管理声卡的寄存器以及查询可用的设备。b. PCM接口:管理audio capture和playback的接口,这也是audio最常用的接口c. Raw MIDI接口: 支持MIDI(电子音乐设备
caffe中layer_factory的机制实现 caffe中的layer都是由layer_factory创建的,是典型的工厂模式。我们看caffe的源码,我们就会发现,不管创建哪种layer,都可以用如下的函数来创建:shared_ptr<Layer<Dtype> > layer = LayerRegistry<Dtype>::CreateLayer(layer_param);这个函数就定义在layer_factory.hpp文件中,是 LayerRegistry<Dtype> class的stat
caffe net 源码分析 #include <algorithm>#include <map>#include <set>#include <string>#include <utility>#include <vector>#ifdef USE_HDF5#include "hdf5.h"#endif // USE_HDF5#include "caffe/common.hpp"#include "caffe/layer.hpp"#in
caffe源码分析之卷积层 卷积层的基类头文件#ifndef CAFFE_BASE_CONVOLUTION_LAYER_HPP_#define CAFFE_BASE_CONVOLUTION_LAYER_HPP_#include <vector>#include "caffe/blob.hpp"#include "caffe/layer.hpp"#include "caffe/proto/caffe...
疯狂python讲义学习知识点 在终端运行python -m pydoc -p 8899 就会在本地运行一个python 文档的http server 端口号为8899利用浏览器打开http://localhost:8899/就可以查看所有模块的文档
Hello World based on caffe之LeNet详解 MNIST数据集是纽约大学Yann LeCun教授整理的一个大型的手写体数字数据库,包括6万个训练集和1万个测试集,尺寸都进行了归一化,尺寸为28x28.下载链接为 http://yann.lecun.com/exdb/mnist/ caffe中也提供了脚本来下载,在caffe/data/mnist中MNIST原始数据为4个文件:train-images-idx3-ubyte ...
c++11的bind函数 对于bind函数,默认bind进来的参数都是值传递,当需要传引用进来的时候,需要用ref()来修饰。例子如下:所以可以知道,bind默认都是值传递。lambda表达式捕获的时候是可以指定是引用捕获还是值传递,这点lambda比bind好一些。他们背后的原理其实都是一样的,都是形成了一个可调用对象,bind进来的参数或者lambda捕获的参数都存在于这个可调用对象里面。...
c++的继承关系总结 1.子类对象的指针可以直接赋值给父类的指针,但地址值可能会变化,也就是可能编译器给自动做了转换,具体可以看下面的例子。这也是最常规的用法。2.父类的对象的指针不能直接赋值给子类的指针,编译报错,可以需要强制转换来通过编译。这种用法一般用在创建的子类对象赋值给了父类的指针,再将父类的指针赋值给子类的指针。也就是该对象实际是子类的对象。如果是父类的对象,里面是不包含子类的内容的,所以不能强制转换为子...
caffe源码分析之layer 1.caffe的主要抽象就是layer,net由layer组成,blob作为layer的输入和输出。因为神经网络中有很多不同的layer,所以提供了一个layer的基类,所有的具体的layer都是继承自这个基类。文件为caffe/include/caffe/layer.hpp和caffe/src/caffe/layer.cpp.因为是个接口类,所以.cpp中基本没有内容,主要在.h中的接口。2....
caffe源码分析之数据结构Blob Caffe提供了一些基础的数据结构,从上到下包括net —>layer —>blob.可以看出blob就是构成caffe大厦的最基础的砖头。本篇就来介绍一下Blob类的一些知识。1.Blob类是caffe用来存储数据的类,是caffe的基本存储单元,提供了一些列接口来set数据,get数据,同时可以存储diff。Blob不仅可以存放比如图像等数据以及数据的diff,还可以存放权值以...
caffe tool分析之----caffe.cpp #ifdef WITH_PYTHON_LAYER#include "boost/python.hpp"namespace bp = boost::python;#endif#include <gflags/gflags.h>#include <glog/logging.h>#include <cstring>#include <map&g...
caffe tool之compute_image_mean源码解析 #include <stdint.h>#include <algorithm>#include <string>#include <utility>#include <vector>#include "boost/scoped_ptr.hpp"#include "gflags/gflags.h"#include "glog...
caffe2源码分析之core之存储篇----tensor core模块的数据存储与表示主要分为以下几个模块,后面逐一分析。storagetensorblobqtensor这篇介绍tensor:file_location : pytorch/c10/core/TensorImpl.h &TensorImpl.cpp...
caffe2源码分析之core之存储篇----storage Core模块是caffe2的核心模块,定义了一系列关键的类,其主要的模块结构如下:数据存储与表示storagetensorblobqtensor操作observer observableoperator操作求导operator_schemacontext计算图graphnettransform运行时allocatordbregistrymodulescop...
caffe2源码分析第一篇----threadpool 从本篇开始分析总结caffe2的源码,caffe2中大量使用了modern c++的新特性,所以在学习神经网络的知识的同时,也同步学习modern c++的特性。最近正好在工作中需要用到threadpool, 所以就先从threadpool开始分析了。分析的方法包括源码分析和最后的归纳总结。1.先来看threadpool的目录结果...
C++中const、constexpr, mutable的用法 这里有一片博客介绍这三种用法,暂时记录在这里,有空学习整理一下https://www.cnblogs.com/xkfz007/articles/2419540.html
c++编码规范 这里记录一些日常的c++编码的规范1.引用和指针的写法int value = 0;int &ref_val = value;//&要和变量名写在一起,表明ref_val是个引用int *p_val = &value; //*同样也要和变量名写在一起,表明p_val是个指针变量int i = 1024, *p = &i, &r = i;//上面两条规...
linux字体问题总结 1.linux系统下字体文件为.ttf文件(windows字体文件为.ttc文件),虽然linux和windows字体文件的后缀名不一样,但内容是一样的,所以可以直接copy windows系统下的font文件到linux相应目录下,并修改相应的后缀名就可以使用了。2.linux字体文件存放的目录为/usr/share/fonts和/usr/local/share/fonts目录,这是两个主要放...
ffmpeg常用命令总结 一.转码和转封装:ffmpeg -i ingput.rmvb -vcodec mpeg4 -b:v 200k -r 15 -s 640x480 -an -f mp4 -movflags faststart -y output.mp4-vcodec : 强制指定视频编码格式,-acodec 强制指定音频编码格式 (ffmpeg -codecs可以查看支持的codecs, 如果指定copy则就...
git提交时忽略某些文件夹或者文件 参考 : https://www.cnblogs.com/rickqin/p/7068088.html 只需要在该目录下创建.gitignore文件,将需要ignore的文件和文件夹写在这个文件中,当然也包括.gitignore本文件,然后git就会自动不去追踪这些文件了。具体可以参考上面的文章。...
编译lua库 lua官网提供了一个解析lua的库,地址为 https://www.lua.org/download.html,我们可以下载该库的源码。 这个源码比较简单,readme里面也提供了编译的方法,但是默认的编译只编译为一个静态库,不能编译为动态库,如果想编译为动态库,需要修改他的makefile。修改内容如下: 1. 修改根目录下的Makefile文件 TO_LIB= liblua.a 修改...
交叉编译 这里记录一些交叉编译的一些知识 1.https://blog.csdn.net/openblog/article/details/7449991 解决交叉编译依赖的方法。 2. https://blog.csdn.net/AtlanticEvix/article/details/4824453 linux库的一些交叉编译的方法...
json-c的交叉编译 第一次学习交叉编译,从最简单的json-c的开源库开始,json-c开源库是一个用c实现的解析json字段的库,可以从github上获取,我另一篇博客专门对这个库有介绍,此篇主要记录对json-c进行交叉编译到arm开发板上。我下载的是Json-c的4.0版本。 1.cd到json-c的目录 里面有一个autogen.sh的脚本,首先要运行这个脚本来产生configure文件。运行完这个脚本...
JSON总结 有空学习总结一下JSON的格式,包含解析的方法等。 1.json的格式,这里有详细的介绍:https://www.runoob.com/json/json-tutorial.html 2.有很多用c/c++实现的json解析库,这个链接测评了很多json开源库的性能。https://www.oschina.net/news/61942/cpp-json-compare json-c库...
关于arm-neon的总结 现在的ARM处理器大部分就配备了NEON,具有NEON技术的处理器都会配备了32个64位的寄存器和16个128位的寄存器,分别被标识为D0-D31, Q0-Q15. NEON指令集只是ARM和THUMB指令集的子集,主要的任务就是执行批处理,比如内存的访问,在NEON寄存器和传统寄存器之间数据的拷贝,数据类型的转化,数据的处理等。arm公司给封装了一个库(OPENMAX),需要使用的时候需要包含...
编译安装opencv 最近开始学习opencv,首先就要在我的fedora系统上编译安装opencv。下面记录安装过程: 1.下载opencv源码,这个可以从github上下载,我下载的版本是3.4.1. 命令为 ·it clone git@github.com:opencv/opencv.git 就可以下载到最新的版本。也可以下载他的tar打包文件自己解压安装。 2.安装依赖库 因为opencv依赖很多...
利用ddd和gdb_server来交叉调试程序 我们可以利用gdb来单步调试程序,但是需要编译的时候有-g选项。在嵌入式开发中,我们可以将gdb拷贝到板子上,在板子上进行gdb调试,也可以在板子上运行gdb_server,然后主机上运行gdb,和远端的gdb_server链接,在主机上gdb调试。下面就介绍一下怎么进行交叉调试: 1.首先需要在主机上安装ddd工具,ddd工具是一个可以运行gdb的界面程序,虽然这个界面非常粗糙。安装包可以从我...
linux系统编译链接总结--高级c/c++编译技术读后总结(下) 本篇开始总结动态库设计的进阶篇。 一 : 动态库的设计,进阶篇 动态链接的重要原则就是不同进程共享同一个动态库的代码段,但不共享数据段。每个加载了动态库的进程都会提供一份自己的数据副本给动态库代码段使用。同时利用内存映射,将同一个动态库的代码段映射到不同的进程空间上。 1.由于动态库是运行的时候加载到进程的内存地址空间的,所以只有当运行时将该库加载到内存的时候,库中各个函数等的地址才能确定,...
正则表达式和使用正则表达式的grep,sed,awk等工具 本文介绍正则表达式和支持正则表达式的linux命令,如grep sed awk等工具 另外,c++标准库提供了std::regex来解析正则表达式。可以参考《c++标准库》。 一 : 正则表达式 正则表达式就是为了可以批处理文本,提供一些字符串的特殊匹配功能,比一般的通配符要强大和灵活,但也要注意不要和linux shell的通配符混在一起,通配符是大部分linux cmd都支持的简单的字符...
linux shell script总结 在一些linux系统管理和自动化测试中经常需要写一些shell脚本,所以这里总结一下主要的规则,便于以后编写时查阅。 shell的开头必须以 #!/bin/bash开头,表明是使用/bin/bash来解释脚本的执行。 shell的注释用# 可以使用source命令来执行脚本,也可以直接将shell脚本文件加上可执行权限,直接执行 一:变量 1.定义变量 : aa=”qq” 注意等号两侧
cmake总结 学习了makefile的规则之后,感觉makefile的规则还是有些复杂的,要建立一个比较复杂的项目,makefile还是有一定的工作量的。但是现在已经有了很多工具来将makefile给封装起来,减少工作量。现在要介绍的一个就是cmake,很多开源的项目也是使用cmake的,还有一个autotool工具,实现类似的功能。下面的文章就是介绍cmake的使用的。 1.http://www.hahac...
跟我一起写makefile总结 最近为了搞懂makefile,精读了陈皓的《跟我一起写makefile》,算是基本搞明白了makefile的各种基本规则和变量了,下面总结如下,以备后面忘记的时候查阅。现在也有了很多makefile的自动生成管理工具,可能很多时候也不用自己写makefile了,但是理解了他的基本原理还是非常有帮助的,整理完成后,准备系统学习一下cmake等makefile管理系统,使自己具备大型项目的管理能力。
fedora安装tftp server 由于要在板子上实现tftp client, 所以现在pc实现tftp server, 直接用sudo dnf install tftp-server安装,显示搜不到package,所以从网上下载了安装包,https://fedora.pkgs.org/26/fedora-x86_64/tftp-server-5.2-20.fc26.x86_64.rpm.html 2.安装完之后,server的目录
extern “C”的用法 经常c c++混合编程的时候,需要用到extern “C”的关键字,这里说明一下其原理: 由于c++为了支持面向对象编程,命名空间和函数的重载,定义了更加复杂的符号命名规则,因为c++的函数一般都是属于某个类,或者某个命名空间,为了唯一的标识函数,链接器在为函数入口点建立符号的时候,必须用某种方法来包含函数的从属信息。c++的重载机制允许同一个类的不同函数拥有相同的函数名和返回值,只是参数不同,所
宏定义中的## 2、#define D(a) cout << #a “=[” << a << “]” << endl;3、#是“字符串化”的意思。出现在宏定义中的#是把跟在后面的参数转换成一个字符串例如: define FOO(arg) my##arg 则 FOO(abc) 相当于 myabc例如: define STRCPY(dst, src) strc
利用反汇编帮助查找段错误 当程序运行时经常会发生段错误,如果在linux系统,可以利用core dump文件,用gdb来帮助查找,前面已经有介绍过这种方法,如果不是linux系统,则很多时候不能使用gdb,则可以利用反汇编来查找出错的位置,一般段错误会打印出出错的指针位置,如下: Oops: Data Abort caused by READ instruction! Fault: Alignment fault pc
linux系统编译链接总结--高级c/c++编译技术读后总结(上) 最近学习了《高级c/c++编译技术》,收获良多,现总结如下: 1.编译环节是将c或c++程序编译成二进制文件,在linux中一般为.o文件,每个源文件编译为一个.o文件。链接:是根据包含关系将.o文件组合起来,合并成一个二进制文件,该文件可为可执行文件,也可以为静态库或者动态库文件。该二进制文件会分为很多节,下面几个节是必须支持的: 代码节(.text):包含了供cpu执行的机器指令。 数据...
makefile 总结 1.https://www.cnblogs.com/zqlxtt/p/5016654.html makefile简介 1.几种等号的意义: = 是最基本的赋值,可以使用后面定义的变量 := 只能使用当前已经定义的变量,不能使用后面定义的 变量 ?= 是如果没有被赋值过就赋予等号后面的值 += 是添加等号后面的值之前一直纠结makefile中“=”和“:=”的区别到底有什么区别,因为给变
rtos开发总结 由于工作需要,使用到rtos,现将遇到的问题总结如下:1.实现类似于linux shell的交互工具。实现基本思路是初始化一个shell线程,然后接收用户的输入,然后parse用户的命令。当然,支持的命令需要提前实现,比如要实现ls的命令,需要实现ls命令的函数,然后该函数注册到一个数组中,当接收到用户输入ls命令时,遍历函数数组中的注册函数,找到相应的命令,然后执行。 1.首先利用
server编译code和cifs mount步骤。 在工作中经常碰到在server上编译code的情况,这种情况下,需要将server上的某个目录mount到本地,便于修改代码和使用编译出来的binary。 首先,对于登录server,一般使用ssh,命令为ssh name@ip.可能会提示你相会交换public key。按照步骤操作即可。 然后对于使用cifsmount,在/etc/fstab中添加如下信息 //ip/dir /mnt/nam
hosts设置和ssh设置 hosts的设置: 1、主机名:无论在局域网还是INTERNET上,每台主机都有一个IP地址,是为了区分此台主机和彼台主机,也就是说IP地址就是主机的门牌号。公网:IP地址不方便记忆,所以又有了域名。域名只是在公网(INtERNET)中存在,每个域名都对应一个IP地址,但一个IP地址可有对应多个域名。局域网:每台机器都有一个主机名,用于主机与主机之间的便于区分,就可以为每台机器设置主机名,以便于以
互斥锁-条件变量-信号量总结 互斥锁:mutex 条件变量:condition: pthread_cond_signal() :保证唤醒一个线程的wait pthread_cond_broadcast() : 唤醒所有线程的wait pthread_cond_wait() : 等待条件变量的signal or broadcast。 条件变量不保存状态信息,signal时如果没有线程在等待,则会丢失该signal,如果
union内部的变量不能有构造函数 union内部包含的变量只能是纯c的struct,不能有构造函数,比如:struct data1 { uint32_t a = 0; uint32_t b = 0;};struct data2 { uint32_t a;};struct area { uint32_t num; union { data1 a; data2 b; }}如...
printf 参数 有些code需要同时在32bit 或者64bit平台上跑,所以printf的时候就会有问题, 比如int64_t, 在32bit平台上打印为%lld,但是在64平台上打印为%ld, 所以,造成兼容性问题,现在可以用%j来代替,如下: 1.对于64bit number, 使用%jd或者%ju 2.对于size_t ssize_t 类型,使用%z, 比如size_t–>%zu, ssize_t –
backup python 学习网站 https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/0014316090478912dab2a3a9e8f4ed49d28854b292f85bb000
fedora重新build rpm软件安装包 将软件安装包的src.rpm的安装包考到home目录下,然后按照后面的流程重新build安装 sudo dnf-builddep ~/name.src.rpm rpmbuild –rebuild name.src.rpm you will find your software rpm in ~/rpmbuild/RPMS/$(uname -m) sudo dnf update name.
fedora 安装与系统升级 最近将系统从22升级到25。步骤记录如下: 1.、更新系统 sudo dnf update –refresh 2、安装插件 sudo dnf install dnf-plugin-system-upgrade 3、下载Fedora25版本的更新包 sudo dnf system-upgrade download –releasever=25 –allowerasing (如果某些依赖不
Linux系统编程第14章-系统编程概念 1.设备文件: Linux系统中每个设备都有设备驱动程序,是内核的一部分。由驱动程序提供的api是固定的,一般都包括open,close,read,write,mmap,ioctl等,这样可以保证IO借口的通用性。IOCTL可以提供对特定设备的特定操作,可以自己定义ioctl命令,来实现对设备的特殊操作。不管是真实的设备还是虚拟的设备,都有一样的设备驱动程序。设备驱动程序可以分为两类:字符型设备基
Linux系统编程第13章-文件I/O缓冲 1.对于IO,内核会维持一个缓冲,当调用read或者write系统调用时,不是直接写入磁盘或者从磁盘读取,而是先写入内核缓冲区,或者从内核缓冲区读取,内核会找合适的时机将缓冲区的数据写入磁盘。这样就可以减少磁盘操作,实现系统调用的快速返回。 2.stdio库的缓冲: 标准C语言的IO函数库stdio在user space提供了一个cache,用来减少系统调用的次数。当调用stdio的函数库比如f
Linux系统编程第12章-系统和进程信息 1.本章介绍通过/proc文件系统获取系统和进程的一些信息。还介绍了uname()系统调用,用于获取各种系统标识。 2./proc文件系统: Linux系统提供了/proc虚拟文件系统,用来给用户层提供系统内核和进程的一些信息,并提供普通文件的IO访问方式。该虚拟文件系统不是存储在硬盘上,而是随程序的运行自动创建和消除的虚拟文件。 a./proc/PID目录 对于系统中的每个进程,都提供了相
Linux系统编程第11章-系统限制和选项 1.Linux系统会有各种资源的限制,比如说一个进程能同时打开多少文件等,编程的时候需要注意不能超出这些限制。本章就讨论系统提供的一些系统调用,来获取各种资源的限制。三个系统调用为: sysconf(),pathconf(), fpathconf(),还有一些资源变量的最大值定义在limit.h头文件中。 2.sysconf()函数的用法在P174.可以在程序中调用该系统调用获取资源的限制值。#
linux系统编程第10章-时间 0.时间定义: 真实时间:度量真实时间的起点有两种,一为某个标准点,称为日历时间(calendar),比如UTC时间。二为进程周期的某个固定点,一般为程序启动的时间点,称为流逝时间(elapse)或者墙上时间(wall clock)。 进程时间:一个进程所使用的cpu时间总量。 1.日历时间: 系统调用gettimeofday()可以获取日历时间。#include<sys/time.h>i
Linux系统编程手册第9章-进程凭证 1.各个进程的各种ID,称为进程凭证。如UID,GID等。具体有实际用户ID(real user ID), 实际组ID(real group ID),有效用户ID(effective user ID),有效组ID(effective group ID),保存的set-user-ID和set-group-ID,文件系统用户ID和文件系统组ID,辅助组ID。 2.实际用户id和实际组id: 这两个I
linux编程手册第8章用户和组 1.密码文件:/etc/passwd 该文件保存了各个用户的一些信息,按顺序包括:登录名,经过加密的密码,用户ID(UID),组ID(GID),注释,主目录,登陆shell,用冒号分隔。 登陆名:登陆系统时,输入的唯一登陆名。 经过加密的密码:该字段包含的是经过加密处理的密码,长度为13个字节。如果启用了shadow密码(常规做法),则该字段一般为x,真正的加密密码存放在/etc/shadow
Linux 系统编程手册第7章-内存分配 1.在堆上分配内存: a.所谓堆,是一段长度可变的连续虚拟内存。开始于进程未初始化数据段末尾。通常将堆的当前边界称为program break。系统提供两个函数来调整program break,#inclue<unistd.h>int brk(void *end_data_segment); //return 0 success, -1 error brk函数调整program break为en
Linux系统编程手册-进程-6章 1.进程是由内核定义的抽象的实体,该实体分配用以执行程序的各种资源。 2.每个进程都有一个进程号pid。有些系统调用可以使用pid作为输入参数,比如kill()系统调用,允许调用者向某一个特定进程发送信号。头函数unistd.h中 pid_t getpid(void)可以返回该进程的pid。 3.每个进程都有一个父进程号ppid。unistd.h中pid_t getppid(void)可以得到父
用audacity生成一定长度pcm数据并encode成aac audacity可以生成一定长度或者是一定字节数的静音数据或者噪声数据。点击“生成”选项,下面有静音或者噪声数据,弹出对话框之后可以选择时间长度或者是字节数,然后点击文件–>导出选择的音频。就会导出pcm文件。 2.利用ffmpeg encode成aac数据,命令为 ffmpeg -strict -2 -i noise.pcm -acodec aac -strict -2 noise.aac
Linux常用命令 1.egrep -RHn “encode” ./ 说明:egrep 是grep -E的功能,./表明搜索当前目录下所有文件。-rn说明列出行号和递归检索。具体参数可以参考grep -h 2.命令后面跟着&是放在后台执行,然后可以通过jobs命令来查看各个任务的任务号(num),通过fg %num来指定将哪个任务放在前台,或者某个任务被ctrl+z挂起后,也可以用bg %num放在后台继续执行。
git & repo 命令总结 git stash 可用来暂存当前正在进行的工作, 比如想pull 最新代码, 又不想加新commit, 或者另外一种情况,为了fix 一个紧急的bug, 先stash, 使返回到自己上一个commit, 改完bug之后再stash pop, 继续原来的工作。 基础命令:$git stash$do some work$git stash pop进阶: Git stash save “wor
git:rebase总结: rebase命令: 参考: http://blog.chinaunix.net/uid-27714502-id-3436696.html http://blog.csdn.net/hudashi/article/details/7664631/1.git branch一般的设置 git在本地最好创建一个master的branch,用来和server的branch同步,然后再创建一个dev b
Linux/Unix系统编程手册二:系统编程概念 系统调用: a.系统调用会将处理器从用户态切换到核心态。以便cpu访问到受保护的内核内存。 b.一般系统调用会有一个c语言外壳函数,便于用户使用。一般linux使用的外壳函数为glibc。外壳函数会帮助用户执行一系列系统调用的步骤,复制参数到指定的寄存器,执行中断机器指令(int 0x80),根据系统调用的返回值设置errno的值。 c.在Linux一般惯例中,系统调用调用失败一般返回一个负值
eclipse配置方法 1.配置toolchain 1.安装arm linux工具: help –>Eclipse Marketplace –>搜索 arm linux –>安装GNU ARM Eclipse 3.4.1 项目—> 属性—–>c/c++builder——>setting—–>toolchains—->toolchain path—–>project—>选择toolchain folder 在tool
常用linux调试方法(包括kernel和app) 当在linux编程中遇到segmentation fault的时候,可以利用core dump文件来debug,方法如下: 1. 在程序运行目录下(嵌入式设备最好是sdcard上面,因为core文件比较大)利用ulimit命令来修改core dump文件的大小。ulimit -a 可以查看ulimit命令的选项。会发现-c是core file size . 我们可以利用ulimit -c unli
欢迎使用CSDN-markdown编辑器 欢迎使用Markdown编辑器写博客本Markdown编辑器使用StackEdit修改而来,用它写博客,将会带来全新的体验哦:Markdown和扩展Markdown简洁的语法代码块高亮图片链接和图片上传LaTex数学公式UML序列图和流程图离线写博客导入导出Markdown文件丰富的快捷键快捷键加粗 Ctrl + B 斜体 Ctrl + I 引用 Ctrl