当前位置: 首页 > news >正文

Linux内核4.14版本——drm框架分析(4)——crtc分析

目录

1. struct drm_crtc结构体

2. crtc相关的API

2.1 drm_crtc_init_with_planes

2.5 drm_mode_setcrtc

3. func的一些介绍

3.1 struct drm_crtc_helper_funcs

3.2 struct drm_crtc_funcs

4. 应用层的调用

4.1 drmModeSetCrtc (drmlib库里)---> drm_mode_setcrtc


       本文主要分析一下crtc相关的内容。

1. struct drm_crtc结构体


/*** struct drm_crtc - central CRTC control structure* @dev: parent DRM device* @port: OF node used by drm_of_find_possible_crtcs()* @head: list management* @name: human readable name, can be overwritten by the driver* @mutex: per-CRTC locking* @base: base KMS object for ID tracking etc.* @primary: primary plane for this CRTC* @cursor: cursor plane for this CRTC* @cursor_x: current x position of the cursor, used for universal cursor planes* @cursor_y: current y position of the cursor, used for universal cursor planes* @enabled: is this CRTC enabled?* @mode: current mode timings* @hwmode: mode timings as programmed to hw regs* @x: x position on screen* @y: y position on screen* @funcs: CRTC control functions* @gamma_size: size of gamma ramp* @gamma_store: gamma ramp values* @helper_private: mid-layer private data* @properties: property tracking for this CRTC** Each CRTC may have one or more connectors associated with it.  This structure* allows the CRTC to be controlled.*/
struct drm_crtc {struct drm_device *dev;struct device_node *port;struct list_head head;char *name;/*** @mutex:** This provides a read lock for the overall CRTC state (mode, dpms* state, ...) and a write lock for everything which can be update* without a full modeset (fb, cursor data, CRTC properties ...). A full* modeset also need to grab &drm_mode_config.connection_mutex.** For atomic drivers specifically this protects @state.*/struct drm_modeset_lock mutex;struct drm_mode_object base;/* primary and cursor planes for CRTC */struct drm_plane *primary;struct drm_plane *cursor;/*** @index: Position inside the mode_config.list, can be used as an array* index. It is invariant over the lifetime of the CRTC.*/unsigned index;/* position of cursor plane on crtc */int cursor_x;int cursor_y;bool enabled;/* Requested mode from modesetting. */struct drm_display_mode mode;/* Programmed mode in hw, after adjustments for encoders,* crtc, panel scaling etc. Needed for timestamping etc.*/struct drm_display_mode hwmode;int x, y;const struct drm_crtc_funcs *funcs;/* Legacy FB CRTC gamma size for reporting to userspace */uint32_t gamma_size;uint16_t *gamma_store;/* if you are using the helper */const struct drm_crtc_helper_funcs *helper_private;struct drm_object_properties properties;/*** @state:** Current atomic state for this CRTC.** This is protected by @mutex. Note that nonblocking atomic commits* access the current CRTC state without taking locks. Either by going* through the &struct drm_atomic_state pointers, see* for_each_crtc_in_state(), for_each_oldnew_crtc_in_state(),* for_each_old_crtc_in_state() and for_each_new_crtc_in_state(). Or* through careful ordering of atomic commit operations as implemented* in the atomic helpers, see &struct drm_crtc_commit.*/struct drm_crtc_state *state;/*** @commit_list:** List of &drm_crtc_commit structures tracking pending commits.* Protected by @commit_lock. This list doesn't hold its own full* reference, but burrows it from the ongoing commit. Commit entries* must be removed from this list once the commit is fully completed,* but before it's correspoding &drm_atomic_state gets destroyed.*/struct list_head commit_list;/*** @commit_lock:** Spinlock to protect @commit_list.*/spinlock_t commit_lock;#ifdef CONFIG_DEBUG_FS/*** @debugfs_entry:** Debugfs directory for this CRTC.*/struct dentry *debugfs_entry;
#endif/*** @crc:** Configuration settings of CRC capture.*/struct drm_crtc_crc crc;/*** @fence_context:** timeline context used for fence operations.*/unsigned int fence_context;/*** @fence_lock:** spinlock to protect the fences in the fence_context.*/spinlock_t fence_lock;/*** @fence_seqno:** Seqno variable used as monotonic counter for the fences* created on the CRTC's timeline.*/unsigned long fence_seqno;/*** @timeline_name:** The name of the CRTC's fence timeline.*/char timeline_name[32];
};

2. crtc相关的API

2.1 drm_crtc_init_with_planes


/*** drm_crtc_init_with_planes - Initialise a new CRTC object with*    specified primary and cursor planes.* @dev: DRM device* @crtc: CRTC object to init* @primary: Primary plane for CRTC* @cursor: Cursor plane for CRTC* @funcs: callbacks for the new CRTC* @name: printf style format string for the CRTC name, or NULL for default name** Inits a new object created as base part of a driver crtc object. Drivers* should use this function instead of drm_crtc_init(), which is only provided* for backwards compatibility with drivers which do not yet support universal* planes). For really simple hardware which has only 1 plane look at* drm_simple_display_pipe_init() instead.** Returns:* Zero on success, error code on failure.*/
int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,struct drm_plane *primary,struct drm_plane *cursor,const struct drm_crtc_funcs *funcs,const char *name, ...)
{struct drm_mode_config *config = &dev->mode_config;int ret;WARN_ON(primary && primary->type != DRM_PLANE_TYPE_PRIMARY);WARN_ON(cursor && cursor->type != DRM_PLANE_TYPE_CURSOR);crtc->dev = dev;crtc->funcs = funcs;INIT_LIST_HEAD(&crtc->commit_list);spin_lock_init(&crtc->commit_lock);drm_modeset_lock_init(&crtc->mutex);ret = drm_mode_object_add(dev, &crtc->base, DRM_MODE_OBJECT_CRTC);   // (1)if (ret)return ret;if (name) {                                          // (2)va_list ap;va_start(ap, name);crtc->name = kvasprintf(GFP_KERNEL, name, ap);va_end(ap);} else {crtc->name = kasprintf(GFP_KERNEL, "crtc-%d",drm_num_crtcs(dev));}if (!crtc->name) {drm_mode_object_unregister(dev, &crtc->base);return -ENOMEM;}crtc->fence_context = dma_fence_context_alloc(1);     // (3)spin_lock_init(&crtc->fence_lock);snprintf(crtc->timeline_name, sizeof(crtc->timeline_name),"CRTC:%d-%s", crtc->base.id, crtc->name);crtc->base.properties = &crtc->properties;           // (4)list_add_tail(&crtc->head, &config->crtc_list);crtc->index = config->num_crtc++;crtc->primary = primary;                             // (5) crtc->cursor = cursor;if (primary && !primary->possible_crtcs)primary->possible_crtcs = 1 << drm_crtc_index(crtc);if (cursor && !cursor->possible_crtcs)cursor->possible_crtcs = 1 << drm_crtc_index(crtc);ret = drm_crtc_crc_init(crtc);                      // (6)if (ret) {drm_mode_object_unregister(dev, &crtc->base);return ret;}if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {     // (7)drm_object_attach_property(&crtc->base, config->prop_active, 0);drm_object_attach_property(&crtc->base, config->prop_mode_id, 0);drm_object_attach_property(&crtc->base,config->prop_out_fence_ptr, 0);}return 0;
}

        (1)创建一个类型为DRM_MODE_OBJECT_CRTC的struct drm_mode_object结构体。

        (2)为创建的crtc赋名字。

        (3)暂不知道。

        (4)初始化properties

        (5)初始化primary plane、cursor plane。

        (6)drm_crtc_crc_init是一些调试方面的。

        (7)attach一些properties变量。

2.5 drm_mode_setcrtc

int drm_mode_setcrtc(struct drm_device *dev, void *data,struct drm_file *file_priv)
{struct drm_mode_config *config = &dev->mode_config;struct drm_mode_crtc *crtc_req = data;struct drm_crtc *crtc;struct drm_connector **connector_set = NULL, *connector;struct drm_framebuffer *fb = NULL;struct drm_display_mode *mode = NULL;struct drm_mode_set set;uint32_t __user *set_connectors_ptr;struct drm_modeset_acquire_ctx ctx;int ret;int i;if (!drm_core_check_feature(dev, DRIVER_MODESET))return -EINVAL;/** Universal plane src offsets are only 16.16, prevent havoc for* drivers using universal plane code internally.*/if (crtc_req->x & 0xffff0000 || crtc_req->y & 0xffff0000)return -ERANGE;crtc = drm_crtc_find(dev, crtc_req->crtc_id);             // (1)if (!crtc) {DRM_DEBUG_KMS("Unknown CRTC ID %d\n", crtc_req->crtc_id);return -ENOENT;}DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name);mutex_lock(&crtc->dev->mode_config.mutex);drm_modeset_acquire_init(&ctx, 0);                       // (2)
retry:ret = drm_modeset_lock_all_ctx(crtc->dev, &ctx);         // (3)if (ret)goto out;if (crtc_req->mode_valid) {                              /* If we have a mode we need a framebuffer. *//* If we pass -1, set the mode with the currently bound fb */if (crtc_req->fb_id == -1) {                         // (4)           if (!crtc->primary->fb) {DRM_DEBUG_KMS("CRTC doesn't have current FB\n");ret = -EINVAL;goto out;}fb = crtc->primary->fb;/* Make refcounting symmetric with the lookup path. */drm_framebuffer_get(fb);} else {fb = drm_framebuffer_lookup(dev, crtc_req->fb_id);if (!fb) {DRM_DEBUG_KMS("Unknown FB ID%d\n",crtc_req->fb_id);ret = -ENOENT;goto out;}}mode = drm_mode_create(dev);                       // (5)if (!mode) {ret = -ENOMEM;goto out;}ret = drm_mode_convert_umode(mode, &crtc_req->mode);   // (6)if (ret) {DRM_DEBUG_KMS("Invalid mode\n");goto out;}/** Check whether the primary plane supports the fb pixel format.* Drivers not implementing the universal planes API use a* default formats list provided by the DRM core which doesn't* match real hardware capabilities. Skip the check in that* case.*/if (!crtc->primary->format_default) {                  // (7)ret = drm_plane_check_pixel_format(crtc->primary,fb->format->format);if (ret) {struct drm_format_name_buf format_name;DRM_DEBUG_KMS("Invalid pixel format %s\n",drm_get_format_name(fb->format->format,&format_name));goto out;}}ret = drm_crtc_check_viewport(crtc, crtc_req->x, crtc_req->y,mode, fb);                           // (8)if (ret)goto out;}if (crtc_req->count_connectors == 0 && mode) {DRM_DEBUG_KMS("Count connectors is 0 but mode set\n");ret = -EINVAL;goto out;}if (crtc_req->count_connectors > 0 && (!mode || !fb)) {DRM_DEBUG_KMS("Count connectors is %d but no mode or fb set\n",crtc_req->count_connectors);ret = -EINVAL;goto out;}if (crtc_req->count_connectors > 0) {               u32 out_id;/* Avoid unbounded kernel memory allocation */if (crtc_req->count_connectors > config->num_connector) {ret = -EINVAL;goto out;}connector_set = kmalloc_array(crtc_req->count_connectors,sizeof(struct drm_connector *),GFP_KERNEL);if (!connector_set) {ret = -ENOMEM;goto out;}for (i = 0; i < crtc_req->count_connectors; i++) {        // (9)connector_set[i] = NULL;set_connectors_ptr = (uint32_t __user *)(unsigned long)crtc_req->set_connectors_ptr;if (get_user(out_id, &set_connectors_ptr[i])) {ret = -EFAULT;goto out;}connector = drm_connector_lookup(dev, out_id);         // (10)if (!connector) {DRM_DEBUG_KMS("Connector id %d unknown\n",out_id);ret = -ENOENT;goto out;}DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",connector->base.id,connector->name);connector_set[i] = connector;}}set.crtc = crtc;set.x = crtc_req->x;set.y = crtc_req->y;set.mode = mode;set.connectors = connector_set;set.num_connectors = crtc_req->count_connectors;set.fb = fb;ret = __drm_mode_set_config_internal(&set, &ctx);            // (11)out:if (fb)drm_framebuffer_put(fb);                                 // (12)if (connector_set) {for (i = 0; i < crtc_req->count_connectors; i++) {if (connector_set[i])drm_connector_put(connector_set[i]);             // (13)}}kfree(connector_set);drm_mode_destroy(dev, mode);if (ret == -EDEADLK) {drm_modeset_backoff(&ctx);goto retry;}drm_modeset_drop_locks(&ctx);drm_modeset_acquire_fini(&ctx);mutex_unlock(&crtc->dev->mode_config.mutex);return ret;
}

        (1)找到需要的crtc实体。

        (2)初始化一个ctrc的需求内容结构体。

        (3)connection、crtc、plane等锁上锁。 

        (4)得到或者生成primary plane的framebuffer。

        (5~6)创建一个struct drm_display_mode结构体,并把应用层传递下来的参数赋值给给结构体。

        (7)检查primary plane支持的pixel format。

        (8)检查一下framebuffer是否足够大,能否满足crtc viewport.

        (9~10)找到crtc绑定链接的connetcor。

        (11)设置struct drm_mode_set结构体。

3. func的一些介绍

3.1 struct drm_crtc_helper_funcs

 
//struct drm_crtc_helper_funcs - helper operations for CRTCs
struct drm_crtc_helper_funcs {//电源管理接口,一般由drm_helper_connector_dpms调用void (*dpms)(struct drm_crtc *crtc, int mode);/*为modeset做准备,一般就是调用dpms接口关闭crtc(DRM_MODE_DPMS_OFF),    *drm_crtc_heler_set_mode接口会调用*atomic接口使用atomic_disable替代*/void (*prepare)(struct drm_crtc *crtc);/* 和prepare接口对应,是在modeset完成后,调用该接口来enable crtc* 一般就是调用dmps接口( DRM_MODE_DPMS_ON)* atomic 操作是用atomic_enable替代*/void (*commit)(struct drm_crtc *crtc);/*检查显示mode的有效性,  drm_helper_probe_single_connector_modes()和* drm_atomic_helper_check_modeset()会调用到, 该接口仅作初步检查* 更详细的检查有@mode_fixup or @atomic_check*/enum drm_mode_status (*mode_valid)(struct drm_crtc *crtc,const struct drm_display_mode *mode);/*验证并修正mode, 由drm_atomic_helper_check_modeset()调用*/bool (*mode_fixup)(struct drm_crtc *crtc,const struct drm_display_mode *mode,struct drm_display_mode *adjusted_mode);//设置display mode ,crtc_set_mode会调用该接口int (*mode_set)(struct drm_crtc *crtc, struct drm_display_mode *mode,struct drm_display_mode *adjusted_mode, int x, int y,struct drm_framebuffer *old_fb);/*更新crtc的display mode, 但不会修改其primary plane配置,* 注意调用该接口的时候, display pipe应该是完全off的*/void (*mode_set_nofb)(struct drm_crtc *crtc);//设置fb 和 显示位置, drm_crtc_helper_set_config()会调用该接口int (*mode_set_base)(struct drm_crtc *crtc, int x, int y,struct drm_framebuffer *old_fb);int (*mode_set_base_atomic)(struct drm_crtc *crtc,struct drm_framebuffer *fb, int x, int y,enum mode_set_atomic);//关闭crtcvoid (*disable)(struct drm_crtc *crtc);/*检查待更新的drm_crtc_state, * drm_atomic_helper_check() -->  drm_atomic_helper_check_planes()会调用*/int (*atomic_check)(struct drm_crtc *crtc,struct drm_atomic_state *state);//多plane的atomic update之前需要调用该接口(drm_atomic_helper_commit_planes中调用)void (*atomic_begin)(struct drm_crtc *crtc,struct drm_atomic_state *state);/*多plane的atomic update之后需要调用该接口(drm_atomic_helper_commit_planes中调用)* atomic_begin/atomic_flush具体的作用好像也不是太清晰,应该就是为driver提供在更新* planes的前后能做一些额外操作吧?*/void (*atomic_flush)(struct drm_crtc *crtc,struct drm_atomic_state *state);//atomic encable crtcvoid (*atomic_enable)(struct drm_crtc *crtc,struct drm_atomic_state *state);atomic disable crtcvoid (*atomic_disable)(struct drm_crtc *crtc,struct drm_atomic_state *state);//获取扫描信息,由drm_crtc_vblank_helper_get_vblank_timestamp()调用bool (*get_scanout_position)(struct drm_crtc *crtc,bool in_vblank_irq, int *vpos, int *hpos,ktime_t *stime, ktime_t *etime,const struct drm_display_mode *mode);
};

3.2 struct drm_crtc_funcs

 
//crtc控制接口,一般填写helper函数
struct drm_crtc_funcs {/*重置软硬件state, 由drm_mode_config_reset()调用,一般赋值为        drm_atomic_helper_crtc_reset()接口*/void (*reset)(struct drm_crtc *crtc);/*设置鼠标图片, width/height应该是鼠标图片的宽高, handle是鼠标图片buf(drm_gem_obj)对        应的handle, 该接口最新版本已经被废弃,使用鼠标层代替*/int (*cursor_set)(struct drm_crtc *crtc, struct drm_file *file_priv,uint32_t handle, uint32_t width, uint32_t height);/*同上,设置鼠标图片,不过这个接口多了hot_x, hot_y坐标*/int (*cursor_set2)(struct drm_crtc *crtc, struct drm_file *file_priv,uint32_t handle, uint32_t width, uint32_t height,int32_t hot_x, int32_t hot_y);/*鼠标移动操作*/int (*cursor_move)(struct drm_crtc *crtc, int x, int y);//gamma设置int (*gamma_set)(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,uint32_t size,struct drm_modeset_acquire_ctx *ctx);//drm_mode_config_cleanup 调用到该接口void (*destroy)(struct drm_crtc *crtc);/* 设置crtc的fb/ connector/ mode的属性,对应用户态drmModeSetCrtc接口* atomic modeset操作,使用drm_atomic_helper_set_config接口赋值*/int (*set_config)(struct drm_mode_set *set,struct drm_modeset_acquire_ctx *ctx);//page翻转接口,vsync同步的int (*page_flip)(struct drm_crtc *crtc,struct drm_framebuffer *fb,struct drm_pending_vblank_event *event,uint32_t flags,struct drm_modeset_acquire_ctx *ctx);//和page_flip类似,但该接口会等待特定的vbankint (*page_flip_target)(struct drm_crtc *crtc,struct drm_framebuffer *fb,struct drm_pending_vblank_event *event,uint32_t flags, uint32_t target,struct drm_modeset_acquire_ctx *ctx);//设置属性int (*set_property)(struct drm_crtc *crtc,struct drm_property *property, uint64_t val);//拷贝crtc的drm_crtc_state对象, 一般赋值为drm_atomic_helper_crtc_duplicate_state()struct drm_crtc_state *(*atomic_duplicate_state)(struct drm_crtc *crtc);void (*atomic_destroy_state)(struct drm_crtc *crtc,struct drm_crtc_state *state);//atomic 操作中设置特定属性值到state中,该接口一般可由drm_atomic_set_property调用int (*atomic_set_property)(struct drm_crtc *crtc,struct drm_crtc_state *state,struct drm_property *property,uint64_t val);//获取atomic属性int (*atomic_get_property)(struct drm_crtc *crtc,const struct drm_crtc_state *state,struct drm_property *property,uint64_t *val);//drm_dev_register之后,调用该接口进行额外的crtc操作int (*late_register)(struct drm_crtc *crtc);//与late_register接口相反, 在drm_dev_unregister之前调用void (*early_unregister)(struct drm_crtc *crtc);//以下接口与crc相关int (*set_crc_source)(struct drm_crtc *crtc, const char *source);int (*verify_crc_source)(struct drm_crtc *crtc, const char *source,size_t *values_cnt);const char *const *(*get_crc_sources)(struct drm_crtc *crtc,size_t *count);//打印crtc的atomic state属性值, 一般由drm_atomic_print_state调用void (*atomic_print_state)(struct drm_printer *p,const struct drm_crtc_state *state);//获取硬件vblank counter计数u32 (*get_vblank_counter)(struct drm_crtc *crtc);//使能vblank中断int (*enable_vblank)(struct drm_crtc *crtc);//关闭vbank中断void (*disable_vblank)(struct drm_crtc *crtc);//获取vblank时间戳bool (*get_vblank_timestamp)(struct drm_crtc *crtc,int *max_error,ktime_t *vblank_time,bool in_vblank_irq);
};

4. 应用层的调用

         crtc的设置主要有ACTIVE/MODE_ID属性, 其中MODE_ID属性,是设置其显示时序,常用的设置接口如下:

4.1 drmModeSetCrtc (drmlib库里)---> drm_mode_setcrtc

        该接口设置crtc的显示buf, 连接的connector_id, 显示时序mode, 从代码中可以看出来,该接口绑定fb到crtc时,实际上是绑定该crtc的primary plane上。前面已经介绍了。

相关文章:

Linux内核4.14版本——drm框架分析(4)——crtc分析

目录 1. struct drm_crtc结构体 2. crtc相关的API 2.1 drm_crtc_init_with_planes 2.5 drm_mode_setcrtc 3. func的一些介绍 3.1 struct drm_crtc_helper_funcs 3.2 struct drm_crtc_funcs 4. 应用层的调用 4.1 drmModeSetCrtc &#xff08;drmlib库里&#xff09;---…...

用原生js手写分页功能

分页功能如下&#xff1a; 数据分页显示&#xff0c;每页显示若干条数据&#xff0c;默认当前页码为第一页。例如&#xff1a;每页5条数据&#xff0c;则第一页显示 1-5 条&#xff0c;第二页显示 6-10 条&#xff0c;依此类推。当页码为第一页时&#xff0c;上一页为禁用状态…...

CornerNet介绍

CornerNet: Detecting Objects as Paired Keypoints ECCV 2018 Paper&#xff1a;https://arxiv.org/pdf/1808.01244v2.pdf Code&#xff1a;GitHub - princeton-vl/CornerNet 摘要&#xff1a; 提出了一种single-stage的目标检测算法CornerNet&#xff0c;它把每个目标检…...

【SpringBoot】日志使用

默认配置 Spring Boot默认帮我们配置好了日志 //记录器Logger logger LoggerFactory.getLogger(getClass());Testpublic void contextLoads() {//System.out.println();//日志的级别&#xff1b;//由低到高 trace<debug<info<warn<error//可以调整输出的日志级…...

关于slice扩容性能损耗的探究

背景 ​ 如果让我评选最伟大的数据结构&#xff0c;在我心中答案只有两个&#xff0c;数组和哈希表&#xff0c;这两个是我的程序的重要组成部分&#xff0c;同时也是我饭碗的重要组成部分。slice和map简洁明了的API很容易让我们有一种他们提供了无限大的空间&#xff0c;可以…...

Java实现单向链表

✅作者简介&#xff1a;热爱Java后端开发的一名学习者&#xff0c;大家可以跟我一起讨论各种问题喔。 &#x1f34e;个人主页&#xff1a;Hhzzy99 &#x1f34a;个人信条&#xff1a;坚持就是胜利&#xff01; &#x1f49e;当前专栏&#xff1a;Java数据结构与算法 &#x1f9…...

3月4日,30秒知全网,精选7个热点

///印度最大供电商罕见于现货市场购煤&#xff0c;能源供应短缺成忧 据知情人士透露&#xff0c;这家印度国有发电公司计划在下周左右发布300万吨的招标 ///QQ音乐推出AIGC黑胶播放器 这是国内音乐行业首个运用AI技术&#xff0c;通过文字、图片指令快速生成不同风格的播放器…...

EXCEL-职业版本(2)

Excel-职业版本&#xff08;2&#xff09; 定位 1.如何快速定位到不连续的空值&#xff0c;填充为0 1.在任意空单元格里复制0 2.选中数据区域CtrlA 3.CtrlG 4.选择【定位条件】 5.选择【空值】 6.ctrlV 粘贴 即可 2.怎么一次性计算每个小组的数量 单价和金额的和? 1.选中…...

java中延时队列的实现

大家好&#xff0c;我是一名CRUD工程师&#xff0c;最近我朋友突然来问我如何实现延时队列&#xff0c;我脱口而出就是MQ。不过突然想到公司的项目好像用的是java的一个原生类。于是我就想着趁周末的时间好好的去探究一下各方法实现延时队列的优缺点。 延迟消息 延迟消息就是字…...

基于java的circle buffer的实现

总目录链接==>> AutoSAR入门和实战系列总目录 文章目录 缓冲区示例什么是循环缓冲区?方法 1:使用数组插入元素删除元素方法 2:使用链表插入元素:删除元素:当数据经常从一个地方移动到另一个地方或从一个进程移动到另一个进程或被频繁访问时,它不能存储在永久性内存…...

通用方法——为什么重写equals还要重写hashcode

本文介绍java.lang.Object类中的两个方法&#xff1a;equals和hashCode。这两个方法大家应该都知道&#xff0c;但是这两个方法的作用是什么、为什么重写equals还要重写hashCode、它们之间有什么关系和约定等&#xff0c;今天就来带大家了解一下。 1、hashCode hashCode即散列…...

JavaSE学习进阶day2_01 包和权限修饰符

第一章 包 1.1 包 包在操作系统中其实就是一个文件夹。包是用来分门别类的管理技术&#xff0c;不同的技术类放在不同的包下&#xff0c;方便管理和维护。 在IDEA项目中&#xff0c;建包的操作如下&#xff1a; 这个咱们在基础班就谈到过。 包名的命名规范&#xff1a; 路径…...

Android性能调优 - 省电优化

省电&#xff1a;通过工具Battery Historian查看到:耗电大头: 屏幕、网络、cpuled/oled屏幕显示:降低亮度&#xff0c;开深色模式&#xff1b;锁屏间隔缩短到 &#xff1b;亮屏需要一直持有唤醒锁&#xff0c;还有gps定位也需要用到唤醒锁;网络&#xff1a; 常用的网络优化措施…...

ElasticSearch - SpringBoot整合ES之全文搜索匹配查询 match

文章目录1. 数据准备2. match 匹配查询1. 全文检索2. 简化查询DSL语句3. match 匹配查询原理官方文档地址&#xff1a;https://www.elastic.co/guide/en/elasticsearch/reference/index.html权威指南&#xff1a;https://www.elastic.co/guide/cn/elasticsearch/guide/current/…...

句子的改写和扩写

目录 1.句子改写 2.句子扩写 &#xff08;不低于15个句子算是长句子&#xff0c;不能太多长句子&#xff09; 1.句子改写 我绝不会嫁给你的。 如果你是世界上最后一个男人&#xff0c;我就去寺庙。 If you married me,I would jump into the well. 如果你嫁给我&#xff0c;我…...

DockerFile创建及案例

DockerFile dockerfile是用来构建docker镜像的文件&#xff0c;命令脚本参数脚本&#xff01; 构建步骤 编写一个dockerfile文件docker build 构建成为一个对象docker run 运行镜像docker push 发布镜像&#xff08;DockerHub、阿里云镜像仓库&#xff09; 去官网Docker-Hub…...

第十四届蓝桥杯三月真题刷题训练——第 1 天

目录 题目1&#xff1a;数列求值 代码&#xff1a; 题目2&#xff1a;质数 代码&#xff1a; 题目3&#xff1a;饮料换购 代码&#xff1a; 题目1&#xff1a;数列求值 题目描述 本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出…...

基于容器云提交spark job任务

容器云提交spark job任务 容器云提交KindJob类型的spark任务&#xff0c;首先需要申请具有Job任务提交权限的rbac&#xff0c;然后编写对应的yaml文件&#xff0c;通过spark内置的spark-submit命令&#xff0c;提交用户程序(jar包)到集群执行。 1、创建任务job提交权限rbac …...

Linux系统调用之目录操作函数

前言 如果&#xff0c;想要深入的学习Linux系统调用中mkdir&#xff0c;rmdir&#xff0c;rename&#xff0c;chdir&#xff0c;getcwd等这些有关于目录操作函数&#xff0c;还是需要去自己阅读Linux系统中的帮助文档。 具体输入命令&#xff1a; man 2 mkdir/rmdir/rename/ch…...

设计模式-策略模式

前言 作为一名合格的前端开发工程师&#xff0c;全面的掌握面向对象的设计思想非常重要&#xff0c;而“设计模式”是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的&#xff0c;代表了面向对象设计思想的最佳实践。正如《HeadFirst设计模式》中说的一句话&…...

React 第五十五节 Router 中 useAsyncError的使用详解

前言 useAsyncError 是 React Router v6.4 引入的一个钩子&#xff0c;用于处理异步操作&#xff08;如数据加载&#xff09;中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误&#xff1a;捕获在 loader 或 action 中发生的异步错误替…...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 &#xff08;1&#xff09;连接查询&#xff08;JOIN&#xff09; 内连接&#xff08;INNER JOIN&#xff09;&#xff1a;返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

Web 架构之 CDN 加速原理与落地实践

文章目录 一、思维导图二、正文内容&#xff08;一&#xff09;CDN 基础概念1. 定义2. 组成部分 &#xff08;二&#xff09;CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 &#xff08;三&#xff09;CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 &#xf…...

Springboot社区养老保险系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;社区养老保险系统小程序被用户普遍使用&#xff0c;为方…...

Java 二维码

Java 二维码 **技术&#xff1a;**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...

接口自动化测试:HttpRunner基础

相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具&#xff0c;支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议&#xff0c;涵盖接口测试、性能测试、数字体验监测等测试类型…...

基于江科大stm32屏幕驱动,实现OLED多级菜单(动画效果),结构体链表实现(独创源码)

引言 在嵌入式系统中&#xff0c;用户界面的设计往往直接影响到用户体验。本文将以STM32微控制器和OLED显示屏为例&#xff0c;介绍如何实现一个多级菜单系统。该系统支持用户通过按键导航菜单&#xff0c;执行相应操作&#xff0c;并提供平滑的滚动动画效果。 本文设计了一个…...

Linux基础开发工具——vim工具

文章目录 vim工具什么是vimvim的多模式和使用vim的基础模式vim的三种基础模式三种模式的初步了解 常用模式的详细讲解插入模式命令模式模式转化光标的移动文本的编辑 底行模式替换模式视图模式总结 使用vim的小技巧vim的配置(了解) vim工具 本文章仍然是继续讲解Linux系统下的…...

多模态学习路线(2)——DL基础系列

目录 前言 一、归一化 1. Layer Normalization (LN) 2. Batch Normalization (BN) 3. Instance Normalization (IN) 4. Group Normalization (GN) 5. Root Mean Square Normalization&#xff08;RMSNorm&#xff09; 二、激活函数 1. Sigmoid激活函数&#xff08;二分类&…...