Jack Huang's Blog


  • 首页

  • 标签

  • 归档

  • 搜索

JavaScript对象深度克隆

发表于 2019-10-10

JavaScript并没有提供对象的复制方法,只能借助第三方库或自己实现对象的深度克隆。具体方法如下:

第三方库实现

实现JavaScript库的深度克隆的第三方库主要有:

  • Underscore —— _.clone()
  • jQuery —— $.clone() / $.extend()
  • lodash —— _.clone() / _.cloneDeep()
  • 借助 JSON 全局对象

Underscore —— _.clone()

在 Underscore 中有这样一个方法:_.clone(),这个方法实际上是一种浅复制 (shallow-copy),所有嵌套的对象和数组都是直接复制引用而并没有进行深复制。其代码如下:

1
2
3
4
5
// Create a (shallow-cloned) duplicate of an object.
_.clone = function(obj) {
if (!_.isObject(obj)) return obj;
return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
};

jQuery —— $.clone() / $.extend()

在 jQuery 中也有这么一个叫 $.clone() 的方法,可是它并不是用于一般的 JS 对象的深复制,而是用于 DOM 对象。与 Underscore 类似,可以通过 $.extend() 方法来完成深复制。值得庆幸的是,在 jQuery 中可以通过添加一个参数来实现递归extend。调用$.extend(true, {}, …)就可以实现深复制。

1
2
3
4
5
6
7
8
9
10
11
var x = {
a: 1,
b: { f: { g: 1 } },
c: [ 1, 2, 3 ]
};

var y = $.extend({}, x), //shallow copy
z = $.extend(true, {}, x); //deep copy

y.b.f === x.b.f // true
z.b.f === x.b.f // false

lodash —— _.clone() / _.cloneDeep()

在lodash中关于复制的方法有两个,分别是.clone()和.cloneDeep()。其中.clone(obj, true)等价于.cloneDeep(obj)。

借助 JSON 全局对象

针对纯 JSON 数据对象的深复制,使用 JSON 全局对象的 parse 和 stringify 方法来实现深复制也算是一个简单讨巧的方法,但它能正确处理的对象只有 Number, String, Boolean, Array, 扁平对象,即那些能够被 json 直接表示的数据结构。

1
2
3
4
function jsonClone(obj) {
return JSON.parse(JSON.stringify(obj));
}
var clone = jsonClone({ a:1 });

递归实现

下面是递归实现对象深度克隆的可用方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
function clone(obj) {
// Handle the 3 simple types, and null or undefined
if (null == obj || "object" != typeof obj) return obj;

// Handle Date
if (obj instanceof Date) {
var copy = new Date();
copy.setTime(obj.getTime());
return copy;
}

// Handle Array
if (obj instanceof Array) {
var copy = [];
for (var i = 0, var len = obj.length; i < len; ++i) {
copy[i] = clone(obj[i]);
}
return copy;
}

// Handle Object
if (obj instanceof Object) {
var copy = {};
for (var attr in obj) {
if (obj.hasOwnProperty(attr)) copy[attr] = clone(obj[attr]);
}
return copy;
}

throw new Error("Unable to copy obj! Its type isn't supported.");
}

参考链接

  1. 深入剖析 JavaScript 的深复制,by 咀嚼之味.
  2. 深入理解JavaScript中的对象复制(Object Clone),by jingxian.
  3. JavaScript语言精粹(修订版),by Douglas Crockford著.

图片或多媒体大文件的存储与管理

发表于 2019-10-10 | 更新于 2019-10-11

图片、声音、视频等大文件在后台数据库中的存储管理方式通常有两种:

  • 文件存储到数据库中
  • 文件存储到文件系统中,数据库中保存文件路径

这两种文件存储管理方式有各自优缺点, 选择哪种方法存储大文件应根据具体情况而定。

文件系统存储管理方式

文件系统存储管理方式将文件存储到磁盘中,在数据库中使用varchar类型记录文件路径。该方法的缺点主要有:

  • 文件不支持DELETE

当删除文件路径时,不支持自动删除对应文件。

  • 文件不支持事务隔离

如果改变文件内容或删除文件,这些操作将立刻被其他客户端看到。

  • 文件不支持回滚

数据库记录能够恢复,但文件删除不能。

  • 文件不支持数据库的备份工具

  • 文件不支持SQL的访问权限设置

  • 文件不是SQL数据类型

数据库不会验证文件路径是否有效。当文件移动、重命名、删除时,数据不会自动更新路径。

数据库中存储文件

数据库通常支持BLOB类型,可用于存储任何二进制数据。数据库中存储文件,其优点对应文件系统管理存储方式的缺点。同样,数据库中存储文件也存在一些缺点:

  • 对数据库的读/写的速度永远都赶不上文件系统处理的速度
  • 数据库备份变的巨大,越来越耗时间
  • 对文件的访问需要穿越你的应用层和数据库层

多媒体大文件存储建议

当只涉及较小规模图片、音频的存储时,建议直接存放到数据库中。当涉及视频大文件存储时,建议还是用文件系统存储。

参考链接

  1. SQL反模式,by Bill karwin著, 谭振林, Push Chen译.
  2. 特殊格式文件(视频、声音等) 在数据库中的存储方式,by Jesson.
  3. 关于图片或者文件在数据库的存储方式归纳,by 王滔.
  4. SQL Server 2008新特性——FILESTREAM,by 曾毅.
  5. oracle对大对象类型操作:blob,clob,nclob,bfile,by lxy2330.
  6. 类似优酷土豆视频网站的视频源文件一般是存储在什么样系统上?,by zhihu.
  7. How to add hours to current date in SQL Server?,by stackoverflow.

Windows下QT与OSG开发环境配置

发表于 2019-10-10 | 更新于 2022-10-25

最近想尝试使用QT开发图形用户界面,OSG负责三维展示的解决方案,于是研究了一下Windows下OSG的编译安装配置,以及在QT中集成OSG的配置过程。过程记录如下:

QT+OSG开发环境配置

QT+OSG开发环境配置将使用QT Creator集成环境进行图形用户界面开发,使用Desktop Qt 5.9.8 MSVC2017 64构建套件编译链接调试C++程序。

Visual Studio Community 2017 下载安装

下载安装Visual Studio Community 2017的“使用C++的桌面开发”工作负载。这将为QT提供MSVC2017 64bit编译套件。

CDB 调试器下载安装

没有安装CDB调试器,QT的Desktop Qt 5.9.8 MSVC2017 64构建套件前会出现感叹号,并且使用该构建套件调试时会报“Unable to create a debugging engine”错误。CDB调试器下载安装方法参考QT - OSG 开发环境配置

QT 5.9.8 下载安装

QT 5.9.8是 LTS 版本,其下载安装请参考Qt5配置开源GSL数学库。需要注意的是,QT 5.9.8安装过程,选择MSVC2017 64bit编译组件,如图1所示。

QT 5.9.8安装选择MSVC2017 64bit编译组件

图1 QT 5.9.8安装选择MSVC2017 64bit编译组件

cmake下载安装

到 cmake 官网下载安装 cmake,用于osg的编译安装。

下载编译安装OSG

下载OSG及相关软件

Windows平台编译安装OSG需下载从OSG官网以下资料:

  • OpenSceneGraph 3.6.4源代码
  • OpenSceneGraph-Data-3.4.0,因为找不到3.6.4版本的数据
  • 3rdParty_VS2017_v141_x64_V11_full

配置OSG

打开cmake,选择osg源代码路径和osg源代码构建的路径,再点击“configure”按钮,选择Visual Studio 15 2017 Win64编译套件,配置osg如图2所示。

cmake编译osg配置

图2 cmake编译osg配置

需要配置的地方主要有:

  • ACTUAL_3rdparty_DIR:配置第三方库的目录
  • Build_OSG_EXAMPLES:选中即编译安装OSG的示例。
  • CMAKE_INSTALL_PREFIX:设置OSG的安装目录,通常放到C盘以外的地方,防止因权限问题安装失败。

配置完成后,再持续点击“configure”按钮,知道红色警告消失。然后点击“Generate”按钮生成vs2017工程。

编译OSG

在cmake中点击“Open Project”按钮,即使用 VS2017 打开 build 文件夹下的工程,点击:生成 -> 批生成 -> 生成 Debug 和 Release 版本的 All_BUILD 即可。

安装OSG

右击解决方案的 Install 项目,点击生成,然后 Debug 平台的库文件就开始安装了,同理选择 Release 平台再重复安装。之后就可以在安装路径中看到编译的库文件了,安装路径由变量CMAKE_INSTALL_PREFIX的配置决定。

配置环境变量

OSG官方文档 Windows Compiling with Visual Studio指出,OSG安装完成后需要配置如下环境变量:

1
2
3
4
5
6
7
8
OSG_ROOT points to the base of the OSG file structure (the directory that contains include, src etc. subdirectories)
OSG_BIN_PATH = %OSG_ROOT%\bin
OSG_INCLUDE_PATH = %OSG_ROOT%\include
OSG_LIB_PATH = %OSG_ROOT%\lib
OSG_SAMPLES_PATH = %OSG_ROOT%\share\OpenSceneGraph\bin
OSG_FILE_PATH = ???\OpenSceneGraph-Data-X.X
OPENSCENEGRAPH_VERSION = 3.6.4
PATH 添加:%OSG_ROOT%\bin;%OSG_ROOT%\bin\osgPlugins-%OPENSCENEGRAPH_VERSION%; 这两个是配置 bin 和插件的路径。

OSG测试

命令行测试

打开 cmd 命令行,输入osgversion,输出当前 osg 版本说明环境变量配置成功了,再来看看能不能导入模型文件,接着键入:

1
osgviewer cow.osg

这里可能会提示系统缺少 zlibd.dll,解决方法很简单:

  • 拷贝第三方库的 dll 目录下的 zlib.dll 和 zlibd.dll 到 OSG 安装目录的 bin 目录中。
  • 拷贝第三方库的 lib 目录下的 zlib.dll 和 zlibd.dll 到 OSG 安装目录的 lib 目录中。

这时重新键入上面的命令,就可以看到一头经典的 3D 牛了,说明 OSG 安装成功了。

QT 配置 OSG 库路径

新建一个 QT 的控制台项目,编辑 .pro 文件,加入 OSG 库的路径:

1
2
3
4
5
6
win32:CONFIG(release, debug|release): LIBS += -L$$PWD/../../../OpenSceneGraph/lib/ -lOpenThreads -losg -losgDB -losgUtil -losgGA  -losgViewer -losgText
else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/../../../OpenSceneGraph/lib/ -lOpenThreadsd -losgd -losgDBd -losgUtild -losgGAd -losgViewerd -losgTextd
else:unix: LIBS += -L$$PWD/../../../OpenSceneGraph/lib/ -lOpenThreads -losg -losgDB -losgUtil -losgGA -losgViewer -losgText

INCLUDEPATH += $$PWD/../../../OpenSceneGraph/include
DEPENDPATH += $$PWD/../../../OpenSceneGraph/lib

main.cpp 如下:

1
2
3
4
5
6
7
8
9
#include <osgViewer/Viewer>
#include <osgDB/ReadFile>

int main(int argc, char *argv[])
{
osgViewer::Viewer viewer;
viewer.setSceneData(osgDB::readNodeFile("cow.osg"));
return viewer.run();
}

运行,出来一头 3D 牛,即配置成功。

参考链接

  1. QT - OSG 开发环境配置,by 程序小哥.
  2. Qt5配置开源GSL数学库,by jackhuang.
  3. Ubuntu16.04编译安装OSG,by jackhuang.
  4. Windows Compiling with Visual Studio,by OpenSceneGraph.
  5. Visual_Studio_Community_2017离线安装,by jackhuang.
  6. Qt-Creator常见问题,by XenonSec.
  7. Visual Studio: MSB3073 error exited with code 1,by stackoverflow.
  8. Qt5.7 + VS2015 环境搭建,by 一去丶二三里.
  9. OSG学习:WIN10系统下OSG+VS2017编译及运行,by 路人甲JIA.
  10. error LNK2019: 无法解析的外部符号 “__declspec(dllimport) public,by OSG_weiguoying.
  11. 应用篇之dll lib pdb和头文件,by 阿兵-AI医疗.
  12. GL.h文件提示报错,by Parkergh.
  13. #undef 的用法及其意义,by DinnerHowe.

Windows忘记密码无法登录的解决方案

发表于 2019-10-09 | 更新于 2019-10-10

突然需要在一台很久不用的Win7计算机上差一点资料,可忘记了登录密码,只能重置密码。过程记录如下:

解决思路

借助手头的一张linux live cd,从光盘启动,进入linux系统,然后找到windows系统盘分区,在C:\Windows\System32下,将cmd.exe重命名为Magnify.exe,然后系统重启,登录Windows操作系统,在登录界面中,调用辅助工具放大镜,即打开命令提示符,输入如下命令重置Windows账户密码:

1
2
3
4
5
6
// 查看Windows账户
net user
// 修改Windows账户密码
net user Administrator 123456
// 重启系统用Administrator账户登录
shutdown -r -t 00

或者采用如下命令新建登录账户:

1
2
3
4
5
6
// 创建用户
net user test 123456 /add
// 用户提权,加入管理员组
net localgroup Administrators test /add
// 使用完删除用户
net user test /delete

参考链接

  1. 关闭windows默认共享,by Blue_sky90.

Qt5配置开源GSL数学库

发表于 2019-10-07 | 更新于 2021-04-28

GNU科学库(英语:GSL - GNU Scientific Library),是一套为 C语言和 C++开发者提供的数值计算函数库,多用于应用数学和科学。软件属于自由软件,在 GNU 通用公共许可证下发布。

这套数值计算函数库提供了大量的数学运算功能,比如随机数生成器,特殊函数以及最小二乘拟合。有超过1000个函数包含在该数值计算库和扩展的测试包中。

下面介绍在Qt5环境中搭载GSL库的方法和步骤。

下载并安装Qt5

下载Qt5请参考Qt下载(多种下载通道+所有版本)。将下载并安装Qt5.9.8 LTS。

安装Qt5请参考图解Qt安装(Windows平台)。

环境配置

MinGW环境配置

MinGW(Minimalist GNU for Windows),又称mingw32,是将GCC编译器和GNU Binutils移植到Win32平台下的产物,包括一系列头文件(Win32API)、库和可执行文件。

另有可用于产生32位及64位Windows可执行文件的MinGW-w64项目,是从原本MinGW产生的分支。如今已经独立发展。

MinGW是从Cygwin(1.3.3版)基础上发展而来。Qt5.9.8使用MinGW 5.3编译器编译程序。

将mingw的bin目录添加进系统的环境变量,告诉系统已经安装了mingw编译器,并且可以被使用。Qt5自带的mingw的安装路径为C:\Qt\Qt5.9.8\5.9.8\mingw53_32,这里我们需要将C:\Qt\Qt5.9.8\5.9.8\mingw53_32\bin目录添加进入系统环境变量。

系统环境变量的设置方法为:【计算机】->【属性】->【高级系统设置】->【环境变量】->【系统变量】->【Path】。

MSYS环境配置

MSYS是bash,make,gawk和grep等GNU实用程序的集合,以允许构建依赖于传统UNIX工具的应用程序和程序。 它旨在补充MinGW和cmd shell的缺陷。

一个示例是构建一个使用自动工具构建系统的库。 用户通常会先运行“ ./configure”,然后运行“ make”来构建它。 配置外壳程序脚本需要Windows系统上不存在的外壳程序脚本解释器,但由MSYS提供。

一个常见的误解是MSYS是“ Windows上的UNIX”,MSYS本身不包含编译器或C库,因此不能将UNIX程序神奇地移植到Windows上,也不能提供任何特定于UNIX的功能,例如case- 敏感文件名。 寻找此类功能的用户应改用Cygwin或Microsoft的Interix。

msys的下载网址为:

msys+7za+wget+svn+git+mercurial+cvs-rev13.7z

上述网址给出的是一个压缩包,直接解压就可以使用。

将msys+7za+wget+svn+git+mercurial+cvs-rev13.7z解压到C:\Qt\Qt5.9.8\5.9.8\mingw53_32。

仅将msys解压后并不能直接使用,因为对于msys而言,它还不知道mingw编译器所处位置,因此需要对msys的环境进行配置。首先需要在msys的路径下创建一个名为mingw的空文件夹,路径为C:\Qt\Qt5.9.8\5.9.8\mingw53_32\msys\mingw。然后修改
C:\Qt\Qt5.9.8\5.9.8\mingw53_32\msys\etc\fstab中的内容,如下所示。

1
C:/Qt/Qt5.9.8/Tools/mingw530_32 /mingw

通过上述环境配置,当启动msys时,将Qt5的mingw编译直接挂载到/mingw目录下。

双击msys文件夹下msys.bat即可运行msys,使用cd命令进入/mingw目录下,我们就会发现此目录下文件就是C:\Qt\Qt5.9.8\Tools\mingw530_32对应的文件。

跳转到gsl-2.6文件夹,即可开始编译链接gsl。

下载并编译安装GSL

从此处 http://ftpmirror.gnu.org/gsl/ 下载最新的GSL-2.6。然后采用如下步骤编译GSL:

  1. 运行msys,进入GSL源文件所在目录
  2. ./configure
  3. make -j8
  4. make install

Qt调用GSL库

创建Qt工程

为了测试GSL数学库能够在Qt环境中运行,新建一个控制台工程进行测试。

新建控制台应用程序的步骤为:【Welcome】->【New Project】->【Application】->【Qt Console Application】->【Choose】->【将工程命名为GslTest】。

引用GSL库

在GslTest项目的工程目录内,新建名为gsl的文件夹。该文件夹的内容如图1所示。

gsl文件夹结构

图1 gsl文件夹结构

gsl文件夹下lib、include、bin中内容为编译安装GSL过程中生成的头文件、库文件及生成的相关exe文件,主要从C:\Qt\Qt5.9.8\5.9.8\mingw53_32\msys路径下提取。

此外,在gsl目录下新建gsl.pro文件,其内容如下:

1
2
3
4
5
# 宏定义项,指明采用GSL,因为有些函数需要使用dll
DEFINES += GSL_DLL
INCLUDEPATH += $$PWD\include
LIBS += -L$$PWD\lib -llibgsl
LIBS += -L$$PWD\lib -llibgslcblas

然后在GslTest的项目文件GslTest.pro末尾引用gsl.pro文件,如下所示。

1
include($$PWD/gsl/gsl.pro)

修改GslTest的main.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <QCoreApplication>
#include <gsl/gsl_sf_bessel.h>
#include <math.h>
#include <iostream>

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
double x=10.0;
double y=gsl_sf_bessel_J0(x);
std::cout<<"J0("<<x<<")="<<y<<std::endl;

return a.exec();
}

运行GslTest

GslTest运行结果

图2 GslTest运行结果

参考链接

  1. Qt下载(多种下载通道+所有版本),by C语言中文网.
  2. 图解Qt安装(Windows平台),by C语言中文网.
  3. GSL - GNU Scientific Library,by gnu.
  4. QT5环境下配置GSL数学库,by 木小猿.
  5. GNU科学库,by wikipedia.
  6. 【ICPC-455】C++ 常用数学函数库,by 陈国林.
  7. MinGW,by wikipedia.
  8. MinGW和MSYS区别和关系以及MinGW&MSYS在Win7中安装并编译x264,by FreeApe.
  9. 最强数学库GSL(GNU Scientific Library) Qt环境下部署,by 尘中远.
  10. Qt5.9.6使用MSVC(VS2017)开发环境搭建,by KirkSong.
  11. QT - OSG 开发环境配置,by 程序小哥.
  12. GSL with CMake build support,by ampl.
  13. 在Visual Studio中使用GNU Scientific Library (GSL),by NULL_BOT.

C++多继承的优缺点

发表于 2019-10-05 | 更新于 2022-12-02

C++中子类可继承多个父类。多继承对父类的个数没有限制,继承方式可以是公共继承、保护继承和私有继承,不写继承方式,默认是private继承。C++多继承语法非常灵活,使用得当可极大提高编程效率,但同时不能其潜在的缺点:

  • 如果一个类继承多个父类,如果父类中的方法名如果相同,那么就会产生歧义。
  • 如果父类中的方法同名,子类中没有覆盖,同样会产生上面的错误。

针对上述缺点,C#和Java中都不支持类多继承,而是使用类单继承和接口多继承设计替代类多继承。

继承类型

当一个类派生自基类,该基类可以被继承为 public、protected 或 private 几种类型。继承类型是通过上面讲解的访问修饰符 access-specifier 来指定的。

我们几乎不使用 protected 或 private 继承,通常使用 public 继承。当使用不同类型的继承时,遵循以下几个规则:

  • 公有继承(public):当一个类派生自公有基类时,基类的公有成员也是派生类的公有成员,基类的保护成员也是派生类的保护成员,基类的私有成员不能直接被派生类访问,但是可以通过调用基类的公有和保护成员来访问。
  • 保护继承(protected): 当一个类派生自保护基类时,基类的公有和保护成员将成为派生类的保护成员。
  • 私有继承(private):当一个类派生自私有基类时,基类的公有和保护成员将成为派生类的私有成员。

参考链接

  1. 论C#之多继承,by Leo.
  2. 接口和抽象类有什么区别?,by zhihu.
  3. java类单继承,接口多继承设计的原因,by xiaoxiang-chen.
  4. C++学习之继承篇(多继承与多重继承),by hudfang.
  5. C++ 继承访问权限控制(public,protected,private),by c++入门与提高.
  6. c++ 类受保护成员的访问,by hudie66fei.

GUI开发方案总结

发表于 2019-10-03 | 更新于 2019-10-04

最近调研GUI开发技术,对相关资料总结一下。

Windows 下的 GUI 库

Windows 下的 GUI 解决方案比较多:

  • 基于 C++ 的有 Qt、MFC、WTL、wxWidgets、DirectUI、Htmlayout;
  • 基于 C# 的有 WinForm、WPF;
  • 基于 Java 的有 AWT、Swing;
  • 基于 Pascal 的 有Delphi;
  • 基于Go语言的有 walk 和 electron;
  • 还有国内初露头角的 aardio;
  • Visual Basic 曾经很流行,现在逐渐失去了色彩;
  • 如果你有 Web 开发经验,也可以基于 Webkit 或 Chromium 将网页转换为桌面程序。

没有哪一种方案能够独霸 Windows,使用比较多的编程语言是 C++、C#、Java。

Linux 下的 GUI 库

Linux 下常用的 GUI 库有基于 C++ 的 Qt、GTK+、wxWidgets,以及基于 Java 的 AWT 和 Swing。其中最著名的就是 Qt 和 GTK+:KDE 桌面系统已经将 Qt 作为默认的 GUI 库,Gnome 桌面系统也将 GTK+ 作为默认的 GUI 库。

参考链接

  1. Qt和其它GUI库的对比,by C语言中文网.
  2. Qt,by wikipedia.
  3. Qt下载(多种下载通道+所有版本),by C语言中文网.
  4. Qt镜像站下载,by 中科大镜像站.

VS2017打包Windows桌面程序

发表于 2019-09-26 | 更新于 2022-07-30

Microsoft Visual Studio 2017 Installer Projects是一个易于发布 VS 项目的官方插件,下面简要介绍该插件的使用。

安装插件

VS 工具栏 > 工具 > 扩展和更新 > 联机 > 搜索 Microsoft Visual Studio 2017 Installer Projects 并安装。安装完成后需要重启 VS。

添加 Setup Project

打开VS2017,新建Setup Project。

配置安装项目

设置Setup Project

选中添加的Setup Project,配置其属性。比较重要的属性有:

key val
Author 一般填公司名,会使用其作为软件安装目录名
Localization 指定软件运行地语种,如果你的软件是多语言的话
TargetPlatform 指定软件目标平台 x86 or x64
Version 发布版本号

桌面快捷方式

开始菜单快捷方式

设置快捷方式Icon

生成安装文件.msi

参考链接

  1. Microsoft Visual Studio 2017 Installer Projects,by SkyRiN.
  2. Vistual Studio Community 2017 30天许可证过期,by 井底一蛤蟆.

Windows下安装Pytorch过程记录

发表于 2019-09-24

PyTorch是一个开源的Python机器学习库,基于Torch,底层由C++实现,应用于人工智能领域,如自然语言处理。它最初由Facebook的人工智能研究团队开发,并且被用于Uber的概率编程软件Pyro。

PyTorch主要有两大特征:

  • 类似于NumPy的张量计算,可使用GPU加速;
  • 基于带自动微分系统的深度神经网络;

下面记录在Windows操作系统下安装PyTorch的方法。

安装Anaconda

到Anaconda Distribution下载合适的Anaconda。

查看cuda版本

参考Windows系统查看CUDA版本号。例如本机cuda版本为9.2。

安装pytorch

进入pytorch官网的GET STARTED,根据自身计算机环境,选择PyTorch Build、Your OS、Package、Language和CUDA,即得到安装pytorch的命令:

1
2
3
4
// 基于Anaconda
conda install pytorch torchvision cudatoolkit=9.2 -c pytorch -c defaults -c numba/label/dev
// 基于Python3.6
pip3 install torch==1.2.0+cu92 torchvision==0.4.0+cu92 -f https://download.pytorch.org/whl/torch_stable.html

pip安装whl包

torch1.2的包很大,直接用pip安装下载很慢,可以先用下载工具将torch1.2的whl下载下来,再直接安装。

1
pip3 install torch-1.2.0+cu92-cp36-cp36m-win_amd64.whl

验证

打开命令提示符,输入:

1
python

输入如下代码,查看输出:

1
2
3
4
from __future__ import print_function
import torch
x = torch.rand(5, 3)
print(x)

输出类似如下结果:

1
2
3
4
5
tensor([[0.3380, 0.3845, 0.3217],
[0.8337, 0.9050, 0.2650],
[0.2979, 0.7141, 0.9069],
[0.1449, 0.1132, 0.1375],
[0.4675, 0.3947, 0.1426]])

输入如下代码,验证GPU驱动和CUDA是安装正确,能够被PyTorch访问:

1
2
import torch
torch.cuda.is_available()

参考链接

  1. CUDA,by wikipedia.
  2. Windows 下安装Pytorch,by Big_quant.
  3. Windows系统查看CUDA版本号,by 潇洒坤.
  4. PyTorch,by wikipedia.
  5. GET STARTED,by pytorch.
  6. Getting Started with Python in VS Code,by visualstudio.

JS如何从ArrayBuffer中解码字符串

发表于 2019-09-24

最近遇到一个问题,拿到一个ArrayBuffer,知道它是以gb2312编码的文档,那么如何使用javascript从中解码出字符串。下面介绍常用的解决方案。

基础知识

字符编码

字符编码(英语:Character encoding)、字集码是把字符集中的字符编码为指定集合中某一对象(例如:比特模式、自然数序列、8位组或者电脉冲),以便文本在计算机中存储和通过通信网络的传递。常见的例子包括将拉丁字母表编码成摩斯电码和ASCII。其中,ASCII将字母、数字和其它符号编号,并用7比特的二进制来表示这个整数。通常会额外使用一个扩充的比特,以便于以1个字节的方式存储。

因此,如果不知道字符存储的编码方案,那么只能得到一堆无意义的数字,无法从中解码出正确的字符信息。

ArrayBuffer

ArrayBuffer对象、TypedArray对象、DataView对象是JavaScript操作二进制数据的一个接口。这些对象早就存在,属于独立的规格,ES6将它们纳入了ECMAScript规格,并且增加了新的方法。

这些对象原始的设计目的,与WebGL项目有关。所谓WebGL,就是指浏览器与显卡之间的通信接口,为了满足JavaScript与显卡之间大量的、实时的数据交换,它们之间的数据通信必须是二进制的,而不能是传统的文本格式。文本格式传递一个32位整数,两端的JavaScript脚本与显卡都要进行格式转化,将非常耗时。这时要是存在一种机制,可以像C语言那样,直接操作字节,将4个字节的32位整数,以二进制形式原封不动地送入显卡,脚本的性能就会大幅提升。

二进制数组就是在这种背景下诞生的。它很像C语言的数组,允许开发者以数组下标的形式,直接操作内存,大大增强了JavaScript处理二进制数据的能力,使得开发者有可能通过JavaScript与操作系统的原生接口进行二进制通信。

二进制数组由三个对象组成。

  • ArrayBuffer对象:代表内存之中的一段二进制数据,可以通过“视图”进行操作。“视图”部署了数组接口,这意味着,可以用数组的方法操作内存。

  • TypedArray对象:用来生成内存的视图,通过9个构造函数,可以生成9种数据格式的视图,比如Uint8Array(无符号8位整数)数组视图, Int16Array(16位整数)数组视图, Float32Array(32位浮点数)数组视图等等。

  • DataView对象:用来生成内存的视图,可以自定义格式和字节序,比如第一个字节是Uint8(无符号8位整数)、第二个字节是Int16(16位整数)、第三个字节是Float32(32位浮点数)等等。

简单说,ArrayBuffer对象代表原始的二进制数据,TypedArray对象代表确定类型的二进制数据,DataView对象代表不确定类型的二进制数据。它们支持的数据类型一共有9种(DataView对象支持除Uint8C以外的其他8种)。

解决方案

UTF-16的编码解码

下面的解决方案只能解码UTF-16编码的字符串,而且当ArrayBuffer的长度过大时,会报“ Maximum call stack size exceeded”的错误。

1
2
3
4
5
6
7
8
9
10
11
12
function ab2str(buf) {
return String.fromCharCode.apply(null, new Uint16Array(buf));
}

function str2ab(str) {
var buf = new ArrayBuffer(str.length*2); // 2 bytes for each char
var bufView = new Uint16Array(buf);
for (var i=0, strLen=str.length; i < strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
}

gb2312解码

下面的解决方案能解码指定编码的字符串,包括utf-8,utf-16, iso-8859-2, koi8, cp1261, and gbk等。

1
2
3
4
5
function ab2str(arrayBuf, encodeType) {
var decoder = new TextDecoder(encodeType)
var u8arr = new Uint8Array(arrayBuf)
return decoder.decode(u8arr)
}

参考链接

  1. How to convert ArrayBuffer to and from String,by Renato Mangini.
  2. 字符编码,by wikipedia.
  3. Converting arraybuffer to string : Maximum call stack size exceeded,by stackoverflow.
  4. “RangeError: Maximum call stack size exceeded” Why?,by stackoverflow.
  5. TextDecoder,by mozilla.
  6. String.fromCharCode(),by mozilla.
  7. 二进制数组,by 阮一峰.
  8. ArrayBuffer,by 阮一峰.
上一页1…343536…53下一页

Jack Huang

528 日志
68 标签
© 2025 Jack Huang
由 Hexo 强力驱动
|
主题 — NexT.Muse