图形界面开发-framebuffer技术

https://www.linuxidc.com/Linux/2012-05/61024.htm


1、framebuffer 帧缓冲

    帧缓冲(framebuffer)是Linux 系统为显示设备提供的一个接口,它将显示缓冲区抽象,屏蔽图像硬件的底层差异,允许上层应用程序在图形模式下直接对显示缓冲区进行读写操作。用户不必关心物理显示缓冲区的具体位置及存放方式,这些都由帧缓冲设备驱动本身来完成。

    framebuffer机制模仿显卡的功能,将显卡硬件结构抽象为一系列的数据结构,可以通过framebuffer的读写直接对显存进行操作。用户可以将framebuffer看成是显存的一个映像,将其映射到进程空间后,就可以直接进行读写操作,写操作会直接反映在屏幕上。

    framebuffer是个字符设备,主设备号为29,对应于/dev/fb%d 设备文件。

通常,使用如下方式(前面的数字表示次设备号)
  0 = /dev/fb0 第一个fb 设备
  1 = /dev/fb1 第二个fb 设备

    fb 也是一种普通的内存设备,可以读写其内容。例如,屏幕抓屏:cp /dev/fb0 myfilefb 虽然可以像内存设备(/dev/mem)一样,对其read,write,seek 以及mmap。但区别在于fb 使用的不是整个内存区,而是显存部分。

2、fb与应用程序的交互

对于用户程序而言,它和其他的设备并没有什么区别,用户可以把fb看成是一块内存,既可以向内存中写数据,也可以读数据。fb的显示缓冲区位于内核空间,应用程序可以把此空间映射到自己的用户空间,在进行操作。

在应用程序中,操作/dev/fbn的一般步骤如下:
(1)打开/dev/fbn设备文件。
(2)用ioctl()操作取得当前显示屏幕的参数,如屏幕分辨率、每
个像素点的比特数。根据屏幕参数可计算屏幕缓冲区的大小。
(3)用mmap()函数,将屏幕缓冲区映射到用户空间。
(4)映射后就可以直接读/写屏幕缓冲区,进行绘图和图片显示了。

3、fb的结构及其相关结构体

在linux中,fb设备驱动的源码主要在Fb.h (linux2.6.28\include\linux)和Fbmem.c (linux2.6.28\drivers\video)两个文件中,它们是fb设备驱动的中间层,为上层提供系统调用,为底层驱动提供接口。



在fb.h文件中有fb驱动需要使用的很多结构,我们先对这些结构体进行说明:

(1)、

一个帧缓冲区对应一个struct fb_info结构,它包括了帧缓冲设备的属性和操作的完整集合,每个帧设备都有一个fb_info结构体。源码如下:

struct fb_info {
int node;
int flags;
struct mutex lock;/* Lock for open/release/ioctl funcs */互斥锁
struct fb_var_screeninfo var;/* Current var */当前缓冲区的可变参数
struct fb_fix_screeninfo fix;/* Current fix */固定参数
struct fb_monspecs monspecs;/* Current Monitor specs */当前显示器标志
struct work_struct queue;/* Framebuffer event queue */帧缓冲事件队列
struct fb_pixmap pixmap;/* Image hardware mapper */图像硬件mapper
struct fb_pixmap sprite;/* Cursor hardware mapper */光标硬件mapper
struct fb_cmap cmap;/* Current cmap */当前的调色板
struct list_head modelist;      /* mode list */
struct fb_videomode *mode;/* current mode */当前的视频模式


#ifdef CONFIG_FB_BACKLIGHT如果配置了LCD支持背光灯
/* assigned backlight device */
/* set before framebuffer registration, 
  remove after unregister */背光调整
struct backlight_device *bl_dev;


/* Backlight level curve */
struct mutex bl_curve_mutex;
u8 bl_curve[FB_BACKLIGHT_LEVELS];
#endif
#ifdef CONFIG_FB_DEFERRED_IO
struct delayed_work deferred_work;
struct fb_deferred_io *fbdefio;
#endif


struct fb_ops *fbops;帧缓冲操作函数集
struct device *device;/* This is the parent */父设备
struct device *dev;/* This is this fb device */fb设备
int class_flag;                    /* private sysfs flags */私有的sysfs标志
#ifdef CONFIG_FB_TILEBLITTING
struct fb_tile_ops *tileops;    /* Tile Blitting */图块blitting
#endif
char __iomem *screen_base;/* Virtual address */虚拟基地址
unsigned long screen_size;/* Amount of ioremapped VRAM or 0 */ ioremap的虚拟内存大小
void *pseudo_palette;/* Fake palette of 16 colors */ 伪16位调色板
#define FBINFO_STATE_RUNNING 0
#define FBINFO_STATE_SUSPENDED 1
u32 state; /* Hardware state i.e suspend */硬件的状态
void *fbcon_par;                /* fbcon use-only private area */
/* From here on everything is device dependent */
void *par;
};

(2)、

/*
 * Frame buffer operations
 *
 * LOCKING NOTE: those functions must _ALL_ be called with the console
 * semaphore held, this is the only suitable locking mechanism we have
 * in 2.6. Some may be called at interrupt time at this point though.
 */
fb_ops结构体用来实现对帧缓冲设备的操作,这些函数需要驱动开发人员编写,

struct fb_ops {
/* open/release and usage marking */
struct module *owner;

          打开和释放
int (*fb_open)(struct fb_info *info, int user);

int (*fb_release)(struct fb_info *info, int user);

          这两个函数对于非线性布局的/常规内存映射无法工作的帧缓冲设备需要
/* For framebuffers with strange non linear layouts or that do not
* work with normal memory mapped access
*/
ssize_t (*fb_read)(struct fb_info *info, char __user *buf,
  size_t count, loff_t *ppos);
ssize_t (*fb_write)(struct fb_info *info, const char __user *buf,
   size_t count, loff_t *ppos);

           检测可变参数,并调整到支持的值
/* checks var and eventually tweaks it to something supported,
* DO NOT MODIFY PAR */
int (*fb_check_var)(struct fb_var_screeninfo *var, struct fb_info *info);

            设置视频模式
/* set the video mode according to info->var */
int (*fb_set_par)(struct fb_info *info);

           设置color寄存器的值
/* set color register */
int (*fb_setcolreg)(unsigned regno, unsigned red, unsigned green,
   unsigned blue, unsigned transp, struct fb_info *info);

            批量设置color寄存器,设置颜色表
/* set color registers in batch */
int (*fb_setcmap)(struct fb_cmap *cmap, struct fb_info *info);

          显示空白
/* blank display */
int (*fb_blank)(int blank, struct fb_info *info);

          pan显示
/* pan display */
int (*fb_pan_display)(struct fb_var_screeninfo *var, struct fb_info *info);

          填充矩形
/* Draws a rectangle */
void (*fb_fillrect) (struct fb_info *info, const struct fb_fillrect *rect);

            数据复制
/* Copy data from area to another */
void (*fb_copyarea) (struct fb_info *info, const struct fb_copyarea *region);

           图形填充
/* Draws a image to the display */
void (*fb_imageblit) (struct fb_info *info, const struct fb_image *image);

           绘制光标
/* Draws cursor */
int (*fb_cursor) (struct fb_info *info, struct fb_cursor *cursor);

            旋转显示
/* Rotates the display */
void (*fb_rotate)(struct fb_info *info, int angle);

            等待blit空闲
/* wait for blit idle, optional */
int (*fb_sync)(struct fb_info *info);

             fb特定的ioctl操作
/* perform fb specific ioctl (optional) */
int (*fb_ioctl)(struct fb_info *info, unsigned int cmd,
unsigned long arg);

              处理32兼容的ioctl操作
/* Handle 32bit compat ioctl (optional) */
int (*fb_compat_ioctl)(struct fb_info *info, unsigned cmd,
unsigned long arg);

             fb特定的mmap操作
/* perform fb specific mmap */
int (*fb_mmap)(struct fb_info *info, struct vm_area_struct *vma);

           保存目前的硬件状态
/* save current hardware state */
void (*fb_save_state)(struct fb_info *info);

            恢复被保存的硬件状态
/* restore saved state */
void (*fb_restore_state)(struct fb_info *info);

           通过fb_info获得framebuffer的能力
/* get capability given var */
void (*fb_get_caps)(struct fb_info *info, struct fb_blit_caps *caps,
   struct fb_var_screeninfo *var);
};

(3)、

fb_fix_screeninfo结构体中,记录了用户不能修改的固定显示控制器参数。这些固定的参数如缓冲区的物理地址、缓冲区的长度等等。
struct fb_fix_screeninfo {
char id[16]; /* identification string eg "TT Builtin" */

        字符串形式的标识符
unsigned long smem_start;/* Start of frame buffer mem */

/* (physical address) */

        fb缓存的开始位置
__u32 smem_len;/* Length of frame buffer mem */

        fb缓存的长度
__u32 type; /* see FB_TYPE_* */

        FB_TYPE_*类型
__u32 type_aux;/* Interleave for interleaved Planes */

         分界
__u32 visual; /* see FB_VISUAL_* */

       屏幕使用的色彩模式 
__u16 xpanstep;/* zero if no hardware panning  */

        如果没有硬件panning ,赋0
__u16 ypanstep;/* zero if no hardware panning  */

__u16 ywrapstep;/* zero if no hardware ywrap    */

         1行的字节数
__u32 line_length;/* length of a line in bytes    */

         内存映射I/O的开始位置
unsigned long mmio_start;/* Start of Memory Mapped I/O   */
/* (physical address) */

         内存映射I/O的长度
__u32 mmio_len;/* Length of Memory Mapped I/O  */
__u32 accel; /* Indicate to driver which */
/*  specific chip/card we have*/
__u16 reserved[3];/* Reserved for future compatibility */
};

(4)、

fb_var_screeninfo结构体中存储了用户可以修改的显示器控制参数,例如屏幕分辨率、透明度等等。

struct fb_var_screeninfo {
__u32 xres; /* visible resolution */
__u32 yres;

        可见解析度,即分辨率
__u32 xres_virtual;/* virtual resolution */
__u32 yres_virtual;

        虚拟解析度
__u32 xoffset;/* offset from virtual to visible */
__u32 yoffset;/* resolution */

        虚拟到可见之间的偏移
__u32 bits_per_pixel;/* guess what */

        每像素位数,BPP
__u32 grayscale;/* != 0 Graylevels instead of colors */

        非0时指灰度


struct fb_bitfield red;/* bitfield in fb mem if true color, */
struct fb_bitfield green;/* else only length is significant */
struct fb_bitfield blue;

         fb缓存的R\G\B位域
struct fb_bitfield transp;/* transparency */

         透明度

__u32 nonstd; /* != 0 Non standard pixel format */

        != 0 非标准像素格式

__u32 activate;/* see FB_ACTIVATE_* */

       
__u32 height; /* height of picture in mm    */

         屏幕的高度
__u32 width; /* width of picture in mm     */

         屏幕的宽度
__u32 accel_flags;/* (OBSOLETE) see fb_info.flags */
         fb_info的标志

/* Timing: All values in pixclocks, except pixclock (of course) */
__u32 pixclock;/* pixel clock in ps (pico seconds) */

         /* 像素时钟(皮秒) */
__u32 left_margin;/* time from sync to picture */

        行切换:从同步到绘图之间的延迟
__u32 right_margin;/* time from picture to sync */

        行切换:从绘图到同步之间的延迟
__u32 upper_margin;/* time from sync to picture */

        帧切换:从同步到绘图之间的延迟
__u32 lower_margin;

         帧切换:从绘图到同步之间的延迟
__u32 hsync_len;/* length of horizontal sync */

         水平同步的长度
__u32 vsync_len;/* length of vertical sync */

         垂直同步的长度
__u32 sync; /* see FB_SYNC_* */
__u32 vmode; /* see FB_VMODE_* */
__u32 rotate; /* angle we rotate counter clockwise */

        顺时钟旋转的角度
__u32 reserved[5];/* Reserved for future compatibility */
};

(5)、

fb_cmap结构体中记录了颜色板信息,即调色板信息。,用户空间可以通过ioctl()的FBIOGETCMAP和 FBIOPUTCMAP命令读取或设定颜色表。

struct fb_cmap {
__u32 start; /* First entry */第一个元素的入口
__u32 len; /* Number of entries */元素个数
__u16 *red; /* Red values */红色、绿色、蓝色
__u16 *green;  
__u16 *blue;
__u16 *transp;/* transparency, can be NULL */透明度
};


上面这些结构体之间有什么关系呢?看下图:



(6)、

fb_bitfield 结构体描述每一像素显示缓冲区的组织方式,包含位域偏移、位域长度和MSB 指示,

struct fb_bitfield {
__u32 offset; /* beginning of bitfield */

         位域偏移
__u32 length; /* length of bitfield */

        位域长度
__u32 msb_right;/* != 0 : Most significant bit is */ 
/* right */

        MSB
};







Fbmem.c文件


这一篇来说下linux帧缓冲设备驱动的上层建筑Fbmem.c文件。

1、先上第一道菜:


1.1、那我们现在来说Fbmem.c (linux2.6.28\drivers\video)文件中的应用程序访问帧缓冲设备的接口,大家对下面这些应该都不陌生吧。:

/**
 * fbmem_init - init frame buffer subsystem
 *
 * Initialize the frame buffer subsystem.
 *
 * NOTE: This function is _only_ to be called by drivers/char/mem.c.
 *
 */
static int __init
fbmem_init(void)
{
proc_create("fb", 0, NULL, &fb_proc_fops);看名字就知道与proc文件系统有关,其中fb_proc_fops是个file_operations的结构体,在同一个文件中定义。

static const struct file_operations fb_proc_fops = {
.owner = THIS_MODULE,
.open = proc_fb_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
};

对应的 open函数实例proc_fb_open源码如下:

static int proc_fb_open(struct inode *inode, struct file *file)
{
return seq_open(file, &proc_fb_seq_ops);
}

同样proc_fb_seq_ops是seq_operations类型的结构体实例。如下所示:

static const struct seq_operations proc_fb_seq_ops = {
.start = fb_seq_start,
.next = fb_seq_next,
.stop = fb_seq_stop,
.show = fb_seq_show,
};

这些函数都在这个文件中被定义,现在想想fbmem.c文件已经被我们去掉很多东西了。


if (register_chrdev(FB_MAJOR,"fb",&fb_fops))这个函数就太常见了,字符设备一出现,就肯定会出现,不过以前我们有时看到的是分开的那三个函数,现在把它们和在一起了。

其中fb_fops是file_operations结构体的实例,如下所示:

static const struct file_operations fb_fops = {
.owner = THIS_MODULE,
.read = fb_read,
.write = fb_write,
.unlocked_ioctl = fb_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = fb_compat_ioctl,
#endif
.mmap = fb_mmap,
.open = fb_open,
.release = fb_release,
#ifdef HAVE_ARCH_FB_UNMAPPED_AREA
.get_unmapped_area = get_fb_unmapped_area,
#endif
#ifdef CONFIG_FB_DEFERRED_IO
.fsync = fb_deferred_io_fsync,
#endif
};
printk("unable to get major %d for fb devs\n", FB_MAJOR);

fb_class = class_create(THIS_MODULE, "graphics");创建一个类
if (IS_ERR(fb_class)) {
printk(KERN_WARNING "Unable to create fb class; errno = %ld\n", PTR_ERR(fb_class));
fb_class = NULL;
}
return 0;
}

module_init(fbmem_init);
static void __exit
fbmem_exit(void)  做和init函数相反的事。
{
remove_proc_entry("fb", NULL);
class_destroy(fb_class);
unregister_chrdev(FB_MAJOR, "fb");
}

module_exit(fbmem_exit);

2、在Fbmem.c (linux2.6.28\drivers\video)文件中还有很多函数是关于LOGO显示的,这个我们也不用关心,所以其实在这个文件中我们主要关心的就是struct file_operations fb_fops这个结构体中的函数。

2.1、简要分析几个struct file_operations fb_fops结构体中的函数:

先来看fb_read函数,源码如下:

static ssize_t
fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
unsigned long p = *ppos;
struct inode *inode = file->f_path.dentry->d_inode;
int fbidx = iminor(inode);这个函数看下面的源码,应该知道它的作用了:

static inline unsigned iminor(const struct inode *inode)
{
return MINOR(inode->i_rdev);
}
struct fb_info *info = registered_fb[fbidx];这个全局的结构数组,我们以前说过
u32 *buffer, *dst;
u32 __iomem *src;
int c, i, cnt = 0, err = 0;
unsigned long total_size;


if (!info || ! info->screen_base)
return -ENODEV;


if (info->state != FBINFO_STATE_RUNNING)
return -EPERM;


if (info->fbops->fb_read) 如果定义了fb_read函数,就调用具体的read函数,也就是我们在前面说过的  

     fb_ops s3cfb_ops结构体中定义的函数。
return info->fbops->fb_read(info, buf, count, ppos);

struct fb_ops s3cfb_ops = {

.owner= THIS_MODULE,
.fb_check_var = s3cfb_check_var,
.fb_set_par = s3cfb_set_par,
.fb_blank = s3cfb_blank,
.fb_pan_display= s3cfb_pan_display,
.fb_setcolreg = s3cfb_setcolreg,
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
.fb_cursor = soft_cursor,
.fb_ioctl = s3cfb_ioctl,
};
total_size = info->screen_size;


if (total_size == 0)
total_size = info->fix.smem_len;


if (p >= total_size)
return 0;


if (count >= total_size)
count = total_size;


if (count + p > total_size)
count = total_size - p;


buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count,
GFP_KERNEL);
if (!buffer)
return -ENOMEM;


src = (u32 __iomem *) (info->screen_base + p);


if (info->fbops->fb_sync)
info->fbops->fb_sync(info);


while (count) {
c  = (count > PAGE_SIZE) ? PAGE_SIZE : count;
dst = buffer;
for (i = c >> 2; i--; )
*dst++ = fb_readl(src++);
if (c & 3) {
u8 *dst8 = (u8 *) dst;
u8 __iomem *src8 = (u8 __iomem *) src;


for (i = c & 3; i--;)
*dst8++ = fb_readb(src8++);


src = (u32 __iomem *) src8;
}


if (copy_to_user(buf, buffer, c)) {
err = -EFAULT;
break;
}
*ppos += c;
buf += c;
cnt += c;
count -= c;
}


kfree(buffer);


return (err) ? err : cnt;
}

2.2、fb_ioctl函数:源码如下:

static long fb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
__acquires(&info->lock)
__releases(&info->lock)
{
struct inode *inode = file->f_path.dentry->d_inode;
int fbidx = iminor(inode);
struct fb_info *info;
long ret;


info = registered_fb[fbidx];
mutex_lock(&info->lock);
ret = do_fb_ioctl(info, cmd, arg);

此函数源码如下:

static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
unsigned long arg)
{
struct fb_ops *fb;
struct fb_var_screeninfo var;
struct fb_fix_screeninfo fix;
struct fb_con2fbmap con2fb;
struct fb_cmap_user cmap;
struct fb_event event;
void __user *argp = (void __user *)arg;
long ret = 0;


fb = info->fbops;
if (!fb)
return -ENODEV;


switch (cmd) {
case FBIOGET_VSCREENINFO:  获得可变的屏幕参数
ret = copy_to_user(argp, &info->var,
   sizeof(var)) ? -EFAULT : 0;
break;
case FBIOPUT_VSCREENINFO:设置可变的屏幕参数
if (copy_from_user(&var, argp, sizeof(var))) {
ret =  -EFAULT;
break;
}
acquire_console_sem();
info->flags |= FBINFO_MISC_USEREVENT;
ret = fb_set_var(info, &var);
info->flags &= ~FBINFO_MISC_USEREVENT;
release_console_sem();
if (ret == 0 && copy_to_user(argp, &var, sizeof(var)))
ret = -EFAULT;
break;
case FBIOGET_FSCREENINFO:获得固定的屏幕参数设置
ret = copy_to_user(argp, &info->fix,
   sizeof(fix)) ? -EFAULT : 0;
break;
case FBIOPUTCMAP:设置颜色表
if (copy_from_user(&cmap, argp, sizeof(cmap)))
ret = -EFAULT;
else
ret = fb_set_user_cmap(&cmap, info);
break;
case FBIOGETCMAP: 获得颜色表
if (copy_from_user(&cmap, argp, sizeof(cmap)))
ret = -EFAULT;
else
ret = fb_cmap_to_user(&info->cmap, &cmap);
break;
case FBIOPAN_DISPLAY:
if (copy_from_user(&var, argp, sizeof(var))) {
ret = -EFAULT;
break;
}
acquire_console_sem();
ret = fb_pan_display(info, &var);
release_console_sem();
if (ret == 0 && copy_to_user(argp, &var, sizeof(var)))
ret = -EFAULT;
break;
case FBIO_CURSOR:
ret = -EINVAL;
break;
case FBIOGET_CON2FBMAP:
if (copy_from_user(&con2fb, argp, sizeof(con2fb)))
ret = -EFAULT;
else if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES)
ret = -EINVAL;
else {
con2fb.framebuffer = -1;
event.info = info;
event.data = &con2fb;
fb_notifier_call_chain(FB_EVENT_GET_CONSOLE_MAP,
&event);
ret = copy_to_user(argp, &con2fb,
   sizeof(con2fb)) ? -EFAULT : 0;
}
break;
case FBIOPUT_CON2FBMAP:
if (copy_from_user(&con2fb, argp, sizeof(con2fb))) {
ret = -EFAULT;
break;
}
if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES) {
ret = -EINVAL;
break;
}
if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX) {
ret = -EINVAL;
break;
}
if (!registered_fb[con2fb.framebuffer])
request_module("fb%d", con2fb.framebuffer);
if (!registered_fb[con2fb.framebuffer]) {
ret = -EINVAL;
break;
}
event.info = info;
event.data = &con2fb;
ret = fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP,
     &event);
break;
case FBIOBLANK:
acquire_console_sem();
info->flags |= FBINFO_MISC_USEREVENT;
ret = fb_blank(info, arg);
info->flags &= ~FBINFO_MISC_USEREVENT;
release_console_sem();
break;;
default:
if (fb->fb_ioctl == NULL)
ret = -ENOTTY;
else
ret = fb->fb_ioctl(info, cmd, arg);
}
return ret;
}
mutex_unlock(&info->lock);
return ret;
}

fb_mem.c文件分析到这里差不多也结束了,当然,我们还有很多没分析,只是分析了一小部分,但是这个文件的大致结构和作用我们应该清楚了。

在这个文件中其他重要的函数,我们都没有分析,如:fb_mmap、register_framebuffer、unregister_framebuffer函数等等,后面这两个函数,我们前面有涉及,所以,要走的路还有很长。





本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/493989.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SPU赋能PSI:探秘隐私集合求交核心技术与高级调度架构实践

1.SPU实现的PSI介绍 1.PSI的定义和种类 隐私集合求交&#xff08;Private Set Intersection, PSI&#xff09;是一种在密码学和安全多方计算&#xff08;MPC&#xff09;领域中的关键技术&#xff0c;允许两个或多个参与者在不泄露各自输入集合中非交集部分的前提下&#xff…

基于单片机防丢失设备的设计和实践

摘要:防止老人或者小孩走丢走失,还可以放在汽车里,利用GPS系统,设计实现了基于单片机的防丢失设备。设备利用液晶显示屏显示信息,并实时发送位置短信到手机传输当前位置的纬度和经度坐标,实现了定位与监测功能。测试结果表明,利用该设备和手机可以同时观察老人或小孩携带…

Manacher算法学习笔记(洛谷题单 Part 5.3 Manacher)

0.随便说说 字符串学的太差了&#xff0c;每次字符串算法都是学完了就忘&#xff0c;正好上场 c f d i v 1 B cfdiv1B cfdiv1B考了一个 M a n a c h e r Manacher Manacher&#xff0c;就先复习它了。 1.一些概念 子串 ( s u b s t r i n g ) (substring) (substring)&#…

【Java程序设计】【C00381】基于(JavaWeb)Springboot的爱心商城管理系统(有论文)

【C00381】基于&#xff08;JavaWeb&#xff09;Springboot的爱心商城管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 博主介绍&#xff1a;java高级开发&#xff0c;从事互联网行业六年&#xff0c;已经做了六年的毕业设计程序开发&#x…

外包干了4年,技术退步明显。。。。

说一下自己的情况&#xff0c;本科生&#xff0c;19年通过校招进入上海某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试&a…

Python环境下一种新的类谱峭度算法的旋转机械故障诊断模型

谱峭度SK的本质是计算每根谱线峭度值的高阶统计量&#xff0c;谱峭度对信号中的瞬态冲击成分十分敏感&#xff0c;能有效的从含有背景噪声信号中识别瞬态冲击及其在频带中的分布。由于谱峭度的复杂性、缺少一个正式的定义和一个容易理解的计算过程使其在很长时间内都未能引入到…

Netty教程之NIO基础

NIO 介绍 NIO 全称java non-blocking IO&#xff08;非阻塞 I/O&#xff09;&#xff0c;后续提供了一系列改进的输入/输出的新特性&#xff0c;被统称为 NIO(即 New IO)&#xff0c;是同步非阻塞的。 阻塞和非阻塞是进程在访问数据的时候&#xff0c;数据是否准备就绪的一种…

光伏百科|分布式光伏电站如何开展运维管理工作?

随着经济的不断发展和生活水平的日益提高&#xff0c;节能环保已经成为全社会的责任和共识&#xff0c;分布式光伏电站作为清洁能源走进了千家万户。然而&#xff0c;在分布式光伏电站运行期间&#xff0c;面临监管困难、系统繁多、火灾隐患和运维不当等困难&#xff0c;该如何…

2024年【G2电站锅炉司炉】考试及G2电站锅炉司炉找解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 G2电站锅炉司炉考试考前必练&#xff01;安全生产模拟考试一点通每个月更新G2电站锅炉司炉找解析题目及答案&#xff01;多做几遍&#xff0c;其实通过G2电站锅炉司炉复审模拟考试很简单。 1、【多选题】下列为锅炉的…

Python爬虫之爬取网页图片

当我们想要下载网页的图片时&#xff0c;发现网页的图片太多了&#xff0c;无从下手&#xff0c;那我们写一个脚本来爬取呗。 这次的脚本是专门针对某个外国网站使用的&#xff0c;因此仅供参考思路。 在测试的过程中&#xff0c;我发现网站使用了发爬虫机制&#xff0c;具体就…

蓝桥杯-网络安全比赛(2)基础学习-正则表达式匹配电话号码、HTTP网址、IP地址、密码校验

正则表达式&#xff08;Regular Expression&#xff09;&#xff1a;定义&#xff1a;一种强大的文本处理工具&#xff0c;用于描述、匹配和查找字符串中的特定模式。应用&#xff1a;密码验证、文本搜索和替换、数据清洗等。特点&#xff1a;通过特定的元字符和规则来构建复杂…

vcf文件可以用excel打开吗?四种解决方案

vcf文件可以用excel打开吗&#xff1f; 当然可以。 一、VCF文件简介 VCF&#xff08;vCard&#xff09;文件是一种用于存储联系人信息的文件格式。它通常包含姓名、电话号码、电子邮件地址、地址等详细信息。VCF文件在多种设备和操作系统中广泛使用&#xff0c;特别是在电子邮…

2024年【G3锅炉水处理】考试题及G3锅炉水处理考试报名

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 G3锅炉水处理考试题参考答案及G3锅炉水处理考试试题解析是安全生产模拟考试一点通题库老师及G3锅炉水处理操作证已考过的学员汇总&#xff0c;相对有效帮助G3锅炉水处理考试报名学员顺利通过考试。 1、【多选题】锅筒…

【八股】2024春招八股复习笔记2(大数据开发,Java)

【八股】2024春招八股复习笔记2&#xff08;大数据开发&#xff09; 文章目录 1、大数据存储&#xff08;Flume、Hive、HBase、HDFS&#xff09;2、大数据计算&#xff08;MapReduce&#xff0c;Spark、Flink&#xff09;3、大数据集群&#xff08;Yarn、ZooKeeper、kafka&…

部署云原生边缘计算平台kubeedge

文章目录 1、kubeedge架构2、基础服务提供 负载均衡器 metallb2.1、开启ipvc模式中的strictARP2.2、部署metalb2.2.1、创建IP地址池2.2.2、开启二层转发&#xff0c;实现在k8s集群节点外访问2.2.3、测试 3、部署cloudcore3.1、部署cloudcore3.2、修改cloudcore的网络类型 4、部…

二叉树|450.删除二叉搜索树中的节点

力扣题目链接 class Solution { public:TreeNode* deleteNode(TreeNode* root, int key) {if (root nullptr) return root; // 第一种情况&#xff1a;没找到删除的节点&#xff0c;遍历到空节点直接返回了if (root->val key) {// 第二种情况&#xff1a;左右孩子都为空&…

2024年第六届机器人系统与自动化工程国际会议(RSAE 2024)即将召开!

2024年第六届机器人系统与自动化工程国际会议&#xff08;RSAE 2024&#xff09;将于2024年6月21-23日在日本东京召开。RSAE 2024 的主要目标是加强合作&#xff0c;并为院士、专业人士和研究人员提供一个论坛&#xff0c;交流他们的研究成果、创新理念和解决方案&#xff0c;包…

【网络】:数据链路层

数据链路层 一.以太网帧格式二.认识MTU三.ARP协议1.ARP协议的工作流程2.ARP数据报的格式3.ARP欺骗 四.其他重要协议或技术1.DNS2.ICMP协议3.NAT技术&#xff08;重点&#xff09;4.代理服务器 五.一些问题 认识以太网 “以太网” 不是一种具体的网络, 而是一种技术标准; 既包含…

dump文件分析OOM及线程堆栈

OutOfMemoryError (OOM) 如果项目报错&#xff1a; OutOfMemoryError: Java heap space&#xff0c;说明堆内存空间&#xff08;Heap Space&#xff09;中没有足够的空间来分配对象了。 一旦发生 OOM&#xff0c;系统有可能不可用&#xff0c;或者频繁重启。属于非常严重的问题…

聊聊CSS

css 的介绍 学习目标 能够知道css的作用 1. css 的定义 css(Cascading Style Sheet)层叠样式表&#xff0c;它是用来美化页面的一种语言。 没有使用css的效果图 使用css的效果图 2. css 的作用 美化界面, 比如: 设置标签文字大小、颜色、字体加粗等样式。 控制页面布局, 比如…