FangChao.Qu Blog


  • 首页

  • 归档

  • 标签

ubuntu 16.04安装opencv3.2

发表于 2017-10-26

1.安装opencv依赖包

$ sudo apt-get install build-essential
$ sudo apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
$ sudo apt-get install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc1394-22-dev # 处理图像所需的包
$ sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev liblapacke-dev
$ sudo apt-get install libxvidcore-dev libx264-dev # 处理视频所需的包
$ sudo apt-get install libatlas-base-dev gfortran # 优化opencv功能
$ sudo apt-get install ffmpeg

2.下载opencv3.2

$ wget https://github.com/opencv/opencv/archive/3.2.0.zip # 从github上直接下载或者clone也可
$ wget https://github.com/opencv/opencv_contrib/archive/3.2.0.zip

3.配置编译opencv

3.1无nvidia cuda版本

$ cd opencv-3.2.0
$ mkdir build
$ cd build
$ cmake -DCMAKE_BUILD_TYPE=RELEASE \
    -DCMAKE_INSTALL_PREFIX=/usr/local \
    -DINSTALL_PYTHON_EXAMPLES=ON \
    -DINSTALL_C_EXAMPLES=OFF \
    -DOPENCV_EXTRA_MODULES_PATH=~/opencv_contrib-3.2.0/modules \
    -D WITH_TBB=ON \
    -D WITH_V4L=ON \
    -D WITH_GTK=ON \
    -D WITH_OPENGL=ON \
    -D BUILD_EXAMPLES=ON .. # cmake命令的使用方式:cmake [<some optional parameters>] <path to the OpenCV source directory>。如果命令报错的话可以试着把-D后面的空格去掉在执行一次。
$ make -j4(此过程较漫长)
$ sudo make install

3.2NVIDIA CUDA版本

$ cmake -D CMAKE_BUILD_TYPE=RELEASE \
-D CMAKE_INSTALL_PREFIX=/usr/local \
-D INSTALL_PYTHON_EXAMPLES=ON \
-D INSTALL_C_EXAMPLES=OFF \
-D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib-3.2.0/modules \
-D PYTHON_EXCUTABLE=/usr/bin/python \
-D WITH_CUDA=ON \    # 使用CUDA
-D WITH_CUBLAS=ON \
-D DCUDA_NVCC_FLAGS="-D_FORCE_INLINES" \
-D CUDA_ARCH_BIN="5.3" \    # 这个需要去官网确认使用的GPU所对应的版本[查看这里](https://developer.nvidia.com/cuda-gpus)
-D CUDA_ARCH_PTX="" \
-D CUDA_FAST_MATH=ON \    # 计算速度更快但是相对不精确
-D WITH_TBB=ON \
-D WITH_V4L=ON \
-D WITH_QT=ON \    # 如果qt未安装可以删去此行;若因为未正确安装qt导致的Qt5Gui报错,可将build内文件全部删除后重新cmake,具体可以参考[这里](http://stackoverflow.com/questions/17420739/opencv-2-4-5-and-qt5-error-s)
-D WITH_GTK=ON \
-D WITH_OPENGL=ON \
-D BUILD_EXAMPLES=ON .

#4.安装完成,进行整理

sudo /bin/bash -c 'echo "/usr/local/lib" > /etc/ld.so.conf.d/opencv.conf'
sudo ldconfig
sudo apt-get update

#5.测试是否安装成功

python
>>> import cv2
>>> cv2.__version__
'3.2.0'
>>>

linux虚拟机安装javaweb环境(Mysql蛋疼的安装)

发表于 2017-10-24

1.sudo vim /etc/hosts

修改hosts文件,将镜像原地址写上 并对应相应域名

Alt text

2.sudo vim /etc/apt/sources.list

更改原地址
Alt text

YOLO模型详解

发表于 2017-09-28

1.简介

  • YOLO为一种新的目标检测方法,该方法的特点是实现快速检测的同时还达到较高的准确率。作者将目标检测任务看作目标区域预测和类别预测的回归问题。该方法采用单个神经网络直接预测物品边界和类别概率,实现端到端的物品检测。同时,该方法检测速非常快,基础版可以达到45帧/s的实时检测;FastYOLO可以达到155帧/s。与当前最好系统相比,YOLO目标区域定位误差更大,但是背景预测的假阳性优于当前最好的方法。

#2.介绍
人类视觉系统快速且精准,只需瞄一眼(You Only Look Once,YOLO)即可识别图像中物品及其位置。

传统目标检测系统采用deformable parts models (DPM)方法,通过滑动框方法提出目标区域,然后采用分类器来实现识别。近期的R-CNN类方法采用region proposal methods,首先生成潜在的bounding boxes,然后采用分类器识别这些bounding boxes区域。最后通过post-processing来去除重复bounding boxes来进行优化。这类方法流程复杂,存在速度慢和训练困难的问题。

本文中,我们将目标检测问题转换为直接从图像中提取bounding boxes和类别概率的单个回归问题,只需一眼(you only look once,YOLO)即可检测目标类别和位置。

YOLO采用单个卷积神经网络来预测多个bounding boxes和类别概率,如图1-1所示。本方法相对于传统方法有如下有优点:

一,非常快。YOLO预测流程简单,速度很快。我们的基础版在Titan X GPU上可以达到45帧/s; 快速版可以达到150帧/s。因此,YOLO可以实现实时检测。

二,YOLO采用全图信息来进行预测。与滑动窗口方法和region proposal-based方法不同,YOLO在训练和预测过程中可以利用全图信息。Fast R-CNN检测方法会错误的将背景中的斑块检测为目标,原因在于Fast R-CNN在检测中无法看到全局图像。相对于Fast R-CNN,YOLO背景预测错误率低一半。

三,YOLO可以学习到目标的概括信息(generalizable representation),具有一定普适性。我们采用自然图片训练YOLO,然后采用艺术图像来预测。YOLO比其它目标检测方法(DPM和R-CNN)准确率高很多。

YOLO的准确率没有最好的检测系统准确率高。YOLO可以快速识别图像中的目标,但是准确定位目标(特别是小目标)有点困难。
Alt text

3.统一检测

统一检测(Unified Detection)

作者将目标检测的流程统一为单个神经网络。该神经网络采用整个图像信息来预测目标的bounding boxes的同时识别目标的类别,实现端到端实时目标检测任务。

如图2-1所示,YOLO首先将图像分为S×S的格子(grid cell)。如果一个目标的中心落入格子,该格子就负责检测该目标。每一个格子(grid cell)预测bounding boxes(B)和该boxes的置信值(confidence score)。置信值代表box包含一个目标的置信度。然后,我们定义置信值为Pr(Object)\ast IOU_{pred}^{truth} 。如果没有目标,置信值为零。另外,我们希望预测的置信值和ground truth的intersection over union (IOU)相同。

每一个bounding box包含5个值:x,y,w,h和confidence。(x,y)代表与格子相关的box的中心。(w,h)为与全图信息相关的box的宽和高。confidence代表预测boxes的IOU和gound truth。

每个格子(grid cell)预测条件概率值C(Pr(Class{i} |Object))。概率值C代表了格子包含一个目标的概率,每一格子只预测一类概率。在测试时,每个box通过类别概率和box置信度相乘来得到特定类别置信分数:Pr(Class{i} |Object)\ast Pr(Object)\ast IOU{pred}^{truth} =Pr(Class{i} )\ast IOU_{pred}^{truth}

这个分数代表该类别出现在box中的概率和box和目标的合适度。在PASCAL VOC数据集上评价时,我们采用S=7,B=2,C=20(该数据集包含20个类别),最终预测结果为7×7×30的tensor。
Alt text

##3.1 网络结构

模型采用卷积神经网络结构。开始的卷积层提取图像特征,全连接层预测输出概率。模型结构类似于GoogleNet,如图3所示。作者还训练了YOLO的快速版本(fast YOLO)。Fast YOLO模型卷积层和filter更少。最终输出为7×7×30的tensor。图2-2 网络结构
Alt text

##3.2 训练方法

作者采用ImageNet 1000-class 数据集来预训练卷积层。预训练阶段,采用图2-2网络中的前20卷积层,外加average-pooling 层和全连接层。模型训练了一周,获得了top-5 accuracy为0.88(ImageNet2012 validation set),与GoogleNet模型准确率相当。然后,将模型转换为检测模型。作者向预训练模型中加入了4个卷积层和两层全连接层,提高了模型输入分辨率(224×224->448×448)。顶层预测类别概率和bounding box协调值。bounding box的宽和高通过输入图像宽和高归一化到0-1区间。顶层采用linear activation,其它层使用 leaky rectified linear。作者采用sum-squared error为目标函数来优化,增加bounding box loss权重,减少置信度权重,实验中,设定为\lambda {coord} =5 and \lambda {noobj}=0.5 。

训练阶段的总loss函数如下:

作者在PASCAL VOC2007和PASCAL VOC2012数据集上进行了训练和测试。训练135轮,batch size为64,动量为0.9,学习速率延迟为0.0005. Learning schedule为:第一轮,学习速率从0.001缓慢增加到0.01(因为如果初始为高学习速率,会导致模型发散);保持0.01速率到75轮;然后在后30轮中,下降到0.001;最后30轮,学习速率为0.0001.
作者还采用了dropout和 data augmentation来预防过拟合。dropout值为0.5;data augmentation包括:random scaling,translation,adjust exposure和saturation。

##3.3 预测
对于PASCAL VOC数据集,模型需要对每张图片预测98个bounding box和对应的类别。对于大部分目标只包含一个box;其它有些面积大的目标包含了多个boxes,采用了Non-maximal suppression(非最大值抑制)来提高准确率。

##3.4 Limitations
一,YOLO的每一个网格只预测两个boxes,一种类别。这导致模型对相邻目标预测准确率下降。因此,YOLO对成队列的目标(如 一群鸟)识别准确率较低。
二,YOLO是从数据中学习预测bounding boxes,因此,对新的或者不常见角度的目标无法识别。
三,YOLO的loss函数对small bounding boxes和large bounding boxes的error平等对待,影响了模型识别准确率。因为对于小的bounding boxes,small error影响更大。
Alt text

4. 实时检测

作者测试了YOLO的实时检测效果,结果参见 YouTube channel: https://goo.gl/bEs6Cj.(可惜要翻墙才能看)。

#5.结论
YOLO为一种基于单独神经网络模型的目标检测方法,具有特点可以高准确率快速检测,同时具有一定鲁棒性,可以适用于实时目标检测。

Activiti工作流(第一天)

发表于 2017-06-29

1.安装流程设计器

  1. 将activiti-designer.zip解压到myeclipse安装目录下的dropins下的activiti-designer文件夹
  2. 创建activiti.link文件,内容如下
  3. 注意:打开菜单Windows->Preferences->Activiti->Save actions, 把bpmn 和.png同步保存

    path=C:\Users\qfc\AppData\Local\MyEclipse Professional 2014\dropins\activiti-designer\

    2.Activiti介绍

    1. 工作流引擎 :ProcessEngine ,它是Activiti的核心类,由该类可以获取其他的服务实例
      (历史服务、仓库服务、任务服务、用户参与者服务)
      
    2. BPMN :UML :用例图、类图、时序图
      业务流程建模与标注(Business Process Model and Notation,BPMN) ,
      描述流程的基本符号,包括这些图元如何组合成一个业务流程图(Business Process Diagram)
    3. 数据库
      Activiti的后台是有数据库的支持,所有的表都以ACT_开头。
      第二部分是表示表的用途的两个字母标识。 用途也和服务的API对应
      Activiti的工作流数据库有23张表
      要保存流程定义

      - act_ge_*  :通用表
      
      • acthi* :历史流程相关表
      • actre* :仓库表:保存流程定义
      • actru* :保存流程运行相关的表
      • actid* :用户参与相关的表
    4. activiti.cfg.xml
      Activiti核心配置文件,配置流程引擎创建工具的基本参数和数据库连接参数

      3.HelloActiviti程序(模拟Activiti流程执行)

    5. 设置流程定义图bpmn
      assignee :代理人、指定人、处理人

    6. 创建流程引擎及工作流数据表

      数据库及表可以自动创建,

      可以在配置数据库连接时,实现自动创建数据库和表

      取得ProcessEngine对象

      先取得ProcessEngineConfiguration 对象 ,再由该对象来构建ProcessEngine

  1. 部署流程
    影响的表:

    act_re_procdef :流程定义表 :

    该表的key属性 是bpmn 的 id决定

    该表的name属性 是bpmn 的name 属性决定

    act_re_deployment:部署表 :id是由act_ge_property的 next_dbid决定

    act_ge_property :通用属性表

  2. 启动流程

  3. 查看我的个人任务

  4. 完成我的个人任务

4.代码

public class TestActiviti {
    ProcessEngine engine=ProcessEngines.getDefaultProcessEngine();

    @Test
    // 取得流程引擎,且自动创建Activiti设计的数据库及表
    public void createProcessEngine() {
        /*方法一
        // 取得ProcessEngineeConfiguration对象
        ProcessEngineConfiguration engineConfiguration = ProcessEngineConfiguration
                .createStandaloneProcessEngineConfiguration();
        // 设置数据库库连接属性
        engineConfiguration.setJdbcDriver("com.mysql.jdbc.Driver");
        engineConfiguration
                .setJdbcUrl("jdbc:mysql://localhost:3306/activitiDB?createDatabaseIfNotExist=true"
                        + "&useUnicode=true&characterEncoding=utf8");
        engineConfiguration.setJdbcUsername("root");
        engineConfiguration.setJdbcPassword("21160233099");
        // 设置创建表的策略(当没有表时,自动创建表)
        // public static final java.lang.String DB_SCHEMA_UPDATE_FALSE =
        // "false";
        // public static final java.lang.String DB_SCHEMA_UPDATE_CREATE_DROP =
        // "create-drop";
        // public static final java.lang.String DB_SCHEMA_UPDATE_TRUE = "true";
        engineConfiguration.setDatabaseSchemaUpdate("true");
        // 通过ProcessEngineConfiguration对象常见ProcessEnginee对象
        ProcessEngine processEngine = engineConfiguration.buildProcessEngine();
 */
        //方法二
            //ProcessEngineConfiguration engineConfiguration=ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
            //ProcessEngine engine=engineConfiguration.buildProcessEngine();
        //方法三
        ProcessEngine processEngine=ProcessEngines.getDefaultProcessEngine();//默认必须是activiti.cfg.xml方法二可以随意改名

    }
    //部署流程定义
    @Test
    public void deploy(){
        //取得流程引擎
        //获取仓库服务:管理流程定义
        RepositoryService repositoryService=engine.getRepositoryService();
        repositoryService.createDeployment()//创建一个部署的构建器
        .addClasspathResource("diagrams/LeaveBill.bpmn")//从类路径添加资源
        .addClasspathResource("diagrams/LeaveBill.png")
        .name("请假单流程")//设置部署名称
        .category("办公类别")//设置部署的类别
        .deploy();
    }
    //执行流程
    @Test
    public void startProcess(){
        String processKey="leaveBill";
        //取运行时服务
        RuntimeService runtimeService=engine.getRuntimeService();
        //取得流程实例
        ProcessInstance pi=runtimeService.startProcessInstanceByKey(processKey);//通过流程定义的key来执行流程
        System.out.println(pi.getId()+pi.getProcessDefinitionId());
    }
    //查询任务
    @Test
    public void queryTask(){
        String name="李四";
        //取得任务服务
        TaskService taskService=engine.getTaskService();
        //创建一个任务查询对象
        TaskQuery query=taskService.createTaskQuery();
        //办理人的任务列表
        List<Task> list=query.taskAssignee(name).list();
        for(Task task:list){
            System.out.println(task.getAssignee()+" "+task.getId());

        }
    }
    @Test
    //完成任务
    public void complete(){
        String taskID="204";
        engine.getTaskService().complete(taskID);


    }
}

linux基础操作2

发表于 2017-06-26

1.网络管理

修改ip地址的配置

sudo vi /etc/sysconfig/network-scripts/ifcfg-eth0 修改该配置文件即可改ip地址

或者在root权限下用setup指令通过一个带提示的伪图形界面来修改

查看ip地址
ifconfig

修改主机名

sudo vi /etc/sysconfig/network

修改其中的hostname配置项

要想立即生效 可以执行指令 hostname nidezhujiming

HOSTNAME=yun12-01

管理内网的”主机名—ip地址”本地映射

sudo vi /etc/hosts

192.168.2.250 yun12-01

重启网络服务

root权限下 service network restart

关闭防火墙服务 service iptables stop

关闭防火墙自动启动 chkconfig iptables off

修改系统的默认启动级别

vi /etc/inittab

  0 - halt (Do NOT set initdefault to this)
 1 - Single user mode
2 - Multiuser, without NFS (The same as 3, if you do not have networking)
3 - Full multiuser mode
4 - unused
 5 - X11
 6 - reboot (Do NOT set initdefault to this)

id:3:initdefault:
~
用level 3 就启动全功能状态的字符界面

查看当前的进程连接网络的信息

netstat -nltp

2.常用工具指令

wc 统计文本信息(行数,词数,字符数)

date 查看或者修改系统的日期和时间

echo 输出字符串或者变量的值

vi linux系统中最通用的文本编辑器

3.linux中的软件安装

##3.1 安装jdk

 实现步骤:
  1. jdk 存放在哪里  /opt
  2. 把软件拷贝到/opt
  3. 绿色软件,解压 
  4.设置环境变量
  vim /etc/profile 
  export JAVA_HOME="/java/jdk1.6.0_39"
  export PATH=$PATH:$JAVA_HOME/bin
刷新配置 ,让配置生效
 source /etc/profile  (java -version失效,可重复此操作)
编写Demo.java,测试 
 -javac Demo.java
     - java Demo

##3.2. 安装tomcat
步骤:

 2. 拷贝、解压
tar -xzvf  apache-tomcat.tar.gz
 3. 运行
- ./startup.sh
- ./shutdown.sh

##3.3 安装Eclipse
步骤:

拷贝、解压
 cp eclipse.tar.gz  /opt
 tar -xzvf  eclipse.tar.gz 

linux基础操作1

发表于 2017-06-21

1.文件系统的管理

tips:输入命令的时候要常用tab键来补全

ls 查看目录信息 ( ls / )
ls -l 等价于 ll
pwd 查看当前所处的路径

cd     切换目录 (cd /) ,如果不带参数则切换到用户主目录 ~

mkdir 创建文件夹

mkdir -p a/b/c  如果要创建的文件夹的父目录不存在,则自动创建

rmdir 删除空文件夹 (只能删除空文件夹)

rm -r  /a/b  (删除非空文件夹)

创建文件

touch a.avi 创建一个空文件

vi blabla.txt 用文本编辑器编辑一个文件并且保存

echo "angelababy,zhen de hen xihuan ni" > qingshu.txt  把左边的输出放到右边的文件里去 

删除文件

rm filename  (rm -r  删除文件夹     rm -rf 强制删除文件或文件夹)

移动文件 修改文件名

mv a/wenjian1.txt b/file1.txt   (移动文件的同时还修改了文件名)

拷贝文件

cp srcFile destFile

查看文本文件内容

cat wodeqingshu.txt

more wodeqingshu.txt 可以分页看

less wodeqingshu.txt 不仅可以分页,还可以方便地搜索,回翻等操作

tail -10 wodeqingshu.txt   查看文件的尾部的10行

程序打出的日志在生产实践中具有非凡的debug的意义

tail -f user.log   实时刷新显示文件的尾部

head -20 wodeqingshu.txt 查看文件的头部20行

2.权限管理

linux系统中对文件权限的描述机制:

d  r  w  x   r  w  x   r  -  x

   所有者      所属组    其他人

可以表示为二进制:  111 111 101

也可以表示为十进制: 7     7   5

修改权限
chmod u+rwx file 为file添加或取消所属用户的权限

(u代表所属用户  o代表其他用户  g代表所属组的成员用户)

chmod 567 file 用数字也可以表示权限  

修改文件的所有者owner(只能由root权限才能操作)

chown hadoop:hadoop  file 将file的所有者改成hadoop用户,所属组改成hadoop组

上级目录的权限对本级文件或者文件夹的操作有约束

3.用户管理

添加用户

useradd  qfc

必须设置密码才能正常登陆    passwd qfc

在/home/下:mkdir qfc

chown qfc:qfc qfc

cp .bash_history .bashrc qfc

删除用户

userdel yun12

userdel -r itcast -----删除用户的同时删除用户的主目录

修改用户属性

usermod -l b a 将a的登陆名改为b

usermod -g hadoop itcast0830 将itcast0830的组改为hadoop组

usermod -G hadoop,root itcast0830 给itcast0830添加两个组hadoop,root

usermod -d /home/itcast itcast0830 将itcast0830的主目录改成/home/itcast

(要事先创建itcast目录,并且拷入环境变量文件)

—-**—-修改用户的密码

passwd itcast0830

添加用户组
groupadd beauties

删除用户组
groupdel beauties

修改用户组属性
groupmod

查看当前登陆的身份
whoami
查看当前用属的组
groups

4.常见系统管理(凡是涉及到修改,就一定要用root权限)


轻易不要使用su去切换到root的身份

普通用户使用sudo来执行root权限的命令

如,将hadoop用户添加到sudoers文件中去

root    ALL=(ALL)       ALL

hadoop  ALL=(ALL)       ALL

磁盘空间信息查看

df -h  查看磁盘空间状态信息

du -sh * 查看当前目录下所有子目录和文件的汇总大小    

进程信息查看

free  查看内存使用状况

top   查看实时刷新的系统进程信息

ps -ef  查看系统中当前瞬间的进程信息快照


ps -ef | grep myshell.sh  搜索myshell进程的信息

kill -9 pid  杀掉进程  (-9 表示强制杀死)

5.文件归档压缩(1:打包–归档; 2:压缩)

  1. 归档与解档
    tar -cvf testdir.tar testdir/
    tar -xvf testdir.tar
  2. 压缩
    gzip testdir.tar

    gzip file

    bzip file

    tar -czvf testdir.tar.gz testdir/

    tar -xzvf testdir.tar.gz 解压到当前目录下

    tar -zxvf testdir.tar.gz -C Downloads/ 解压到指定的Downloads目录下

基于SSM的商贸平台项目(第十天)

发表于 2017-06-21

1.数据库总结

1.1 打断设计:

在报运中它的数据库设计比较难,我在这设计时进行打断设计,实现跳跃查询。在设计时我们业务关联曾经是比较多的,报运和购销合同一对多关联,合同又跟货物一对多,货物又跟附件一对多。关联曾经过多,查询效率过多,这当数据大时(100万),查询效率就可能非常低,所以我对这的设计进行了优化,在主表中加入一个打断设计的字段,这个字段存储子表的多个主键。这样就无需建立外键关联。这样设计后,报运查询相关合同下的货物信息时,不像关联方式,必须由报运去找多个合同,再通过每个合同去找多个货物信息,而直接通过打断字段,利用sql in子查询从报运直接去查找合同下的货物信息。这样减少了关联曾经,查询效率很大提高。当系统的用户数据越来越多,业务关联层级越多,这种设计方式的效率越高。它跳跃了中间多层,实现跳跃查询。

1.2 数据搬家(数据冗余)

在报运时,本身货物信息需要新增7个字段,毛重、净重、长、宽、高、出口单价、含税,还需要合同下的货物的货号、数量、包装单位、件数等。如果按原始设计,读取报运信息后,一部分货物信息要从关联的报运下的货物信息中读取,还有一部分要从合同下的货物读取。这样设计比较麻烦,开发结构复杂,业务不利于开发人员学习业务。我们对其进行优化,我们为了查询更快,关系更简单,代码更简单,将相关的合同在报运新增时,直接把所需要的部分货物信息,货号、数量、包装单位、件数直接复制到报运下的货物表中,这样在报运修改时,直接补充7个字段。在需要报运信息时。就变得简单,直接读取报运下的货物表即可。同时,为了后续业务读取这部分货物信息,还有它们关联的附件信息,我们直接也将合同下的附件信息整体搬迁。这样后续的业务直接可以从报运相关的表中查询,而无需通过多级关联去合同下去找,关联曾经变少,效率提高很多。

1.3 一对一的特殊设计

业务装箱和委托、发票、财务都是一对一的。我们为了设计上清晰,我们采用4张。主外键为一个值,委托、发票、财务直接就存放的是装箱单的ID。这样在程序中只要获得其中一个的ID,就可以查询其中任何一个对象。改变传统设计,传统设计财务关联发票,发票关联委托,委托关联装箱。财务需要获取报运的信息和装箱的信息,这时要财务要找到发票,发票找到委托,委托找到装箱,装箱找到多个报运。这样关联层级过多,速度比较慢。我们进行优化设计,改变对应关系,直接设计财务和装箱进行关联。上面的需求就非常简单,通过财务找到装箱,直接获取装箱的部分需要的信息,在通过装箱的打断设计字段,直接获取报运下的货物信息。实现多次跳跃查询。

2.技术总结

2.2 页面结构,批量修改自定义控件

在报运货物的修改中,批量进行数据修改,批量的业务就可以直接套用。利用动态表格技术,实现动态的往一个table中增加tr,动态往tr总增加td,它文本框,单选框,多选框,下拉框,大文本。利用一个js函数addRecord反复调用,就可以实现往表格中插入数据。数据在后台service层进行js串拼接,在拼接过程中,将业务数据就拼接进去。然后利用jQuery ready事件进行js动态执行。由于js运行非常快,用户感知不到表格数据的动态增加,他以为直接展现。如果数据在600行。这时不能使用通过ready事件一行一行执行。如果超过600行,采用的方式来实现。在批量修改时,我就增加了一个行标识,来标识本行记录是否修改,如果修改了,在后台就进行更新,如果没有修改,就不更新操作。

2.3POI复杂报表打印

购销合同复杂报表的打印,这个报表中需要插入用户LOGO,可以插入多个货物的图片,可以插入一根分割线,对合计的值进行公式的设置,打印时用户可以自定义设置打印一款货物,还是打印两款货物,货物生产厂家如果不同,还必须另起一页。获取一个合同信息和多个货物信息。

2.3 POI百万数据导出

在POI高版本中提供了一个特殊的构造方法SXSSF对象,利用这个对象,在构造时可以设定一个参数,产生对象的数量,根据这个数量,在大数据量导出时,当创建这么多对象后,直接POI写到xml临时文件中。当真正写文件时,再从临时文件中获取信息,输出内容。这样做解决了早期版本中,直接在内存中创建大量对象,导致非常容易内存堆溢出。它不支持模板文件操作。

2.4 amcharts 分析统计

  1. 组织数据
  2. 拼接字符串,拼接为amchart官网Demo的html格式

3.革命尚未成功,还需继续努力

  1. 工作流采用最新的Activiti5 5.16版本,它会自动创建24张表,多了一张日志表。在购销合同上报时,同时启动流程。销售专责就行购销合同的处理,然后提交流程到销售部领导的审批,销售部领导审批通过后,提交到船运部。船运部报运专责开始处理报运业务,处理完成,提交给船运部报运经理进行审核,报运经理审核通过后,他提交给船运部装箱专责。船运部装箱专责处理装箱业务,处理完成提交给装箱经理审批,装箱经理审批后,提交给委托专责,委托专责处理委托业务,处理完成提交给发票经理审批,发票经理审批通过后提交给财务部,财务部财务专责处理内部核算,提交给财务经理审批。财务经理审批通过后,流程完成。
  2. 并发处理
    购销合同打印,首先打印时,将临时文件放在服务器的临时目录。基于windows处理文件并发机制。当打印时产生一个文件名,先判断临时目录中文件是否存在,如果存在自动给其再编一个新的名称,再次判断如果这个名称还冲突,再重新命名,只到没有冲突为止。
    下载,下载时控制下载的人数,当这个数量超过阀值(10个,通过配置文件配置),action进行转向友好提示页面,“用户当前下载人数过多,请稍后下载”。

基于SSM的商贸平台项目(第九天)

发表于 2017-06-16

1.让微软汗颜的图形报表

思路:

  1. 组织数据源
  2. 拼接字符串,拼接为amchart官网Demo的html格式

    1.1饼形图:

    Alt text

1.2柱状图

Alt text

1.3折线图

Alt text

2.异构数据库,让程序支持主流数据库切换

Alt text

程序开发时有要求:

  1. 不能使用存储过程,不能使用规则rule,不能使用触发器;
  2. 可以少量使用view。基于程序方便维护,程序通用性强,减少对数据库的依赖,增强程序代码的处理。也就是现今大多数软件公司都减少dba的角色,增强java代码来处理。
    特例:但在大型项目中,分页采用存储过程。
  1. 在企业的实际开发中,由于这种底层封装效率太低,要做大量数据操作时或者大量连接查询统计时,spring jdbctemplate 直接访问数据。sqlDao封装spring jdbctemplate。

  2. sqlDao返回list集合实际是一个一唯字符串数组

    3.分表技术

当业务数据量非常巨大时,常用的优化方式。一张表的数据量过大,这样在日常的操作时速度非常缓慢。怎么提高它的响应的速度,实际中就是将一些不常在使用的数据移动到另一张表中,而这另一张表叫历史表。历史表和原来的表结构一致。这样当前表由于只使用当前的部分数据,所以性能提高。因为实际业务中很少再去查询历史表,即使查询历史表由于使用的人也少,所以它的性能还能适应。

表结构一样,新创建表结果跟它一样

在HDD+SSD的zotac 1060,装win10于SSD

发表于 2017-06-15

1.自制win10系统U盘

UltralSO 系统U盘制作链接

2.装系统ing……

2.1 开机时,按Esc进入主板Biso设置界面

2.2 按F8进入U盘启动(因自己的PC主板而异)

2.3 插入U盘,重新启动,进入U盘启动,按照提示一步一步,进入分区设置,系统装入分区设置,因自己需求设置相应的的分区

2.4 在设置分区界面,shift+f10进入dos操作命令界面

2.4.1 第一步、全新安装系统过程中,在选择目标磁盘,安装程序会提示不创建GPT分区,不能完成安装,这时候我们按下Shift+F10,会出现命令提示符(管理员)界面

2.4.2 第二步、键入diskpart命令后回车,然后完成下面的命令,相关命令为:

1、list disk-------------------列出系统计算机所有磁盘
2、select disk 0 --------------选择0号磁盘,数字并不一定和下面截图完全相同
我们需要根据磁盘大小,判断安装系统的目标磁盘

2.4.3 第三步、选定磁盘后,完成下述命令,相关命令为:

1、clean------------------------清除磁盘,该命令将擦除磁盘上的所有数据
2、convert gpt------------------将磁盘转换为GPT格式
3、list partition---------------列出磁盘上的分区

完成查处和转换操作后,输入list partition命令,会显示这个磁盘上没有显示的分区,是因为我们刚4刚完成转换成GPT分区格式,分区为空

2.4.4 第四步、接下来要创建EFI分区及系统安装分区,相关命令为:

  1. create partition efi size=100–创建EFI分区,大小为100M
  2. create partition msr size=128–创建MSR分区,微软默认大小是128M
  3. create partition primary size=50000–创建主分区,这里要注意数字按M计算,50000就是分区大小为50000M,可以根据自己实际情况调整,该分区用来安装win7
  4. list partition—————–列出磁盘上的分区

温馨提示:diskpart命令的详细内容,可以利用键入help命令查看

2.4.5  第五步、输入Exit,退出命令提示符界面,返回安装界面

  利用diskpart命令创建GPT磁盘分区图文教程的内容,看着很复杂,实际上比起第三方磁盘工具,优势表现在可以更改GPT格式磁盘的分区ID

[具体操作链接](http://www.beihaiting.com/a/XTJC/XTJQ/2014/0815/5127.html)

3.ssd装系统注意事项

  1. 4k分区(网上说的,但是自己没用到,因为是重新格式化的ssd,所以默认是4k分区)

基于SSM的商贸平台项目(第八天)

发表于 2017-06-07

1.设计方式

1.1打断设计:

传统方式创建对象关联,当业务层级过多,查询效率极速下降,业界有个不成文的规定,在数据库表设计时,关联关系部超过4层。打断设计将业务多级进行分解,硬拆成多个块。具体实现就是通过一个字段来存储两个表之间的关系。存储主表的ID,将多个ID用特殊符号分割。

##1.2数据搬家:(冗余,分次计算)
将合同下的部分信息直接放在报运下的货物表中,这样直接在报运的货物表中查询(无需关心是哪个合同的货物信息,也无需关系货物部分信息和报运部分信息的对应)

由于有分次报运的概念,因为一个货物可以分多次报运,一个合同下的货物信息,可能分多次报运,最终所有货物报运完成。例如:1000,第一次报运800,第二次报运200。不能将报运新增的7个字段,冗余到合同下的货物表中。

报运的附件表实现了整体的数据搬家,为了后续业务在查询货物时,也可以直接查询到附件信息,主要是为财务业务服务。

##1.3分次计算
当系统中有一个集中处理数据的地方,如果它非常耗时,我们对其要进行优化。例如:毛重、净重、体积信息。它会导致用户等待。我们对其进行优化,将集中计算分到不同的地方。我们将总的计算,分解到货物新增时,只计算一条。用户由于本身新增数据,他感觉要保存新增的数据,所以他能容忍稍微等待。在新增时程序动态计算冗余的内容。因为处理数据量极其小,造成处理速度很快,几乎用户感觉不到延迟。

2.特殊设计:一对一;

1) 委托ID就是装箱ID,发票ID就是装箱ID,财务ID就是装箱ID。
2) 委托、发票、财务它们的主键既外键
无论获得一个什么ID,只要是装箱、委托、发票、财务其中之一,就可以获得任何一个它们的对象。

#2.传递数据时,数据可以隐藏到同一个框中
实际开发中少量传递数据的方式。无需查询数据库,提高性能,缺点就需要手动拼串,解串。

// 拼接HTML片段
public String getDivDataCreate(String[] contractIds) {
    StringBuffer sBuf = new StringBuffer();
    for (int i = 0; i < contractIds.length; i++) {
        Export export = exportDao.get(contractIds[i]);
        sBuf.append(
                "<input type=\"checkbox\" name=\"exportIds\" checked value=\"")
                .append(contractIds[i]).append("|")
                .append(export.getCustomerContract())
                .append("\" class=\"input\"/>");
        sBuf.append(export.getCustomerContract()).append("&nbsp;&nbsp;");
    }
    return sBuf.toString();
}

// 拆串拼串
private PackingList spellString(PackingList packingList) {
    String _exportIds = "";
    String _exportNos = "";

    String[] _ids = packingList.getExportIds().split(",");
    for (int i = 0; i < _ids.length; i++) {
        String[] _temids = _ids[i].split("\\|"); // 正则表达式,转义
        _exportIds += _temids[0] + "|";
        _exportNos += _temids[1] + "|";
    }
    _exportIds = UtilFuns.delLastChar(_exportIds); // 去掉最后的“|”
    _exportNos = UtilFuns.delLastChar(_exportNos);

    packingList.setExportIds(_exportIds);
    packingList.setExportNos(_exportNos);
    return packingList;
}
12
FangChao.Qu

FangChao.Qu

所有人都在努力,并不是只有你满腹委屈

20 日志
6 标签
GitHub 微博
© 2017 FangChao.Qu
由 Hexo 强力驱动
主题 - NexT.Muse