1 简介

 由于在开发过程中,本来以为抓图项目会部署在Windows服务器上,但随着项目的进行发现项目需要部署在Linux系统,甚至是国产化平台银河麒麟上,但在部署时发现在国产化平台部署时出现缺包的问题无法解决,经过沟通把项目部署在Ubuntu 16.04服务器中。自然这就涉及到使用Java调用海康威视提供的设备网络SDK,即提供的.so文件来实现摄像机抓拍的功能。

1.1 .so文件

 so(Shared Object)是Linux环境下的程序函数库,即编译好的可以供其它程序使用的代码和数据,和Windows系统中的.dll文件差不多。在Linux操作系统中,函数库非常重要,因为很多的软件之间都会互相使用彼此提供的函数库来进行特殊功能的运行,诸如身份验证,SSL函数库进行联机加密。

2 注意事项

2.1 下载

 请移步到海康威视官网下载设备网络SDK_V6.0.2.35(for Linux64)

2.2 目录结构


在当前的Linux设备网络SDK解压之后的目录结构如上图所示,可以看到较为关键的为lib目录, LinuxJavaDemo目录中的HCNetSDK.java文件,以及readme.txt.

2.3 readme.txt

 该文件是Linux调用设备网络SDK的引导文档,具体内容如下:

如果HCNetSDKCom目录以及libhcnetsdk.so、libhpr.so、libHCCore文件和可执行文件在同一级目录下,则使用同级目录下的库文件;
如果不在同一级目录下,则需要将以上文件的目录加载到动态库搜索路径中,设置的方式有以下几种:
一.  将网络SDK各动态库路径加入到LD_LIBRARY_PATH环境变量1.在当前的终端黑窗口直接输入:export  LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/XXX:/XXX/HCNetSDKCom      只在当前终端起作用2. 修改~/.bashrc或~/.bash_profile,最后一行添加 export  LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/XXX:/XXX/HCNetSDKCom,保存之后,使用source  .bashrc执行该文件 ,当前用户生效3. 修改/etc/profile,添加内容如第2条,同样保存之后使用source执行该文件  所有用户生效二.在/etc/ld.so.conf文件结尾添加网络sdk库的路径,如/XXX和/XXX/HCNetSDKCom/,保存之后,然后执行ldconfig 三.可以将网络sdk各依赖库放入到/lib64或usr/lib64下四.可以在Makefile中使用-Wl,-rpath来指定动态路径,但是需要将网络sdk各个动态库都用 –l方式显示加载进来比如:-Wl,-rpath=/XXX:/XXX/HCNetSDKCom -lhcnetsdk  -lhpr –lHCCore –lHCCoreDevCfg –lStreamTransClient –lSystemTransform –lHCPreview –lHCAlarm –lHCGeneralCfgMgr –lHCIndustry –lHCPlayBack –lHCVoiceTalk –lanalyzedata -lHCDisplay推荐使用一或二的方式,但要注意优先使用的是同级目录下的库文件。

需要注意的是在将以上文件的目录加载到动态库搜索路径中时方案一种的三种方法是并列的,只要实现了一种即可,并不需要把三种方法全部执行。在抓图项目启动时,采用了修改/etc/profile配置文件,这样对各个用户均有效。配置的具体过程参见配置LD_LIBRARY_PATH

2.4 设备抓图

 在项目中使用摄像机进行图片抓取使用的是设备网络SDK中的设备抓图来实现的:
参见设备网络SDK压缩包解压之后的开发文档目录下的设备网络SDK编程指南(IPC).pdf,在第五章函数说明有更加准确的介绍。

3 源码实现

3.1 配置LD_LIBRARY_PATH

3.1.1 依赖


首先需要准备好海康威视SDK, 。
可以把该tar包解压到指定目录,比如把tar包放在了/home/sqh目录下。并解压

root@aia-28-T630:/home/sqh# ls
lib  lib.tar
root@aia-28-T630:/home/sqh#

3.1.2 环境变量

确保环境变量${LD_LIBRARY_PATH}目录具有包含上述的目录。

    root@aia-28-T630:/home/sqh# echo ${LD_LIBRARY_PATH}/usr/local/cuda-9.0/lib64:/usr/local/mpich3/lib::/home/sqh/lib:/home/sqh/lib/HCNetSDKCom。

若不包含/home/sqh/lib和/home/sqh/lib/HCNetSDKCom
则需要配置环境变量。
使用root用户修改配置文件/etc/profile

root@aia-28-T630:/home/sqh# vim /etc/profile

在尾部追加如下的内容:

export TOMCAT_HOME=/usr/local/tomcat/apache-tomcat-8.5.38
export CLASSPATH=.:$JAVA_HOME/lib:$TOMCAT_HOME/lib
export PATH=$PATH:$TOMCAT_HOME/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/sqh/lib:/home/sqh/lib/HCNetSDKCom

添加内容的另外一部分为添加的TOMCAT配置环境变量。
使用root权限执行source目录

source /etc/profile

然后执行命令

root@aia-28-T630:/home/sqh# echo ${LD_LIBRARY_PATH}
/usr/local/cuda-9.0/lib64:/usr/local/mpich3/lib::/home/sqh/lib:/home/sqh/lib/HCNetSDKCom。

表示环境变量配置成功

3.2 修改HCNetSDK.java

该JNA映射接口文件在LinuxJavaDemo中的src目录,HCNetSDK.java文件需要导入项目,笔者导入了包`

com.example.screenshot.sdk.

 需要配置Native.loadLibrary(“hcnetsdk”,HCNetSDK.class),第一个参数,确保LD_LIBRARY_PATH已经正确配置并且生效,此时可以使用libhcnetsdk.so文件名中的hcnetsdk完成so文件的载入。

package com.example.screenshot.sdk;import com.sun.jna.*;
import com.sun.jna.examples.win32.GDI32.RECT;
import com.sun.jna.examples.win32.W32API;
import com.sun.jna.examples.win32.W32API.HDC;
import com.sun.jna.examples.win32.W32API.HWND;
import com.sun.jna.ptr.ByteByReference;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.NativeLongByReference;
import com.sun.jna.ptr.ShortByReference;//SDK接口说明,HCNetSDK.dll
public interface HCHetSDK extends Library {//依稀记得”hcnetsdk”可以使用文件名的绝对路径来代替,即也可使用
///”ome/sqh/lib/libhcnetsdk.so”来完成HCNetSDK的实例化。
HCNetSDK INSTANCE = (HCNetSDK) Native.loadLibrary("hcnetsdk",HCNetSDK.class);/***宏定义***///常量public static final int MAX_NAMELEN = 16;  //DVR本地登陆名public static final int MAX_RIGHT = 32;    //设备支持的权限(1-12表示本地权限,13-32表示远程权限)public static final int NAME_LEN = 32;    //用户名长度public static final int PASSWD_LEN = 16;    //密码长度public static final int SERIALNO_LEN = 48;   //序列号长度

3.2.1 Native.loadLibrary

 在HCNetSDK.java文件中定义的HCNetSDK接口继承自Library。如果动态链接库里的函数是以StdCallLibrary,比如kernel32库,则继承StdCallLibrary,默认继承Library。

3.2.2 接口内部定义

 接口内部需要一个公共的静态常量:Instance,通过这个常量,就可以获得这个接口的实例,从而使用该接口的方法,也就是调用外部dll/so的函数。

HCNetSDK INSTANCE = (HCNetSDK) Native.loadLibrary("hcnetsdk",HCNetSDK.class);

第一个参数是动态链接库dll/so的名称,但不带.dll或者.so这样的后缀。这符合JNI的规范,因为带了后缀名就不可以跨操作系统平台了。搜索动态链接库的路径顺序是:先从当前类的当前文件夹找,如果没有找到,再在工程当前文件夹下找win32/win64文件夹,找到后搜索对应的dll文件,如果找不到再到WINDOWS下去搜索,再找不到就报错

java.lang.UnsatisfiedLinkError: Unable to load library

第二个参数则是真实的类型,没什么解释的,不再赘述。

注意:so文件的命名方式为lib**.so,但是在加载.so文件的时候是不需要lib前缀的。

3.2.3 暂未验证的方式

在查询某些博客时发现了如下的解释,但没有验证(参见JNA路径问题–Native.loadLibrary(“NLPIR”, CLibrary.class))
Native.loadLibrary(“NLPIR”, CLibrary.class)会自动去项目的src/main/resources文件夹下寻找系统对应的dll和so。

(根据com.sun.jna.Platform类对应文件夹名)

3.3 编码实现定时抓图

 由于iSC平台并未提供直接对某个摄像头进行抓图的功能接口,因此需要通过Java调用so动态链接库,直接操纵设备进行抓图。
以设备连接为例,程序工作的流程图如下:

设备断开连接类似,不再赘述。

3.3.1 Screenshot.java Controller

该文件负责接收请求,当进行设备连接时,则相应设备开始抓图,断开连接时,取消抓图。

package com.example.screenshot.controller;import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.example.screenshot.common.CommonReturn;
import com.example.screenshot.model.Device;
import com.example.screenshot.sdk.HCNetSDK;
import com.example.screenshot.service.AsyncTask;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.*;/*** 抓图** @Owner: SongQuanHeng* @Time: 2019/3/14-14:44* @Version:* @Change:*/
@RestController
public class ScreenShot {private final static Logger logger = LoggerFactory.getLogger(ScreenShot.class);private Map<String, Device> devices = new HashMap<>();// 在该类中直接引用了HCNetSDK的静态变量INSTANCE,供自己使用static HCNetSDK hCNetSDK = HCNetSDK.INSTANCE;private final List<String> validKeys = new ArrayList<>(Arrays.asList("ip"));@Autowiredprivate AsyncTask asyncTask;@RequestMapping(value = "/connect", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)public String connect(@RequestBody JSONObject param) throws Exception {logger.debug("Enter connect");logger.debug("hCNetSDK: "+hCNetSDK);if (!hasValidKey(param)) {return CommonReturn.httpReturnFailure("参数有误, 请传入监控点IP");}if (devices.isEmpty()) {boolean initSucc = hCNetSDK.NET_DVR_Init();if (!initSucc) {return CommonReturn.httpReturnFailure("SDK初始化失败");}logger.debug("完成SDK初始化");}String ip = getIp(param);if (devices.containsKey(ip)) {return CommonReturn.httpReturnFailure("传入的设备ip已经连接");}logger.debug("ip: "+ip);Device device = new Device(ip);boolean connSucc = device.connect();if (!connSucc) {return CommonReturn.httpReturnFailure("设备链接失败");}device.setConnected(true);devices.put(ip, device);logger.debug("当前连接设备一共有: "+ devices.size());asyncTask.executeAsyncTask(device);return CommonReturn.httpReturnSuccess("设备连接成功");}private String getIp(JSONObject param) {return param.getString("ip").trim();}@RequestMapping(value = "/disconnect", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)public String disconnect(@RequestBody JSONObject param) {if (!hasValidKey(param)) {return CommonReturn.httpReturnFailure("参数有误, 请传入监控点IP");}String ip = getIp(param);if (!devices.containsKey(ip)) {return CommonReturn.httpReturnFailure("传入的IP未连接, 请检查参数");}Device device = devices.get(ip);boolean operSucc = device.disconnect();if (!operSucc) {return CommonReturn.httpReturnFailure("断开连接失败");}devices.remove(ip);if (devices.isEmpty()) {boolean cleanUpSucc =  hCNetSDK.NET_DVR_Cleanup();if (!cleanUpSucc) {printErrInfo("disconnect", "NET_DVR_Cleanup");return CommonReturn.httpReturnFailure("SDK反初始化失败");}}return CommonReturn.httpReturnSuccess("断开连接,"+"设备IP" + ip+"抓拍结束");}@RequestMapping(value = "/getConnectedDevices", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)public String getDevices() {logger.debug("Enter getDevices");JSONObject result = new JSONObject();result.put("size", devices.size());JSONArray ips = new JSONArray();for (String key: devices.keySet()) {ips.add(key);}result.put("ips", ips);return CommonReturn.httpReturnSuccess("获取在线设备成功", result);}private boolean hasValidKey(JSONObject param) {for (String key : validKeys) {if (!param.containsKey(key)){return false;}}return true;}public  void printErrInfo(String inFunc, String afterFunc) {int errCode = hCNetSDK.NET_DVR_GetLastError();logger.debug("In "+inFunc," after Exec "+ afterFunc + " , errCode: "+ errCode);}public int getLastErrCode() {logger.debug("hcNetSDK: " + hCNetSDK);return hCNetSDK.NET_DVR_GetLastError();}
}

3.3.2 AsyncTask异步任务执行类

 该类型主要是负责异步抓图,并保存到指定目录,然后把映射的图片资源以HTTP请求的方式告诉第三方。

package com.example.screenshot.service;import com.alibaba.fastjson.JSONObject;
import com.example.screenshot.config.ServerConfig;
import com.example.screenshot.model.Device;
import com.example.screenshot.sdk.HCNetSDK;
import com.example.screenshot.util.GeneralUtil;
import com.sun.jna.NativeLong;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;import java.io.File;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;/*** 异步任务执行类** @Owner: SongQuanHeng* @Time: 2019/3/14-17:02* @Version:* @Change:*/
@Service
public class AsyncTask {static HCNetSDK hCNetSDK = HCNetSDK.INSTANCE;private static String relativeDir = File.separator+"Img"+File.separator;private static String imageLocation;static {String dir = GeneralUtil.getRootDir();File file = new File(dir);
// 用来放置抓图的路径,并且把路径映射成了静态资源imageLocation = file.getParentFile().getParentFile().getParentFile().getPath()+relativeDir;}@Value("${notification.url}")private String notificationUrl;@Autowiredprivate ServerConfig serverConfig;private final Logger logger = LoggerFactory.getLogger(this.getClass());private final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");public static String getImageLocation() {return imageLocation;}public static String getRelativeDir() {return relativeDir;}@Asyncpublic void executeAsyncTask(Device device) throws Exception {logger.info("Enter executeAsyncTask");HCNetSDK.NET_DVR_JPEGPARA jpegpara = new HCNetSDK.NET_DVR_JPEGPARA();logger.info(Thread.currentThread().getName());while (device.isConnected()) {String fileName = getImgName();logger.debug("produce Pic: " + fileName);logger.debug("absolute dir: " + (getImageLocation()+fileName));boolean operSucc = hCNetSDK.NET_DVR_CaptureJPEGPicture(device.getUserID(), new NativeLong(1), jpegpara, getImageLocation()+fileName);if (!operSucc) {printErrInfo("executeAsyncTask", "NET_DVR_CaptureJPEGPicture");}JSONObject message = getMessage(device, fileName);logger.debug(message.toJSONString());GeneralUtil.postJson(notificationUrl, message.toJSONString());Thread.sleep(1000*4);}logger.info("Leave executeAsyncTask");}private JSONObject getMessage(Device device, String fileName) {JSONObject message = new JSONObject();message.fluentPut("imgUrl", serverConfig.getUrl() + getRelativeDir()+fileName);message.put("ip", device.getIp());message.put("produceTime", dateFormat.format(new Date()));return message;}private String getImgName() {return UUID.randomUUID().toString()+".jpg";}public  void printErrInfo(String inFunc, String afterFunc) {int errCode = hCNetSDK.NET_DVR_GetLastError();logger.debug("In "+inFunc+" after Exec "+ afterFunc + " , errCode: "+ errCode);}public int getLastErrCode() {logger.debug("hcNetSDK: " + hCNetSDK);return hCNetSDK.NET_DVR_GetLastError();}
}

3.3.3 Device Model

 Device类用来为摄像头设备进行建模,其中包含主要的行为包括设备连接、设备断开连接。该类的实现如下:

package com.example.screenshot.model;import com.example.screenshot.sdk.HCNetSDK;
import com.sun.jna.NativeLong;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;/*** 对设备进行建模** @Owner:* @Time: 19-3-22-下午9:11*/
public class Device {private final Logger logger = LoggerFactory.getLogger(this.getClass());private String ip;private NativeLong userID = new NativeLong(-1);private short port = Short.parseShort("8000");private String userName = "admin";private String password = "hik12345+";public NativeLong getUserID() {return userID;}public boolean isConnected() {return isConnected;}private boolean isConnected;private static HCNetSDK hCNetSDK = HCNetSDK.INSTANCE;private HCNetSDK.NET_DVR_DEVICEINFO_V30 deviceInfo;public void setIp(String ip) {this.ip = ip;}public Device(String ip) {this.ip = ip;setConnected(false);}public String getIp() {return ip;}public void setConnected(boolean connected) {isConnected = connected;}public void resetUserID() {userID = new NativeLong(-1);return ;}public boolean connect() {logger.debug("Enter connect");logger.debug("in connect: "+hCNetSDK);userID = hCNetSDK.NET_DVR_Login_V30(ip, port, userName, password, deviceInfo);int errCode = getLastErrCode();logger.debug("After connect errCode: "+ errCode);if (errCode!=0) {setConnected(false);return false;} else {setConnected(true);return true;}}public boolean disconnect() {logger.debug("Enter disconnect");boolean operSucc = hCNetSDK.NET_DVR_Logout(userID);if (!operSucc) {printErrInfo("disconnect", "NET_DVR_Logout");}resetUserID();setConnected(false);return operSucc;}public  void printErrInfo(String inFunc, String afterFunc) {int errCode = hCNetSDK.NET_DVR_GetLastError();logger.debug("In "+inFunc," after Exec "+ afterFunc + " , errCode: "+ errCode);}public int getLastErrCode() {logger.debug("hcNetSDK: " + hCNetSDK);return hCNetSDK.NET_DVR_GetLastError();}
}

3.3.4 WebMvcConfiger 将图片映射成静态资源实现类

package com.example.screenshot.config;import com.example.screenshot.service.AsyncTask;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;import java.io.File;/*** 配置静态资源映射,把图片映射成HTTP资源,该类执行之后,则抓取的图片可以通过* http://ip:port/Img/imgName在浏览器中访问* @Owner:* @Time: 19-3-21-下午10:44*/
@Configuration
public class WebMvcConfigurer extends WebMvcConfigurerAdapter {private final Logger logger = LoggerFactory.getLogger(this.getClass());@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {logger.debug("Enter addResourceHandlers");logger.debug("imageLocation: "+AsyncTask.getImageLocation());File file = new File(AsyncTask.getImageLocation());if (!file.exists()) {logger.debug("Before mkdirs");boolean mkFlag = file.mkdirs();logger.debug("mkFalg: "+mkFlag);} else {logger.debug(AsyncTask.getImageLocation() + " has existed");}registry.addResourceHandler("/Img/**").addResourceLocations("file:"+AsyncTask.getImageLocation());logger.debug("Leave addResourceHandlers");}
}

 通过这种方式可以把抓取的文件映射成静态HTTP资源,在供其他人进行算法分析时,只要通过httpclient发送post请求,然后把图片的url地址传给对方,这样对方即可以通过该url把图片拉取到本地进而继续进行算法分析的程序了,这不在本文的范围之内,不再赘述了。

4 总结

 文档主要是介绍了在Linux环境下使用Java调用so文件的具体过程,其中演示环节使用了摄像机的抓拍能力,整体的流程是通过Spring Boot接收REST请求,在设备连接时开启图像抓拍,然后抓拍会保存一系列的图片到本地的目录,然后把该目录映射成HTTP资源供需要使用图片的人进行使用。
 尤其需要注意的是,算法详细讲述了海康威视设备网络SDK的用法,并以摄像机抓拍为功能实现的基础阐述了设备网络SDK的目录结构,导入项目的步骤,JNA整合的详细过程。希望能辅助有相同开发需求场景。

5 参考

Windows下使用Java调用Hikvision设备网络SDK的使用指南

JNA实战笔记汇总<一> 简单认识JNA|成功调用JNA

6 下载

Linux下使用Java调用Hikvision设备网络SDK的使用指南.pdf
设备网络SDK.zip

Linux下使用Java调用Hikvision设备网络SDK使用指南相关推荐

  1. Windows下使用Java调用Hikvision设备网络SDK的使用指南

    1 简介 在出差的过程中,曾经出现了一个微小人脸检测的需求,该算法的主要工作流程是从一张图片上通过算法识别出图片上的微小人脸.撇去算法如何实现,在这个微小人脸检测执行的过程中,图片的来源经过协商,希望 ...

  2. 海康威视错误代码0xf_海康威视设备网络SDK编程指南(报 警主机).pdf

    设备(报警主机) 网络SDK 编程指南 V5.2 I 设备网络SDK 编程指南 声 明 非常感谢您购买我公司的产品,如果您有什么疑问或需要请随时联系我们.  我们已尽量保证手册内容的完整性与准确性, ...

  3. java 视频截取图片 linux,在Windows和Linux下用JAVA调用FFMPEG 3.x进行视频截图的最新范例...

    ffmpeg3.x版本,相对2.x版本,在接口上,作了较大的改动.原来的程序可能就不能正常编译.运行了.网上不少范例程序,所以也就不能用了.java 下面的例子,是本人在原ffmpeg2.X例子基础上 ...

  4. window与linux环境下,java调用c语言的方法

    windows环境下,java调用c语言的方法 1.环境 C语言编译器:工具比较多,本文使用的是gcc,带gcc的软件业比较丰富,我使用的是TDM-GCC, 注:网上很多使用的是MinGW,但我遇到了 ...

  5. Linux下的硬件驱动——USB设备(下)

    Linux下的硬件驱动--USB设备(下)(驱动开发部分) 文档选项 打印本页 将此页作为电子邮件发送 未显示需要 JavaScript 的文档选项 级别: 初级 赵明, 联想软件设计中心嵌入式研发处 ...

  6. Linux下的硬件驱动——USB设备

    想起当初对于破安卓手机,挂在系统上可是费了好些劲,今偶遇USB驱动开发,收集备用,哪天一生气,说不定也写一个linux下的手机驱动,类似于91手机助手的,也不用配置了. Linux下的硬件驱动--US ...

  7. 基于最新版设备网络SDK集成海康摄像头之Java Demo调试运行教程

    Java Demo运行截图: 由于涉及到空间隐私,部分位置会打码. 设备网络SDK 设备网络SDK是基于硬件的SDK,是基于设备私有网络通信协议开发的,为后端设备(嵌入式网络硬盘录像机.视频服务器). ...

  8. ​Linux下C如何调用PCI Lib函数

    Linux下C如何调用PCI Lib函数 在Linux下,可以通过"setpci"和"setpci"命令来访问PCI设备的配置空间,那么能否用程序来访问PCI ...

  9. java createjpeg4_在linux下用java的JPEGCodec.createJPEGEncoder(bos)生成jpg图片问题

    在rh8   linux   下用java的JPEGCodec.createJPEGEncoder(bos)生成jpg图片,XServer已启动.出现如下问题 错误提示如下 java.lang.Int ...

最新文章

  1. 用深度学习就不怕买到山寨奢侈品?LeCun投了这样一家公司
  2. 有关ftp4j的FTPListParseException异常
  3. python 如何获取列表(List)中指定元素的下标? index() enumerate() 获取重复元素下标
  4. 在 Wi ndows,MSComm控件在中文Wi的ndows下的通信问题与处理方法.doc
  5. 这可能是我见过最详细的快速排序!
  6. Reactor三种线程模型与Netty线程模型
  7. 数据爆发式增长下,CIO不可不知的“数据经济学”
  8. 认识CodeSmith
  9. oracle健康检查脚本下载,oracle 数据库性能健康检查脚本
  10. 低熵加壳malware
  11. pytorch系列(八):猫狗大战3-单机多卡无脑训练
  12. [tensorflow] 数字标签转化为one-hot形式的tensor
  13. Blender摄像机环绕运动、动画渲染、视频合成
  14. python seo cms_「SEO帝国」 SEO中讲的 CMS是什么意思
  15. 《长尾理论》读书笔记------”长尾法则--怎样创造一个消费天堂“
  16. android陌陌权限申请实现,Hook实现Android 微信,陌陌 ,探探位置模拟
  17. 因素分析(Factor Analysis)
  18. (附源码)node.js 游戏网站 毕业设计 031726
  19. 异常:javax.el.PropertyNotFoundException: Property ‘id‘ not found on ..........
  20. HTTP服务器项目面试题

热门文章

  1. Java中字节Byte和位Bit的关系
  2. 使用天翼云主机组功能让云主机不放在同一个篮子里
  3. 5G商用加速冲刺,群雄逐鹿5G芯片市场
  4. input修改自动填充背景色(单一色以及透明)
  5. 提取图片中的文字或者表格,识别车牌,驾驶证,营业执照,发票的工具
  6. 在Vue中使用jsPdf设置半透明水印
  7. [Python3] 简单的jieba分词以及停用词去除
  8. 中国网上人民大学计算机在线考试,中国人民大学网络教育易考通客户端在线考试须知...
  9. 购物网站制作——顶部导航栏(index.html)
  10. 论文阅读 (75):Video Anomaly Detection with Spatio-temporal Dissociation (2022)