Android 绘图基础:Canvas画布——自定义View基础(绘制表盘、矩形、圆形、弧、渐变)
Canvas画布,通过它我们可以自定义一个View,设置View的相关效果之类的。感觉用法差不多,重要的是要理解方法中传入的参数的含义,比如float类型的参数,传递的是坐标,已开是没有注意传入的参数时坐标,导致我迷糊了一段时间,希望大家不要犯我的错误,记住是坐标啊!。
一、Canvas画布介绍
The Canvas class holds the “draw” calls. To draw something, you need 4 basic components: A Bitmap to hold the pixels, a Canvas to host the draw calls (writing into the bitmap), a drawing primitive (e.g. Rect, Path, text, Bitmap), and a paint (to describe the colors and styles for the drawing).
关于Canvas网上也没有什么好的介绍, 我就直接从API中复制过来的,这里翻译一下。
Canvas 支持“绘制”调用,想要进行绘制,你需要4个基本组成:一个由像素构成的位图,支持绘制调用的画布(绘制位图),一个图元(如矩形,路径,文本,位图),和油漆(用于绘制图的颜色和样式)。
(上面的四个基本组成会在后面代码部分进行解释)
API中说的究竟是什么意思呢?我们可以把这个Canvas理解成系统提供给我们的一块内存区域(但实际上它只是一套画图的API,真正的内存是下面的Bitmap),而且它还提供了一整套对这个内存区域进行操作的方法,所有的这些操作都是画图API。这样我们就可以在画布上进行绘制了。
二、使用步骤
上面说了那么多是不是特别想知道它要怎样使用呢?现在我们就来说说他的使用步骤。
2.1使用步骤
1、写一个class类继承自View
2、在继承的class中写它的两个构造器,以前的版本中我们只需要写它的两个构造器(一个构造器参数为View(Context)另一个构造器参数为 View(Context AttributeSet) ),现在版本的升级又新出了两个构造器(View(Context attribute style)带有主题样式的),不管那么多,我们还是只写本来的两个构造器就OK了。
3、在该class中调用onDraw方法和onMeasure()方法。
4、在布局中使用该View
5、进行绘制
2.1使用示例
下面我们按照上面的步骤一步步进行
1、写一个class类继承自View
public class MyView extends View
2、在继承的class中写它的两个构造器
public MyView(Context context) {
super(context);
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
}
在该class中重写onDraw方法和onMeasure()方法。
onDraw(我们将在该方法中进行绘制图形)
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
onMeasure(获得画布的高度与宽度)
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
}
补充:由于onMeasure方法中本身就有获取高度与宽度的方法,我们直接点进去(ctrl+左键),复制出来就可以了。
在布局中使用该View(布局时必须写全包名+类名)
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<com.example.myview.MyView
android:layout_width="match_parent"
android:layout_height="match_parent"
5、进行绘制
我们要如何进行绘制呢?首先我们看些Canvas都能绘制写什么。
drawRect(float left, float top, float right, float bottom, Paint paint)
//绘制矩形(左上右下的坐标,我们可以理解为左上的坐标为我们确定了矩形的左上角点,右下坐标为我们确定了右下角的点,这样一个矩形区域就确定出来了,paint为画笔)
drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, Paint paint)
//绘制圆角矩形(左上右下的坐标)
drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)
//绘制弧(参数一是RectF对象,一个矩形区域椭圆形的界限用于定义在形状、大小、电弧,参数二是起始角(度)在电弧的开始,
参数三扫描角(度)开始顺时针测量的,参数四是如果这是真的话,包括椭圆中心的电弧,并关闭它,实际绘制的是扇形,如果它是假这将是一个弧线,参数五是Paint对象)
drawOval(float left, float top, float right, float bottom, Paint paint)
//绘制椭圆
drawLine(float startX, float startY, float stopX, float stopY, Paint paint)
//绘制直线(XY起止坐标)
drawCircle(float cx, float cy, float radius, Paint paint)
//绘制圆形
drawText(String text, float x, float y, Paint paint)
//绘制文本
其他的不再进行列举,有需要可以查看API文档。
在参数中可以看到我们画图是需要画笔的,下面我们再来看下画笔(画漆)。这里展示一段代码相信你就能够明白了。
Paint mpaintline = new Paint();
mpaintline.setColor(Color.RED);
//设置线宽
mpaintline.setStrokeWidth(10);
//设置抗锯齿
mpaintline.setAntiAlias(true);
//设置空心,比如画实心圆还是空心圆
mpaintcircle.setStyle(Paint.Style.STROKE);
mpainttext.setTextSize(30);
//设置字的位置
mpainttext.setTextAlign(Align.CENTER);
mpainttext.setColor(Color.BLACK);
2.2表盘示例
上面说了那么多,我们来看一个具体而完整的实例,来整理一下思路。
public class MyView extends View
private int width;
private int height;
private Paint mpaintline;
private Paint mpaintcircle;
private Paint mpainttext;
private Calendar mcalendar;
private static final int NEED_INVALIDATE=0x23;
private Handler mhandler=new Handler(){
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case NEED_INVALIDATE:
//重新获取时间
mcalendar=Calendar.getInstance();
//重新绘制界面
invalidate();//告诉UI主线程重新绘制
//再次发送消息,递归调用,再次监测秒针
mhandler.sendEmptyMessageDelayed(NEED_INVALIDATE, 1000);
break;
default:
break;
}
};
};
public MyView(Context context) {
super(context);
}
public MyView(Context context, AttributeSet attrs) { //为了不是每次都创建Paint,我们在这里创建
super(context, attrs);
mcalendar=Calendar.getInstance();
mpaintline = new Paint();
mpaintline.setColor(Color.RED);
//设置线宽
mpaintline.setStrokeWidth(10);
//设置抗锯齿
mpaintline.setAntiAlias(true);
mpaintcircle = new Paint();
mpaintcircle.setColor(Color.GREEN);
mpaintcircle.setStrokeWidth(10);
//设置空心
mpaintcircle.setStyle(Paint.Style.STROKE);
mpainttext=new Paint();
mpainttext.setTextSize(30);
mpainttext.setTextAlign(Align.CENTER);
mpainttext.setColor(Color.BLACK);
//发送消息,监测秒针
mhandler.sendEmptyMessage(NEED_INVALIDATE);
}
//在此方法中进行绘制
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//绘制圆形
canvas.drawCircle(width/2, height/2, width/2-20, mpaintcircle);
//绘制表芯
canvas.drawCircle(width/2, height/2, 5, mpaintcircle);
//绘制表盘时我们采用旋转画布的思想,让画布进行旋转一定角度,绘制
for(int i=1;i<=12;i++){
//保存画布当前状态
canvas.save();
//指定旋转角度与旋转点
canvas.rotate(360/12*i,width/2,height/2);
//绘制表盘
canvas.drawLine(width/2, height/2-(width/2-20), width/2,height/2-width/2+40, mpaintline);
//绘制文字
canvas.drawText(""+i, width/2, height/2-width/2+70, mpainttext);
//恢复开始位置
canvas.restore();
}
int minute=mcalendar.get(Calendar.MINUTE);
int hour=mcalendar.get(Calendar.HOUR);
int second=mcalendar.get(Calendar.SECOND);
float minudegrees=minute/60f*360;
float hourdregrees=hour*60/12f/60*360;
float senconddegree=second/60f*360;
//绘制分针
canvas.save();
canvas.rotate(minudegrees,width/2,height/2);
canvas.drawLine(width/2, height/2, width/2, height/2-width/2+90, mpaintline);
canvas.restore();
//绘制时针
canvas.save();
canvas.rotate(hourdregrees,width/2,height/2);
canvas.drawLine(width/2, height/2, width/2, height/2-width/2+100, mpaintline);
canvas.restore();
//绘制秒针
canvas.save();
canvas.rotate(senconddegree,width/2,height/2);
canvas.drawLine(width/2, height/2, width/2, height/2-width/2+60, mpaintline);
canvas.restore();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//固定
2.3绘制圆形progressbar
这里模拟下载,自定义了一个ProgressBar。在MyProgressCircle 中定义出最大进度和当前进度,给出当前进度的SET\GET方法,通过Mainactivity中改变Progres的当前进度,根据当前进度,不停修改半径,重新绘制表层绿色圆形。
public class MyProgressCircle extends View{
private int width;
private int height;
private int Maxprogress=100;
private int Currentprogress;
private Paint PaintBackGround;
private Paint PaintCurrent;
private Paint PaintText;
public int getMaxprogress() {
return Maxprogress;
}
public void setMaxprogress(int maxprogress) {
Maxprogress = maxprogress;
}
//当前进度的set、get方法
public int getCurrentprogress() {
return Currentprogress;
}
public void setCurrentprogress(int currentprogress) {
Currentprogress = currentprogress;
invalidate();
}
public MyProgressCircle(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public MyProgressCircle(Context context, AttributeSet attrs) {
super(context, attrs);
PaintBackGround=new Paint();
PaintBackGround.setColor(Color.GRAY);
PaintBackGround.setAntiAlias(true);
PaintBackGround.setStrokeWidth(10);
PaintCurrent=new Paint();
PaintCurrent.setColor(Color.GREEN);
PaintCurrent.setAntiAlias(true);
PaintCurrent.setStrokeWidth(10);
PaintText=new Paint();
PaintText.setColor(Color.BLACK);
PaintText.setAntiAlias(true);
PaintText.setTextAlign(Align.CENTER);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(width/2, height/2,width/2-30 , PaintBackGround);
//根据当前进度改变半径,绘制圆形
canvas.drawCircle(width/2, height/2,(float) (width/2-30)*Currentprogress/Maxprogress, PaintCurrent);
canvas.drawText(Currentprogress*100f/Maxprogress+"%", width/2,height/2, PaintText);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
}
}
MainActivity中改变progress进度
public class MainActivity extends Activity implements OnClickListener{
private Button btn_circle_progress;
private MyProgressCircle myprogresscircle;
private int progress;
private Handler mhanHandler=new Handler(){
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case 0x23:
progress++;
if(progress<=100){
myprogresscircle.setCurrentprogress(progress);
mhanHandler.sendEmptyMessageDelayed(0x23, 200);
}
break;
default:
break;
}
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.circle_progress);
btn_circle_progress=(Button) findViewById(R.id.mbtn_circleprogress);
myprogresscircle=(MyProgressCircle) findViewById(R.id.mycircleprogress);
btn_circle_progress.setOnClickListener(this);
}
@Override
public void onClick(View v) {
mhanHandler.sendEmptyMessageDelayed(0x23, 1000);
}
}
2.4绘制弧形progressbar
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//设置画弧的区域
RectF oval1=new RectF(width/2-100,height/2-100,width/2+100,height/2+100);
canvas.drawArc(oval1, 270, Currentprogress, false, PaintCurrent);//第二个参数:顺时针起始位置;第三个参数:顺时针转的弧
canvas.drawText(Currentprogress*100f/Maxprogress+"%", width/2,height/2, PaintText);
}
MainActivity
public class MainActivity_ARC extends Activity implements OnClickListener{
private Button btn_arc_progress;
private MyArcProgress myprogressarc;
private int progress;
private Handler mhanHandler=new Handler(){
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case 0x23:
progress++;
if(progress<=360){
myprogressarc.setCurrentprogress(progress);
mhanHandler.sendEmptyMessageDelayed(0x23, 200);
}
break;
default:
break;
}
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.arc_progress);
btn_arc_progress=(Button) findViewById(R.id.mbtn_arcprogress);
myprogressarc= (MyArcProgress) findViewById(R.id.myarcprogress);
btn_arc_progress.setOnClickListener(this);
}
@Override
public void onClick(View v) {
mhanHandler.sendEmptyMessageDelayed(0x23, 1000);
}
}
2.5绘制多条线与矩形
public class MyRectProgress extends View{
private int width;
private int height;
private int Maxprogress=100;
private int Currentprogress;
private Paint PaintBackGround;
private Paint PaintCurrent;
private Paint PaintText;
private int i;
private float[] lines=new float[400];
public int getMaxprogress() {
return Maxprogress;
}
public void setMaxprogress(int maxprogress) {
Maxprogress = maxprogress;
}
public int getCurrentprogress() {
return Currentprogress;
}
public void setCurrentprogress(int currentprogress) {
Currentprogress = currentprogress;
lines[i]=50;
i++;
lines[i]=50+250f*Currentprogress/Maxprogress;
i++;
lines[i]=300;
i++;
lines[i]=50+250f*Currentprogress/Maxprogress;
invalidate();
}
public MyRectProgress(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public MyRectProgress(Context context, AttributeSet attrs) {
super(context, attrs);
PaintBackGround=new Paint();
PaintBackGround.setColor(Color.GRAY);
PaintBackGround.setAntiAlias(true);
PaintBackGround.setStrokeWidth(10);
PaintCurrent=new Paint();
PaintCurrent.setColor(Color.GREEN);
PaintCurrent.setAntiAlias(true);
PaintCurrent.setStrokeWidth(5);
PaintText=new Paint();
PaintText.setColor(Color.BLACK);
PaintText.setAntiAlias(true);
PaintText.setTextAlign(Align.CENTER);
PaintText.setTextSize(30);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//canvas.drawCircle(width/2, height/2,width/2-30 , PaintBackGround);
canvas.drawRect(50,50 ,300, 300, PaintBackGround);
canvas.drawLines(lines, PaintCurrent);
//canvas.drawLine(50,50+250f*Currentprogress/Maxprogress, 300, 50+250f*Currentprogress/Maxprogress, PaintCurrent);
canvas.drawText(Currentprogress*100f/Maxprogress+"%", width/2,height/2, PaintText);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
}
}
2.5绘制渐变
样式就是我们开始时图片展示的样式
package com.example.myview;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.RectF;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.view.View;
public class MyotherProgress extends View{
private int width;
private int height;
private int Maxprogress=100;
private int Currentprogress;
private Paint PaintBackGround;
private Paint PaintCurrent;
private Paint PaintText;
public int getMaxprogress() {
return Maxprogress;
}
public void setMaxprogress(int maxprogress) {
Maxprogress = maxprogress;
}
public int getCurrentprogress() {
return Currentprogress;
}
public void setCurrentprogress(int currentprogress) {
Currentprogress = currentprogress;
invalidate();
}
public MyotherProgress(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public MyotherProgress(Context context, AttributeSet attrs) {
super(context, attrs);
PaintBackGround=new Paint();
PaintBackGround.setColor(Color.GRAY);
PaintBackGround.setAntiAlias(true);
PaintBackGround.setStrokeWidth(10);
PaintCurrent=new Paint();
PaintCurrent.setColor(Color.GREEN);
PaintCurrent.setAntiAlias(true);
PaintCurrent.setStrokeWidth(10);
/* 设置渐变色 颜色是改变的 */
Shader mShader = new LinearGradient(0, 0, 100, 100,
new int[] { Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW,
Color.LTGRAY }, null, Shader.TileMode.REPEAT);
PaintCurrent.setShader(mShader);
PaintText=new Paint();
PaintText.setColor(Color.BLACK);
PaintText.setAntiAlias(true);
PaintText.setTextAlign(Align.CENTER);
PaintText.setTextSize(30);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//底层圆形
canvas.drawCircle(width/2, height/2,width/2-30 , PaintBackGround);
// 设置个新的长方形,扫描测量
RectF oval = new RectF(30,height/2-(width/2-30 ) , width-30 , height/2+width/2-30 );
//绘制扇形
// 画弧,第一个参数是RectF(确定绘制区域):
//该类是第二个参数是角度的开始,
//第三个参数是多少度,
//第四个参数是真的时候画扇形,是假的时候画弧线
canvas.drawArc(oval, 0, Currentprogress*360f/100, true, PaintCurrent);
canvas.drawText(Currentprogress*100f/Maxprogress+"%", width/2,height/2, PaintText);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
}
}
相关文章:
Android 绘图基础:Canvas画布——自定义View基础(绘制表盘、矩形、圆形、弧、渐变)
Canvas画布,通过它我们可以自定义一个View,设置View的相关效果之类的。感觉用法差不多,重要的是要理解方法中传入的参数的含义,比如float类型的参数,传递的是坐标,已开是没有注意传入的参数时坐标,导致我迷…...
js拷贝数组对象:浅拷贝深拷贝
前言 js拷贝数组对象:浅拷贝&深拷贝,包括:Object.assign、concat、slice、JSON.parse(JSON.stringify()) 场景:弹窗选择组织结构(树形结构),选择后显示相关数据至输入框中(每次选…...
【C++】string类的使用
目录 一、标准库中的string类 二、string类的常用接口 1、string类对象的常见构造 2、string类对象的容量操作 2.1、size 与 length 2.2、capacity 与 reserve 2.3、resize 2.4、总结 3、string类对象的访问及遍历操作 3.1、operator[] 与 at 3.2、begin end 3.3、…...
微服务架构简介
微服务 软件架构是一个包含各种组织的系统组织,这些组件包括 Web服务器, 应用服务器, 数据库,存储, 通讯层), 它们彼此或和环境存在关系。系统架构的目标是解决利益相关者的关注点。 image Conway’s law: Organizations which design systems[...] are constrained…...
【Spring源码】AOP的开端:核心对象创建的准备工作
AOP的核心成员是如何被被加载的?本篇我们主要分析使用xml的逻辑,如果使用注解,增加注解处理类即可(ConfigurationClassPostProcessor)拿之前分析循环的时候举的例子🌰,它的日志切面就是通过xml进…...
新号涨粉22w,搞笑博主再次爆火,小红书近期创作趋势是什么?
2月借势元宵、情人节,小红书平台又涌现出哪些黑马博主?品牌在投放种草方面有何亮眼表现?为洞察小红书平台的内容创作趋势及品牌营销策略,新红推出2月月度榜单,从创作者及品牌两方面入手,解析月榜数据&#…...
【C++】30h速成C++从入门到精通(内存管理、函数/类模板)
C内存分布我们先来看一下下面的一段代码相关问题int globalVar 1; static int staticGlobalVar 1; void Test() {static int staticVar 1;int localVar 1;int num1[10] {1, 2, 3, 4};char char2[] "abcd";char* pChar3 "abcd";int* ptr1 (int*)mal…...
自动驾驶决策概况
文章目录1. 第一章行为决策在自动驾驶系统架构中的位置2. 行为决策算法的种类2.1 基于规则的决策算法2.1.1 决策树2.1.2 有限状态机(FSM)2.1.3 基于本体论(Ontologies-based)2.2 基于统计的决策算法2.2.1 贝叶斯网络(B…...
金山轻维表项目进展自动通知
项目经理作为项目全局把控者,经常要和时间“赛跑”。需要实时了解到目前进展如何,跟进人是那些?哪些事项还未完成?项目整体会不会逾期?特别是在一些大型公司中,优秀的项目经理已经学会使用金山轻维表做项目…...
基于上下文分析的 Python 实时 API 推荐
原文来自微信公众号“编程语言Lab”:基于上下文分析的 Python 实时 API 推荐 搜索关注 “编程语言Lab”公众号(HW-PLLab)获取更多技术内容! 欢迎加入 编程语言社区 SIG-程序分析 参与交流讨论(加入方式:添加…...
软件测试-接口测试-代码实现接口测试
文章目录 1.request1.1 request介绍1.2 发送get请求1.3 发送set请求1.4 其他请求方式1.5 传递url参数1.6 响应内容解析1.7 cookie1.8 设置session2.集成UnitTest2.1 接口测试框架开发2.2 案例:使用TPShop项目完成对登录功能的接口测试1.request 1.1 request介绍 概念 基于py…...
中村成洋《垃圾回收的算法与实现》PDF 读书笔记
观前提醒 为了能够锻炼自己,我会查阅大量外文不停的修改内容,少部分会提示成中文。 可能有误,请见谅 提示:若是觉得阅读困难,可以看如下内容 脚本之家可获取,若失效可私信浏览器的沙拉查词扩展…...
docker 网络模式
docker 网络模式主要分为四种,可以通过docker network ls 查看 ~$ docker network ls NETWORK ID NAME DRIVER SCOPE a51d97d72f10 bridge br…...
数据库开发(一文概括mysql基本知识)
Mysql 是最流行的关系型数据库管理系统,在 WEB 应用方面 MySQL 是最好的 关系型数据库(Relational Database Management System:关系数据库管理系统)应用软件之一。mysql在问开发中,几乎必不可少,因为其他的可能是要收费的&#x…...
【JVM】详解Java内存区域和分配
这里写目录标题一、前言二、运行时数据分区2.1程序计数器(PC)2.2 Java虚拟机栈2.3 本地方法栈2.4 Java堆2.5 方法区2.5.1 运行时常量池2.6 直接内存三、HotSpot虚拟机对象探秘3.1 对象的创建3.2 对象的内存布局3.3 对象的访问定位一、前言 C/C需要自行回收和释放已经没用的对象…...
JAVA开发(史上最完整追本溯源JAVA历史、发展和学习)
(第二次世界大战1931-1945) 世界上最先进的技术往往是由于战争催生,在第二次世界大战中除了飞机,坦克和大炮的武器较量外,在隐秘战线的情报工作其实更为重要,在军队将领来往的电报中,为了防止军事情报的泄漏ÿ…...
Qt 防止程序退出
文章目录摘要QWidgetQML方法 1方法 2关键字: Qt、 eventFilter、 Close、 键盘、 任务管理器摘要 今天要聊得内容还是怎么防止别人关闭我的程序,之前都是在win下面,一般都是用过钩子连捕获键盘事件,完了吧对应的事件忽略&#x…...
【校验码 - 循环冗余校验码CRC】
水善利万物而不争,处众人之所恶,故几于道💦 目录 循环冗余校验码 1.多项式 2.CRC编码的组成 3.校验码的生成 4.例题: 循环冗余校验码 广泛地在网络通信及磁盘存储时采用。 1.多项式 在循环冗余校验(CRC)码中,无一例…...
【Rust】一文讲透Rust中的PartialEq和Eq
前言 本文将围绕对象:PartialEq和Eq,以及PartialOrd和Ord,即四个Rust中重点的Compare Trait进行讨论并解释其中的细节,内容涵盖理论以及代码实现。 在正式介绍PartialEq和Eq、以及PartialOrd和Ord之前,本文会首先介绍…...
Vulnhub靶场----9、DC-9
文章目录一、环境搭建二、渗透流程三、思路总结一、环境搭建 DC-9下载地址:https://download.vulnhub.com/dc/DC-9.zip kali:192.168.144.148 DC-9:192.168.144.158 二、渗透流程 1、信息收集nmap -T5 -A -p- -sV -sT 192.168.144.158思路&am…...
使用Containerd搭建K8s集群【v1.25】
[toc] 一、安装要求 在开始之前,部署Kubernetes集群机器需要满足以下几个条件: 一台或多台机器,操作系统 CentOS7.x-86_x64硬件配置:2GB或更多RAM,2个CPU或更多CPU,硬盘30GB或更多集群中所有机器之间网络互通可以访问外网,需要拉取镜像禁止swap分区二、准备环境 角色IP…...
NMT - 构建双语概率词典(Probabilistic dictionaries)
文章目录一、安装依赖包mosesdecoder安装 mgiza二、数据预处理三、训练本文参考:How to train your Bicleaner https://github.com/bitextor/bicleaner/wiki/How-to-train-your-Bicleaner 一、安装依赖包 这个过程主要依赖于 mosesdecodermgiza mosesdecoder git…...
《ChatGPT是怎样炼成的》
ChatGPT 在全世界范围内风靡一时,我现在每天都会使用 ChatGPT 帮我回答几个问题,甚至有的时候在一天内我和它对话的时间比和正常人类对话还要多,因为它确实“法力无边,功能强大”。 ChatGPT 可以帮助我解读程序,做翻译…...
Streaming System是第一章翻译
GIthub链接,欢迎志同道合的小伙伴一起翻译 Chapter 1.Streaming101 如今,流数据处理在大数据中是非常重要的,其主要原因是: 企业渴望对他们的数据有更及时的了解,而转换到流处理是实现更低延迟的一个好方法…...
abap MODIFY常用语法解析
MODIFY 是既可以操作数据又可以操作内表的一个语法, 实现的逻辑都一样. 如果你内表或数据库中存在该行数据会对该行数据进行更新. 如果不存在,就会插入数据. , 1.如果it_tab是带有标题行的内表,是可以忽略FROM wa_tab工作区的 MODIFY it_tab .2.把工作区wa_tab中的数据更新…...
[媒体分流直播]媒体直播和传统直播的区别,以及媒体直播的特点
传媒如春雨,润物细无声,大家好,我是51媒体网胡老师。 直播毋庸置疑已经融入到了我们生活的方方面面,小到才艺,游戏,大到政策的发布,许多企业和机构也越来越重视直播,那么一场活动怎…...
打地鼠游戏-第14届蓝桥杯STEMA测评Scratch真题精选
[导读]:超平老师的《Scratch蓝桥杯真题解析100讲》已经全部完成,后续会不定期解读蓝桥杯真题,这是Scratch蓝桥杯真题解析第102讲。 蓝桥杯选拔赛现已更名为STEMA,即STEM 能力测试,是蓝桥杯大赛组委会与美国普林斯顿多…...
链表经典刷题--快慢指针与双指针
本篇总结链表解题思路----快慢指针,其实也就是双指针,这个快慢并不单纯指“快慢”,它更多的可以表示,速度快慢,距离长度,时间大小等等,用法很有趣也很独特,理解它的思想,…...
【Java集合框架】篇四:Set接口
1. Set及主要实现类特点 Set:无序、不可重复(去重)、存储value HashSet:底层使用HashMap,即使用 数组单项链表红黑树 结构进行存储。(jkd8中) LinkedHashSet:是HashSet的子类&…...
Python 数据库连接 + 创建库表+ 插入【内含代码实例】
人生苦短 我用python Python其他实用资料:点击此处跳转文末名片获取 数据库连接 连接数据库前,请先确认以下事项: 您已经创建了数据库 TESTDB.在TESTDB数据库中您已经创建了表 EMPLOYEEEMPLOYEE表字段为 FIRST_NAME, LAST_NAME, AGE, SEX 和 INCOME。连…...
如何进行一个网站建设/网络营销中的seo与sem
<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />目前在安防领域一个无可争辩的事实就是:安防监控系统已经从一个模拟的监控系统,过渡到数字化、网络化、智能化监控系统。监控前端的接入方式从模拟介质的视…...
wordpress 换头像/热门推广平台
文章转自:http://other.caixin.com/2013-09-14/100582628.html 文章作者:安替 美国一个跨学科团队今年完成了一项对资源稀缺状况下人的思维方式的研究,结论是:穷人和过于忙碌的人有一个共同思维特质,即注意力被稀缺资源…...
杭州建设职业技术学院招聘信息网站/代运营是什么意思
JVM 中对象咋创建啊,又怎么访问啊 虚拟机遇到 new 指令,会根据指令参数去常量池找对应类的符号引用,如果没找到会进行类加载,此时会执行类构造器指令。类加载完成之后,初始化之前,开始进行对象内存分配&…...
做网站的画布是多少/百度一下就会知道了
只要事务涉及多个表的或者同一个表相同行的更新时,同时运行的事务就可能在同时尝试写入时变为死锁状态。事务会在提交或回滚时一次性解除其所有锁定,而不会逐一放弃锁定。 例如,假设事务T1和T2在大致相同的时间开始: 如果T1开始对…...
淘宝官网页版/seo的基本工作内容
iOS4已经直接支持blocks,很有必要学习一下。 在ios中,将blocks当成对象来处理,它封装了一段代码,这段代码可以在任何时候执行。Blocks可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或返回值。它和传统的…...
学做网站的书籍/百度云资源链接分享群组
时间:2014.04.29 地点:基地二楼 ---------------------------------------------------------------------------------------------- 一、题目 定义字符串的左旋转操作:把字符串前面的若干个字符移动到字符串的尾部。如把字符串abcdef左旋转…...