QRCode是被广泛应用的一种二维码,解码速度快。二维码相对于条形码来说,二维码的存储数据量更大,空间利用率高,有一定的容错性。

二维码原理介绍:

二维码是用某种特定的几何图形按一定的规律在平面上分布的黑白相间的图形记录数据符号信息的;

在代码编制上巧妙的利用构成计算机内部逻辑基础的0/1比特流的概念,使用若干个与二进制相对应的几何形体来表示文字数值信息,通过图像输入设备或光电扫描设备自动识读以实现信息自动处理;

二维码能够在横向和纵向两个方位同时表达信息,因此能在很小的面积内表达大量的信息;

二维码相对于条形码的优势就是省空间;

上图是一个QRCode的基本结构:

位置探测图形、位置探测图形分隔符、定位图形:用于二维码的定位,对每个QR来说,位置都是固定存在的,只是大小规格有所差异;

校正图形:确定规格,校正图形的数量和位置也就确定了;

格式信息:表示二维码的纠错级别,分为L、M、Q、H;

版本信息:即二维码的规格,QR码符号共有40种规格的矩阵;

数据和纠错码字:实际保存的二维码信息,和纠错码字(用于修正二维码损坏带来的错误)。

条形码原理介绍:

条形码扫描器结构

由于不同颜色的物体,其反射的可见光的波长不同,所以当条形码扫描器光源发出的光经光阑及凸透镜1后,照射到黑白相间的条形码上时,反射光经凸透镜2聚焦后,照射到光电转换器上,于是光电转换器接受到与白条和黑条相对应的强弱不同的反射光信号,并转换成相应的电信号输出到放大整形电路,整形电路把模拟信号转换成数字电信号,再经译码接口电路译成数字字符信息。

整形电路的脉冲数字信号经译码器译成数字、字符信息.它通过识别起始、终止字符来判别出条形码符号的码制及扫描方向;通过测量脉冲数字电信号0、1的数目来判别出条和空的数目.通过测量0、1信号持续的时间来判别条和空的宽度.这样便得到了被辩读的条形码符号的条和空的数目及相应的宽度和所用码制,根据码制所对应的编码规则,便可将条形符号换成相应的数字、字符信息,通过接口电路送给计算机系统进行数据处理与管理,便完成了条形码辨读的全过程。

Zxing是一个开源的,用于Java实现的多种格式的1D/2D条码图像处理库,它包含了联系到其他语言的接口。

Zxing可以实现使用手机的内置摄像头完成条形码和二维码的扫描与解码。

Zxing可以实现条形码和二维码的编码与解码。

Zxing目前支持的格式如下:UPC-A、UPC-E、EAN-8、EAN-13、39码、93码、代码128、QR码。

二、Zxing使用原理介绍

Zxing是一个开源的,用于Java实现的多种格式的1D/2D条码图像处理库,它包含了联系到其他语言的接口。

Zxing可以实现使用手机的内置摄像头完成条形码和二维码的扫描与解码。

Zxing可以实现条形码和二维码的编码与解码。

Zxing目前支持的格式如下:UPC-A、UPC-E、EAN-8、EAN-13、39码、93码、代码128、QR码。

三、实现步骤

1.导入Zxing.jar包,直接将源码内的com.mining.app.zxing.camera,com.mining.app.zxing.decoding, com.mining.app.zxing.view, com.mining.app.zxing.encoding四个文件夹,zxing package直接复制到你的工程目录下。

源码下载地址:http://code.google.com/p/zxing/

GitHub下载地址:https://github.com/zxing/zxing

2.将raw文件(用于),values,权限以及资源文件,全部准备完全,详情可参见源码。

3. activity.xml主菜单布局文件

?
1
2
3
4
5
6
7
8
9
10
11
<linearlayout android:background="#ffe1e0de" android:layout_height="match_parent" android:layout_width="match_parent" android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"><button android:id="@+id/button1" android:layout_alignparenttop="true" android:layout_height="wrap_content" android:layout_width="fill_parent" android:text="扫描二维码/条形码">
    <edittext android:id="@+id/et_qr_string" android:layout_height="wrap_content" android:layout_width="match_parent">
    <linearlayout android:layout_height="wrap_content" android:layout_width="match_parent">
        </linearlayout></edittext></button><button android:id="@+id/button2" android:layout_alignparenttop="true" android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="生成二维码"></button><button android:id="@+id/button3" android:layout_alignparenttop="true" android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="生成条形码">
     
    <textview android:gravity="center_horizontal" android:id="@+id/result" android:layout_below="@+id/button1" android:layout_height="wrap_content" android:layout_width="fill_parent" android:lines="2" android:textcolor="@android:color/black" android:textsize="16sp">
    <imageview android:id="@+id/qrcode_bitmap" android:layout_alignparentleft="true" android:layout_below="@+id/result" android:layout_height="fill_parent" android:layout_width="fill_parent">
</imageview></textview></button></linearlayout>

4.activity_capture.xml扫描布局文件

?
1
2
3
4
5
6
7
8
9
10
11
12
13
<!--?xml version="1.0" encoding="utf-8"?-->
<framelayout android:layout_height="fill_parent" android:layout_width="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android">
    <relativelayout android:layout_height="fill_parent" android:layout_width="fill_parent">
        <surfaceview android:id="@+id/preview_view" android:layout_gravity="center" android:layout_height="fill_parent" android:layout_width="fill_parent">
        <zxing.view.viewfinderview android:id="@+id/viewfinder_view" android:layout_height="wrap_content" android:layout_width="wrap_content">
        <include android:id="@+id/include1" android:layout_alignparenttop="true" android:layout_height="wrap_content" android:layout_width="fill_parent" layout="@layout/activity_title">
    </include></zxing.view.viewfinderview></surfaceview></relativelayout>
</framelayout>

5.activity_title.xml Title布局文件

?
1
2
3
4
5
6
<!--?xml version="1.0" encoding="utf-8"?-->
<relativelayout android:background="@drawable/mmtitle_bg_alpha" android:layout_height="wrap_content" android:layout_width="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android"><button android:background="@drawable/mm_title_back_btn" android:id="@+id/button_back" android:layout_centervertical="true" android:layout_height="wrap_content" android:layout_marginleft="2dip" android:layout_width="75.0dip" android:text="返回" android:textcolor="@android:color/white">
    <textview android:gravity="center_vertical" android:id="@+id/textview_title" android:layout_alignbaseline="@+id/button_back" android:layout_alignbottom="@+id/button_back" android:layout_centerhorizontal="true" android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="二维码扫描" android:textcolor="@android:color/white" android:textsize="18sp">
</textview></button></relativelayout>

上述文件用于标签,便于修改以及占少量内存

6.MainActivity.java.主界面用于事件的处理

?
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package example.com.zxingdemo;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.google.zxing.WriterException;
import zxing.encoding.EncodingHandler;
public class MainActivity extends Activity {
    private final static int SCANNIN_GREQUEST_CODE = 1;
    /**
     * 显示扫描结果
     */
    private TextView mTextView ;
    /**
     * 显示扫描拍的图片
     */
    private ImageView mImageView;
    /**
     * 输入框产生二维码
     * @param savedInstanceState
     */
    private EditText qrStrEditText;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTextView = (TextView) findViewById(R.id.result);
        mImageView = (ImageView) findViewById(R.id.qrcode_bitmap);
        qrStrEditText = (EditText) findViewById(R.id.et_qr_string);
        //点击按钮跳转到二维码扫描界面,这里用的是startActivityForResult跳转
        //扫描完了之后调到该界面
        Button mButtonScan = (Button) findViewById(R.id.button1);
        Button mBtnTwoCode = (Button) findViewById(R.id.button2);
        Button mBtnOneCode = (Button) findViewById(R.id.button3);
        mButtonScan.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                intent.setClass(MainActivity.this, MipcaActivityCapture.class);
                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivityForResult(intent, SCANNIN_GREQUEST_CODE);
            }
        });
        //产生二维码
        mBtnTwoCode.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                String contentString = qrStrEditText.getText().toString();
                try {
                    if (!contentString.equals("")) {
                        Bitmap qrCodeBitmap = EncodingHandler.createQRCode(contentString, 350);
                        mImageView.setImageBitmap(qrCodeBitmap);
                        qrStrEditText.setText("");
                        mTextView.setText(contentString);
                    } else {
                        Toast.makeText(getApplicationContext(), "Text can be not empty", Toast.LENGTH_SHORT).show();
                    }
                } catch (WriterException e) {
                    e.printStackTrace();
                }
            }
        });
        //产生条形码
        mBtnOneCode.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                String contentString = qrStrEditText.getText().toString();
                int size = contentString.length();
                for (int i = 0; i < size; i++) {
                    int c = contentString.charAt(i);
                    if ((19968 <= c && c < 40623)) {
                        Toast.makeText(getApplicationContext(), "text not be chinese", Toast.LENGTH_SHORT).show();
                        return;
                    }
                }
                Bitmap mBmpOneCode = null;
                try {
                    if (contentString != null && !"".equals(contentString)) {
                        mBmpOneCode = EncodingHandler.CreateOneDCode(contentString);
                        qrStrEditText.setText("");
                        mTextView.setText(contentString);
                    }
                } catch (WriterException e) {
                    e.printStackTrace();
                }
                if (mBmpOneCode != null) {
                    mImageView.setImageBitmap(mBmpOneCode);
                }
            }
        });
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case SCANNIN_GREQUEST_CODE:
                if(resultCode == RESULT_OK){
                    Bundle bundle = data.getExtras();
                    //显示扫描到的内容
                    mTextView.setText(bundle.getString("result"));
                    //显示
                    mImageView.setImageBitmap((Bitmap) data.getParcelableExtra("bitmap"));
                }
                break;
        }
    }
}

7.MipcaActivityCapture.java.主要是调用起Camera功能进行扫描

?
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
package example.com.zxingdemo;
import android.app.Activity;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.graphics.Bitmap;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Bundle;
import android.os.Handler;
import android.os.Vibrator;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.Result;
import java.io.IOException;
import java.util.Vector;
import zxing.camera.CameraManager;
import zxing.decoding.CaptureActivityHandler;
import zxing.decoding.InactivityTimer;
import zxing.view.ViewfinderView;
/**
 * Initial the camera
 * @author Ryan.Tang
 */
public class MipcaActivityCapture extends Activity implements Callback {
    private CaptureActivityHandler handler;
    private ViewfinderView viewfinderView;
    private boolean hasSurface;
    private Vector<barcodeformat> decodeFormats;
    private String characterSet;
    private InactivityTimer inactivityTimer;
    private MediaPlayer mediaPlayer;
    private boolean playBeep;
    private static final float BEEP_VOLUME = 0.10f;
    private boolean vibrate;
    /**
     * Called when the activity is first created.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_capture);
        //ViewUtil.addTopView(getApplicationContext(), this, R.string.scan_card);
        CameraManager.init(getApplication());
        viewfinderView = (ViewfinderView) findViewById(R.id.viewfinder_view);
        Button mButtonBack = (Button) findViewById(R.id.button_back);
        mButtonBack.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                MipcaActivityCapture.this.finish();
            }
        });
        hasSurface = false;
        inactivityTimer = new InactivityTimer(this);
    }
    @Override
    protected void onResume() {
        super.onResume();
        SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
        SurfaceHolder surfaceHolder = surfaceView.getHolder();
        if (hasSurface) {
            initCamera(surfaceHolder);
        } else {
            surfaceHolder.addCallback(this);
            surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        }
        decodeFormats = null;
        characterSet = null;
        playBeep = true;
        AudioManager audioService = (AudioManager) getSystemService(AUDIO_SERVICE);
        if (audioService.getRingerMode() != AudioManager.RINGER_MODE_NORMAL) {
            playBeep = false;
        }
        initBeepSound();
        vibrate = true;
    }
    @Override
    protected void onPause() {
        super.onPause();
        if (handler != null) {
            handler.quitSynchronously();
            handler = null;
        }
        CameraManager.get().closeDriver();
    }
    @Override
    protected void onDestroy() {
        inactivityTimer.shutdown();
        super.onDestroy();
    }
    /**
     * 处理扫描结果
     *
     * @param result
     * @param barcode
     */
    public void handleDecode(Result result, Bitmap barcode) {
        inactivityTimer.onActivity();
        playBeepSoundAndVibrate();
        String resultString = result.getText();
        if (resultString.equals("")) {
            Toast.makeText(MipcaActivityCapture.this, "Scan failed!", Toast.LENGTH_SHORT).show();
        } else {
            Intent resultIntent = new Intent();
            Bundle bundle = new Bundle();
            bundle.putString("result", resultString);
            bundle.putParcelable("bitmap", barcode);
            resultIntent.putExtras(bundle);
            this.setResult(RESULT_OK, resultIntent);
        }
        MipcaActivityCapture.this.finish();
    }
    private void initCamera(SurfaceHolder surfaceHolder) {
        try {
            CameraManager.get().openDriver(surfaceHolder);
        } catch (IOException ioe) {
            return;
        } catch (RuntimeException e) {
            return;
        }
        if (handler == null) {
            handler = new CaptureActivityHandler(this, decodeFormats,
                    characterSet);
        }
    }
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
                               int height) {
    }
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        if (!hasSurface) {
            hasSurface = true;
            initCamera(holder);
        }
    }
    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        hasSurface = false;
    }
    public ViewfinderView getViewfinderView() {
        return viewfinderView;
    }
    public Handler getHandler() {
        return handler;
    }
    public void drawViewfinder() {
        viewfinderView.drawViewfinder();
    }
    private void initBeepSound() {
        if (playBeep && mediaPlayer == null) {
            // The volume on STREAM_SYSTEM is not adjustable, and users found it
            // too loud,
            // so we now play on the music stream.
            setVolumeControlStream(AudioManager.STREAM_MUSIC);
            mediaPlayer = new MediaPlayer();
            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            mediaPlayer.setOnCompletionListener(beepListener);
            AssetFileDescriptor file = getResources().openRawResourceFd(
                    R.raw.beep);
            try {
                mediaPlayer.setDataSource(file.getFileDescriptor(),
                        file.getStartOffset(), file.getLength());
                file.close();
                mediaPlayer.setVolume(BEEP_VOLUME, BEEP_VOLUME);
                mediaPlayer.prepare();
            } catch (IOException e) {
                mediaPlayer = null;
            }
        }
    }
    private static final long VIBRATE_DURATION = 200L;
    private void playBeepSoundAndVibrate() {
        if (playBeep && mediaPlayer != null) {
            mediaPlayer.start();
        }
        if (vibrate) {
            Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
            vibrator.vibrate(VIBRATE_DURATION);
        }
    }
    /**
     * When the beep has finished playing, rewind to queue up another one.
     */
    private final OnCompletionListener beepListener = new OnCompletionListener() {
        public void onCompletion(MediaPlayer mediaPlayer) {
            mediaPlayer.seekTo(0);
        }
    };
}</barcodeformat>

四、代码分析

1.生成二维码

调用方法:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//产生二维码
        mBtnTwoCode.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                String contentString = qrStrEditText.getText().toString();
                try {
                    if (!contentString.equals("")) {
                        Bitmap qrCodeBitmap = EncodingHandler.createQRCode(contentString, 350);
                        mImageView.setImageBitmap(qrCodeBitmap);
                        qrStrEditText.setText("");
                        mTextView.setText(contentString);
                    } else {
                        Toast.makeText(getApplicationContext(), "Text can be not empty", Toast.LENGTH_SHORT).show();
                    }
                } catch (WriterException e) {
                    e.printStackTrace();
                }
            }
        });

实现方法:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
private static final int BLACK = 0xff000000;
    //生成二维码
    public static Bitmap createQRCode(String str,int widthAndHeight) throws WriterException {
        Hashtable<encodehinttype, string=""> hints = new Hashtable<encodehinttype, string="">(); 
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
        BitMatrix matrix = new MultiFormatWriter().encode(str,
                BarcodeFormat.QR_CODE, widthAndHeight, widthAndHeight);
        int width = matrix.getWidth();
        int height = matrix.getHeight();
        int[] pixels = new int[width * height];
         
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                if (matrix.get(x, y)) {
                    pixels[y * width + x] = BLACK;
                }
            }
        }
        Bitmap bitmap = Bitmap.createBitmap(width, height,
                Bitmap.Config.ARGB_8888);
        bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
        return bitmap;
    }</encodehinttype,></encodehinttype,>

2.生成条形码

调用方法:

?
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
//产生条形码
        mBtnOneCode.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                String contentString = qrStrEditText.getText().toString();
                int size = contentString.length();
                for (int i = 0; i < size; i++) {
                    int c = contentString.charAt(i);
                    if ((19968 <= c && c < 40623)) {
                        Toast.makeText(getApplicationContext(), "text not be chinese", Toast.LENGTH_SHORT).show();
                        return;
                    }
                }
                Bitmap mBmpOneCode = null;
                try {
                    if (contentString != null && !"".equals(contentString)) {
                        mBmpOneCode = EncodingHandler.CreateOneDCode(contentString);
                        qrStrEditText.setText("");
                        mTextView.setText(contentString);
                    }
                } catch (WriterException e) {
                    e.printStackTrace();
                }
                if (mBmpOneCode != null) {
                    mImageView.setImageBitmap(mBmpOneCode);
                }
            }
        });

实现方法:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//生成条形码
    public static Bitmap CreateOneDCode(String content) throws WriterException {
        // 生成一维条码,编码时指定大小,不要生成了图片以后再进行缩放,这样会模糊导致识别失败
        BitMatrix matrix = new MultiFormatWriter().encode(content,
                BarcodeFormat.CODE_128, 500, 200);
        int width = matrix.getWidth();
        int height = matrix.getHeight();
        int[] pixels = new int[width * height];
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                if (matrix.get(x, y)) {
                    pixels[y * width + x] = BLACK;
                }
            }
        }

3.扫描二维码、条形码

?
1
2
3
4
5
6
7
8
9
10
mButtonScan.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                intent.setClass(MainActivity.this, MipcaActivityCapture.class);
                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivityForResult(intent, SCANNIN_GREQUEST_CODE);
            }
        });

五、实现效果图

 

 

Zxing实现工作原理之QRCode相关推荐

  1. 2021年大数据ELK(十八):Beats 简单介绍和FileBeat工作原理

    全网最详细的大数据ELK文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. 目录 Beats 简单介绍和FileBeat工作原理 一.Beats 二.FileB ...

  2. 深入理解Nginx工作原理

    1 反向代理 1.1 概念 反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给intern ...

  3. 高频开关电源原理_程控开关电源的工作原理

    本文介绍了开关电源的工作原理以及它的特点. 程控开关电源要要比线性电源复杂得多. 下图是典型的开关电源工作原理图. 首先对 220 V/50Hz 的 AC 输入,通过桥式整流器进行整流 储能电容对整流 ...

  4. Servlet生命周期与工作原理

    Servlet生命周期分为三个阶段: 1,初始化阶段  调用init()方法 2,响应客户请求阶段 调用service()方法 3,终止阶段 调用destroy()方法 Servlet初始化阶段: 在 ...

  5. java的工作原理你知道吗_每天用Mybatis,但是Mybatis的工作原理你真的知道吗?

    近来想写一个mybatis的分页插件,但是在写插件之前肯定要了解一下mybatis具体的工作原理吧,于是边参考别人的博客,边看源码就开干了. 核心部件:SqlSession Executor Stat ...

  6. linux网络管理原理,Linux__网络管理(物理层 数据链路层 网络层工作原理)

    千锋云计算逆战班11点后打卡 今天学习后,进行复习下,物理层 数据链路层  网络层 的工作原理 物理层关心的两件事情:1.信号 2.介质 先说信号:信号分为模拟信号和数字信号 模拟信号: 模拟信号,不 ...

  7. HDD工作原理 导图

    以上导图介绍了我们使用的 (HDD)机械硬盘的基本构造以及核心工作原理,对于大家扫盲有所帮助 参考文档: https://blog.csdn.net/yizhaoxin/article/details ...

  8. 路由和交换机工作原理

    路由器与交换机的工作原理 计算机网络往往由许多种不同类型的网络互连连接而成.如果几个计算机网络只是在物理上连接在一起,它们之间并不能进行通信,那么这种"互连"并没有什么实际意义.因 ...

  9. Google工作原理

    今天在晚上看到一个图,讲解google的工作原理,感觉写的不错.贴过来方便以后深入的研究. 转载于:https://www.cnblogs.com/muyuge/archive/2010/07/06/ ...

最新文章

  1. 用户组管理之更新分组表数据
  2. ETSafeMail安全电子邮件技术白皮书
  3. dcdc芯片效率不高的原因_半导体厂商如何做芯片的出厂测试?
  4. Comet4J推技术在SSHE三大框架中应用-linux下亲测可用
  5. 自动化测试与DevOps以及持续集成的关系。
  6. mac系统一些快捷键
  7. html文件form根目录,HTML ,form 和 link 使用根目录 的问题,我已经上图了!
  8. Atitit import sql fun 重要的sql功能扩展 ext 目录 1.1. Insert merge 1 1.2. Insert set 1 1.2.1. 13.2.5. LOAD
  9. 国外图片分享网站有哪些?20个国外免费、高清图片素材网站、图库全合集
  10. 从吃喝玩乐到学习,71个良心网站,看完你会回来点收藏
  11. 32位服务器系统支持8G内存,32位系统怎么支持8g内存条win10 64位系统闲置服务器...
  12. Centos6.10系统迁移到新固态硬盘LVM
  13. 微信企业号接入微信支付
  14. html5的video在IOS端默认全屏和黑屏问题
  15. uni-app 保存图片到本地相册
  16. Ubuntu16.04系统联网(连接WiFi)设置(亲测有效!!!)
  17. 图片上传系统在淘系中的实践
  18. jquery方法之append()与appendto()
  19. DMP文件的生成和使用
  20. U-boot开机logo的制作方法

热门文章

  1. java menuitem 图标_java – 如何以编程方式更改ActionBar中的MenuItem图标
  2. sklearn(一)、决策树
  3. java基础一(总览全局)
  4. photoshop入门教程
  5. socket发送字符串和数组
  6. 网站页面title标题的设置方法技巧
  7. html标签的title属性
  8. misc life 未来的购物方式
  9. 计算机毕业设计Java酒店预订管理系统(源码+系统+mysql数据库+lw文档)
  10. 俄语翻译专业好就业吗?文件资料俄语翻译多少钱