当前位置: 首页 > 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设计模式》中说的一句话&…...

面试+算法:罗马数字及Excel列名与数字互相转换

概述 算法是一个程序员的核心竞争力&#xff0c;也是面试最重要的考查环节。 试题 判断一个罗马数字是否有效 罗马数字包含七种字符&#xff1a;I&#xff0c;V&#xff0c;X&#xff0c;L&#xff0c;C&#xff0c;D和M&#xff0c;如下 字符数值I1V5X10L50C100D500M1000…...

Connext DDS路由服务Routing Service(1)

1 简介 RTI路由服务是一种开箱即用的解决方案,允许开发人员快速扩展和集成不同或地理位置分散的实时系统。它跨域、LAN和WAN扩展RTI ConnextDDS应用程序,包括防火墙和NAT穿越。 它还支持DDS到DDS的桥接,允许您对数据进行转换。这允许未修改的DDS应用程序进行通信,即使它们是…...

如何使用SaleSmartly进行Facebook Messenger 营销、销售和支持

如何使用SaleSmartly&#xff08;ss客服&#xff09;进行Facebook Messenger 营销、销售和支持上篇文章我们讲了什么是Facebook Messenger CRM以及获得Facebook Messenger CRM的注意事项&#xff0c;现在你有更多时间与客户聊天&#xff0c;让我们看看你如何使用SaleSmartly&am…...

教资教育知识与能力中学教学

目录 3.1 教学概述 3.2 教学过程 3.3 教学原则*【简答/辨析重点】 3.4 教学方法 3.5 教学组织形式 3.6 教学工作基本环节 3.7 教学评价 3.1 教学概述 1、教学的意义【14/18辨析】 教学是传授系统知识、促进学生发展的最有效形式&#xff1b; 教学是学校进行全面发展教…...

IDEA中使用Tomcat的两种方式:集成本地Tomcat使用Tomcat Maven插件

一、前言 在IDEA中创建完一个Maven Web项目&#xff0c;并补齐了目录以后&#xff0c;准备使用Tomcat时&#xff0c;就需要在自己创建的项目中去部署Tomcat&#xff0c;前文已经介绍了如何创建Maven Web&#xff0c;所以这里就不多加赘述&#xff0c;直接讲述部署Tomcat的方法…...

IP 地址的简介

IP 地址 Internet 依靠 TCP/IP 协议&#xff0c;在全球范围内实现不同硬件结构、不同操作系统、不同网络系统的主机之间的互联。在 Internet 上&#xff0c;每一个节点都依靠唯一的 IP 地址相互区分和相互联系&#xff0c;IP 地址用于标识互联网中的每台主机的身份&#xff0c…...

3D动作/动画特效

硕士/博士符合一本高校人才引进条件的硕士、博士&#xff0c;教研能力突出者可签合作高校正式编制本科/硕士成绩优异专业扎实、有创新思维者可在签约工作后在校继续读研读博【产业模式】数字经济→数字孪生→升级转型【细份领域】数字产业、数字工程、数字教研、数字政企【合作…...

python 多线程编程之_thread模块

_thread模块除了可以派生线程外&#xff0c;还提供了基本的同步数据结构&#xff0c;又称为锁对象&#xff08;lock object&#xff0c;也叫原语锁、简单锁、互斥锁、互斥和二进制信号量&#xff09;。 下面是常用的线程函数&#xff1a; 函数描述start_new_thread(function,…...

vue:vue2与vue3的区别

一、背景 vue2是指的2.X vue3是指的3.0以及更新的版本&#xff08;3.2版本在script标签里可以写setup&#xff0c;极大的简化了开发&#xff09; 本文对比两者区别。 二、官网 生命周期选项 | Vue.js API 参考 | Vue.js Vue.js - 渐进式 JavaScript 框架 | Vue.js Vue.…...

SQL数据库语法

目录 1. 常用数据类型 2. 约束 4. 数据库操作 5. 数据表操作 1. 常用数据类型 int 整型double 浮点数varchar 字符型data 年月日datetime 年月日 时分秒2. 约束 主键 primary key : 物理上存储的顺序(存在真实排序), 主键…...