Chrome 源码阅读:跟踪一个鼠标事件的流程

我们通过在关键节点打断点的方式,去分析一个鼠标事件的流程。

我们知道chromium是多进程模型,那么,我们可以推测:一个鼠标消息先从主进程产生,再通过跨进程通信发送给渲染进程,渲染进程再发送给WebFrame,最后被派发到目标Node上

于是,首先,我们在主进程,找到鼠标时间的最终消费点,打上断点,进行分析:

主进程继续往下走,就是把事件通过跨进程通信框架mojo发送过去的逻辑了:

接下来,我们要换个进程,在渲染进程打上断点,看看消息过来后,怎么走的流程:

首先搜索这个mojom的事件,确认渲染进程断点落脚处:

题外话:这个input_handler.mojom.cc到了渲染进程那就成了input_handler.mojom-blink.cc了。

这两个文件99%相似,只有少量的不同(命名空间、基础类型):

这两个类的基类是一样的:

这个类的头文件写明了,是由什么工具生成的:

很好奇生成源,我们也去看看:

// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.module blink.mojom;import "cc/mojom/browser_controls_state.mojom";
import "cc/mojom/overscroll_behavior.mojom";
import "cc/mojom/touch_action.mojom";
import "mojo/public/mojom/base/string16.mojom";
import "mojo/public/mojom/base/time.mojom";
import "third_party/blink/public/mojom/input/gesture_event.mojom";
import "third_party/blink/public/mojom/input/handwriting_gesture_result.mojom";
import "third_party/blink/public/mojom/input/input_event_result.mojom";
import "third_party/blink/public/mojom/input/input_event.mojom";
import "third_party/blink/public/mojom/input/pointer_lock_context.mojom";
import "third_party/blink/public/mojom/input/pointer_lock_result.mojom";
import "third_party/blink/public/mojom/input/ime_host.mojom";
import "third_party/blink/public/mojom/input/stylus_writing_gesture.mojom";
import "third_party/blink/public/mojom/input/touch_event.mojom";
import "third_party/blink/public/mojom/selection_menu/selection_menu_behavior.mojom";
import "ui/base/ime/mojom/ime_types.mojom";
import "ui/events/mojom/event_constants.mojom";
import "ui/events/mojom/event_latency_metadata.mojom";
import "ui/events/mojom/event.mojom";
import "ui/events/mojom/scroll_granularity.mojom";
import "ui/gfx/geometry/mojom/geometry.mojom";
import "ui/gfx/range/mojom/range.mojom";
import "ui/latency/mojom/latency_info.mojom";[EnableIf=is_android]
import "third_party/blink/public/mojom/input/synchronous_compositor.mojom";// These structs are purposely duplicated from ui/events/mojom/event.mojom.
// They map WebInputEvent <-> WebInputEvent across mojo.
// We have to work at unifying them. The current problem is that the browser
// uses WebInputEvents inside the render widget host and input router. Once
// we move these to ui::Event's then we can get rid of these duplicated
// mojom structs. Ideally the browser would use ui::Event up until we
// pass the events into the renderer and just use a StructTraits to perform
// conversion from ui::mojom::Event --> blink::WebInputEvent.
struct KeyData {int32 dom_key;int32 dom_code;int32 windows_key_code;int32 native_key_code;bool is_system_key;bool is_browser_shortcut;mojo_base.mojom.String16 text;mojo_base.mojom.String16 unmodified_text;
};struct PointerData {int32 pointer_id;float force;double tilt_x;double tilt_y;float tangential_pressure;int32 twist;blink.mojom.Button button;ui.mojom.EventPointerType pointer_type;int32 movement_x;int32 movement_y;bool is_raw_movement_event;gfx.mojom.PointF widget_position;gfx.mojom.PointF screen_position;MouseData? mouse_data;int32 device_id;
};struct WheelData {float delta_x;float delta_y;float wheel_ticks_x;float wheel_ticks_y;float acceleration_ratio_x;float acceleration_ratio_y;uint8 phase;uint8 momentum_phase;blink.mojom.DispatchType cancelable;uint8 event_action;uint8 delta_units;
};struct MouseData {int32 click_count;WheelData? wheel_data;
};struct ScrollUpdate {float velocity_x;float velocity_y;
};struct ScrollData {float delta_x;float delta_y;ui.mojom.ScrollGranularity delta_units;bool target_viewport;blink.mojom.InertialPhaseState inertial_phase;bool synthetic;int32 pointer_count;// Used for GestureScrollBegin type only. If this is true, we use the scroll// sequence to do cursor control rather than scroll.bool cursor_control;ScrollUpdate? update_details;
};struct PinchBeginData {bool needs_wheel_event;
};struct PinchUpdateData {float scale;bool zoom_disabled;bool needs_wheel_event;
};struct PinchEndData {bool needs_wheel_event;
};struct FlingData {float velocity_x;float velocity_y;bool target_viewport;bool prevent_boosting;
};struct TapData {int32 tap_count;bool needs_wheel_event;
};struct TapDownData {int32 tap_down_count;
};struct GestureData {gfx.mojom.PointF screen_position;gfx.mojom.PointF widget_position;blink.mojom.GestureDevice source_device;bool is_source_touch_event_set_blocking;ui.mojom.EventPointerType primary_pointer_type;int32 primary_unique_touch_event_id;int32 unique_touch_event_id;gfx.mojom.Size? contact_size;ScrollData? scroll_data;PinchBeginData? pinch_begin_data;PinchUpdateData? pinch_update_data;PinchEndData? pinch_end_data;TapData? tap_data;TapDownData? tap_down_data;FlingData? fling_data;
};struct TouchPoint {blink.mojom.TouchState state;float radius_x;float radius_y;float rotation_angle;PointerData pointer_data;
};struct TouchData {blink.mojom.DispatchType cancelable;bool moved_beyond_slop_region;bool touch_start_or_first_move;bool hovering;uint32 unique_touch_event_id;array<TouchPoint> touches;
};struct Event {blink.mojom.EventType type;int32 modifiers;mojo_base.mojom.TimeTicks timestamp;ui.mojom.LatencyInfo latency;ui.mojom.EventLatencyMetadata event_latency_metadata;KeyData? key_data;PointerData? pointer_data;GestureData? gesture_data;TouchData? touch_data;
};// Represents the current state of overscroll.
struct DidOverscrollParams {gfx.mojom.Vector2dF accumulated_overscroll;gfx.mojom.Vector2dF latest_overscroll_delta;gfx.mojom.Vector2dF current_fling_velocity;gfx.mojom.PointF causal_event_viewport_point;cc.mojom.OverscrollBehavior overscroll_behavior;
};// A struct wrapper for the TouchAction enumeration because
// enumerations cannot be optional.
struct TouchActionOptional {cc.mojom.TouchAction touch_action;
};// Types related to sending edit commands to the renderer.
struct EditCommand {string name;string value;
};// A structure that indicates selection offsets if the selection could be
// established.
struct SelectAroundCaretResult {// The offset differences between the extended selection and the initial// selection (which is a caret).int32 extended_start_adjust;int32 extended_end_adjust;// The offset differences between the word selection (regardless of the// extended selection granularity) and the initial selection (which is a// caret).int32 word_start_adjust;int32 word_end_adjust;
};// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.blink_public.input
// GENERATED_JAVA_CLASS_NAME_OVERRIDE: SelectionGranularity
enum SelectionGranularity {kWord,kSentence,
};// An enumeration that describes the allowed non-directional pan action for the
// element under pointer being considered.
enum PanAction {// No pan action allowed.kNone,// Pan action is scroll.kScroll,// Pan action moves cursor when initial touch move is in horizontal direction,// or scrolls in the vertical direction.kMoveCursorOrScroll,// Pan action is stylus writable.kStylusWritable,
};// Interface exposed by the browser to the renderer.
interface WidgetInputHandlerHost {// When the renderer's main thread computes the touch action, send this to the// browser.SetTouchActionFromMain(cc.mojom.TouchAction touch_action);// Sets the pan action possible for the element under pointer which could be// one of the actions described under enum PanAction. Note that this is// different from TouchAction and does not contain directional pan info.SetPanAction(PanAction pan_action);// Sent by the compositor when input scroll events are dropped due to bounds// restrictions on the root scroll offset.DidOverscroll(DidOverscrollParams params);// Sent by the compositor when a GSB has started scrolling the viewport.DidStartScrollingViewport();// Required for cancelling an ongoing input method composition.ImeCancelComposition();// Sends the character bounds after every composition change// to always have correct bound info.ImeCompositionRangeChanged(gfx.mojom.Range range,array<gfx.mojom.Rect>? character_bounds,array<gfx.mojom.Rect>? line_bounds);// Updates the mouse capture state of this widget. While capture is enabled,// all mouse events, including those that don't hittest to this widget, will// be targeted to this widget. This enables Blink to behave correctly when// a scrollbar is being dragged, or text is being drag-highlighted, even// when the mouse passes across different RenderWidget areas.SetMouseCapture(bool capture);// Updates the browser whether this main frame widget has ongoing autoscroll// selection. Any further mouse up event should always be dispatched to the// main frame in addition to it's event target (OOP child frame) if the state// is active. This API should only ever be called on the InputHandler for a// main frame's RenderWidgetHost.SetAutoscrollSelectionActiveInMainFrame(bool autoscroll_selection);// Requests locking the target of mouse events to a single element and// removing the cursor from view.  Mostly used by the Pointer Lock API.// See https://www.w3.org/TR/pointerlock/ for more info. This call is// also used by Pepper Flash.// |from_user_gesture| indicates whether this request came from a user// gesture or not.// |unadjusted_movement| indicates whether the request asked for raw mouse// movement data or just what the operating system returns (often accelerated// mouse movement).// |result| kSuccess if the mouse has been locked or the appropriate error// reason if not.// |context| is one end of a mojo pipe that will stay connected as long as// the mouse is locked. Is a NullRemote if |result| is not kSuccess.RequestMouseLock(bool from_user_gesture,bool unadjusted_movement)=> (PointerLockResult result,pending_remote<blink.mojom.PointerLockContext>? context);
};// This interface provides the input actions associated with the FrameWidget.
// Other input actions may also be dispatched via the WidgetInputHandler
// interface. If frame input actions are dispatched the WidgetInputHandler
// should be fetched via the associated interface request so that input calls
// remain in order. See https://goo.gl/x4ee8A for more details.
interface FrameWidgetInputHandler {// Adds text decorations between a given valid start and end offsets in the// currently focused editable field.AddImeTextSpansToExistingText(uint32 start, uint32 end, array<ui.mojom.ImeTextSpan> ime_text_spans);// Clears text decorations type between a given valid start and end offsets// in the currently focused editable field.ClearImeTextSpansByType(uint32 start, uint32 end, ui.mojom.ImeTextSpanType type);// Sets the text composition to be between the given start and end offsets in// the currently focused editable field.SetCompositionFromExistingText(int32 start, int32 end, array<ui.mojom.ImeTextSpan> ime_text_spans);// Deletes the current selection plus the specified number of characters// before and after the selection or caret.ExtendSelectionAndDelete(int32 before, int32 after);// Deletes the current selection plus the specified number of characters// before and after the selection or caret.ExtendSelectionAndReplace(uint32 before,uint32 after,mojo_base.mojom.String16 replacement_text);// Deletes text before and after the current cursor position, excluding the// selection. The lengths are supplied in Java chars (UTF-16 Code Unit),// not in code points or in glyphs.DeleteSurroundingText(int32 before, int32 after);// Deletes text before and after the current cursor position, excluding the// selection. The lengths are supplied in code points, not in Java chars// (UTF-16 Code Unit) or in glyphs. Does nothing if there are one or more// invalid surrogate pairs in the requested rangeDeleteSurroundingTextInCodePoints(int32 before, int32 after);// Selects between the given start and end offsets in the currently focused// editable field.SetEditableSelectionOffsets(int32 start, int32 end);// Stylus Writing - perform Gesture action in input using gesture data.HandleStylusWritingGestureAction(blink.mojom.StylusWritingGestureData gesture_data)=> (HandwritingGestureResult result);// Message payload is the name/value of a WebCore edit command to execute.ExecuteEditCommand(string command, mojo_base.mojom.String16? value);// These messages are typically generated from context menus and request the// renderer to apply the specified operation to the current selection.Undo();Redo();Cut();Copy();CopyToFindPboard();CenterSelection();Paste();PasteAndMatchStyle();Delete();SelectAll();CollapseSelection();// Pushed from the browser to the renderer each time the IME is activated,// e.g. an editable element becomes focused.[EnableIf=is_android]PassImeRenderWidgetHost(pending_remote<ImeRenderWidgetHost> remote);// Replaces the selected region or a word around the cursor with the// specified string.Replace(mojo_base.mojom.String16 word);// Replaces the misspelling in the selected region with the specified string.ReplaceMisspelling(mojo_base.mojom.String16 word);// Requests the renderer to select the region between two points.// Expects a SelectRange_ACK message when finished.SelectRange(gfx.mojom.Point base, gfx.mojom.Point extent);// Sent by the browser to ask the renderer to adjust the selection start and// end points by the given amounts. A negative amount moves the selection// towards the beginning of the document, a positive amount moves the// selection towards the end of the document. Will send show selection menu// event when needed.AdjustSelectionByCharacterOffset(int32 start, int32 end, SelectionMenuBehavior behavior);// Requests the renderer to select the specified granularity around caret and// to potentially show the selection handles and / or context menu after// selection.// Expects ack with new selection information when finished, or null if the// selection failed.SelectAroundCaret(SelectionGranularity granularity, bool should_show_handle,bool should_show_context_menu)=> (SelectAroundCaretResult? result);// Requests the renderer to move the selection extent point to a new position.// Expects a MoveRangeSelectionExtent_ACK message when finished.MoveRangeSelectionExtent(gfx.mojom.Point extent);// Tells the renderer to scroll the currently focused node into view only if// the currently focused node is a Text node (textfield, text area or content// editable divs).ScrollFocusedEditableNodeIntoView();// Replies when the next PageScaleAnimation has completed. Can only be called// on the outermost main frame. Can be used to reliably wait for a// ScrollFocusedEditableNodeIntoView to complete since that may create a// PageScaleAnimation which can take several frames to complete.// ScrollFocusedEditableNodeIntoView cannot use a reply callback for this// since it may be called on a subframe but the scroll will be completed in// another renderer when it bubbles up to the root. Additionally, the caller// may not be the one to have called ScrollFocusedEditableNodeIntoView; for// example, a test that simulates tapping an input box.WaitForPageScaleAnimationForTesting() => ();// Requests the renderer to move the caret selection toward the point.MoveCaret(gfx.mojom.Point point);
};// An enumeration describing the active and focus states. If a widget is
// focused then it must also be active, therefore there is no focused and
// not active value in this enumeration. All widgets in a tab will have
// the same active state. Active state is tab specific, and focus state is
// frame specific. See
// https://www.chromium.org/developers/design-documents/aura/focus-and-activation/
enum FocusState
{kFocused,kNotFocusedAndActive,kNotFocusedAndNotActive
};// Interface exposed by the renderer to the browser. This class represents
// an input interface for an associated Widget object. See FrameWidgetInputHandler
// for an interface at the frame level.
interface WidgetInputHandler {// Tells widget focus has been changed.SetFocus(FocusState state);// Tells widget mouse capture has been lost.MouseCaptureLost();// This message notifies the renderer that the next key event is bound to one// or more pre-defined edit commands. If the next key event is not handled// by blink, the specified edit commands shall be executed against current// focused frame.// Parameters// * edit_commands//   See t_p/b/renderer/core/editing/commands/editing_command_type.h//   Contains one or more edit commands.// See t_p/b/renderer/core/editing/commands/editor_command.cc for// detailed definition of webkit edit commands.//// This message must be sent just before sending a key event.SetEditCommandsForNextKeyEvent(array<EditCommand> commands);// Sends the cursor visibility state to the render widget.CursorVisibilityChanged(bool visible);// This message sends a string being composed with an input method.// Note, the response is specifically for Devtools to learn about completionImeSetComposition(mojo_base.mojom.String16 text,array<ui.mojom.ImeTextSpan> ime_text_spans,gfx.mojom.Range range, int32 start, int32 end) => ();// This message deletes the current composition, inserts specified text, and// moves the cursor.// Note, the response is specifically for Devtools to learn about completionImeCommitText(mojo_base.mojom.String16 text,array<ui.mojom.ImeTextSpan> ime_text_spans,gfx.mojom.Range range, int32 relative_cursor_position) => ();// This message inserts the ongoing composition.ImeFinishComposingText(bool keep_selection);// Request from browser to update text input state.RequestTextInputStateUpdate();// Request from browser to update the cursor and composition information which// will be sent through ImeCompositionRangeChanged. Setting// |immediate_request| to true  will lead to an immediate update. If// |monitor_updates| is set to true then changes to text selection or regular// updates in each compositor frame (when there is a change in composition// info) will lead to updates being sent to the browser.RequestCompositionUpdates(bool immediate_request, bool monitor_request);// Sends an input event to the render widget. The browser should use this// API if it wants to know about the result of the rendering handling// the event. The callback may be delayed based on the event running on// the main thread so DispatchNonBlockingEvent is always preferred if// you don't require notification.DispatchEvent(Event event)=> (blink.mojom.InputEventResultSource source,ui.mojom.LatencyInfo updated_latency,blink.mojom.InputEventResultState state,DidOverscrollParams? overscroll,TouchActionOptional? touch_action);// Sends a non-blocking input event to the render widget. The behaviour// of this API is the same as DispatchEvent just that there is no callback// after the event is processed.DispatchNonBlockingEvent(Event event);// Forces input to be flushed and resolves the callback only once the input// has been fully processed, meaning its effects are visible to the full// system. In practice, this will force a redraw and wait until the new// CompositorFrame (containing all changes caused by prior input) has been// displayed.WaitForInputProcessed() => ();// Attach the synchronous compositor interface. This method only// should be called for Android WebView.[EnableIf=is_android]AttachSynchronousCompositor(pending_remote<SynchronousCompositorControlHost> control_host,pending_associated_remote<SynchronousCompositorHost> host,pending_associated_receiver<SynchronousCompositor> compositor_request);// Return an associated FrameWidgetInputHandler interface so that input// messages to the frame associated with this widget can be sent// serially.GetFrameWidgetInputHandler(pending_associated_receiver<FrameWidgetInputHandler> interface_request);// Notifies the renderer whether hiding/showing the browser controls is// enabled, what the current state should be, and whether or not to// animate to the proper state.UpdateBrowserControlsState(cc.mojom.BrowserControlsState constraints,cc.mojom.BrowserControlsState current,bool animate);
};

可见,这个生成的不止一个事件,包含了大部分用户事件了。去看看所在目录,也初步熟悉blink的目录结构了:

后面我们再详细介绍这套mojo跨进程通信框架的细节。

言归正传,我们attach到render进程,继续打断点跟踪鼠标事件。

想在渲染进程找到WidgetInputHandler类对应的消息,只需要在后面加个Impl即可,我们通过符号跳转,找到WidgetInputHandlerImpl类:

接下来,中间弯弯绕绕太多,我们直接在node打个断点,看看鼠标事件如何传递到node具体的处理逻辑中的:

事件首先被捕获并封装为一个MouseEventPointerEvent对象。然后通过EventDispatcher类和相关方法,事件被分发到目标Node。对应的HTML元素(通过HTMLElement和特化的TextControlInnerEditorElement)会处理这个事件,然后这个时间触发默认基类的处理器。

WebFrameWidget:继承自WebWidget,但是大部分函数依然是虚函数,用于专门负责处理一个WebFrame(即一个网页框架)的渲染和事件。如果要想显示一个网页,那么需要继承自WebFrameWidget并实现相关纯虚函数。

WebFrameWidgetImpl:是WebFrameWidget在blink里的一个具体实现类。它实现了接口中定义的所有方法,并提供了框架的具体行为。WebFrameWidgetImpl负责实际的绘图逻辑、输入事件处理、视图的更新和大小调整等。这个实现将抽象的行为具体化,它通过调用Blink渲染引擎的其他组件,如布局引擎、绘图系统等,来完成对Web内容的渲染和事件处理。WebFrameWidgetImpl是Web内容在Blink中被渲染的核心地方,它直接与底层的渲染流水线交互。

讲到这里,也要引出一个重量级的基类:Node:

Node 类是一个非常重要的基类,它表示文档中的一个节点。Node 类扮演了核心角色,以下是对 Node 类及其作用的更详细介绍:

  1. 层次结构:
    Node 类位于 DOM(文档对象模型)层次结构中的基础位置。在 DOM 中,所有的元素、文本内容和属性都被视为节点。因此,Node 类提供了一系列的基础方法和属性,用于管理节点之间的关系(例如父子关系和兄弟关系)、节点的遍历以及节点的基本操作(比如插入、替换、删除)。

  2. 事件模型:
    Node 类还是事件模型的一部分。在 Blink 中,事件通常会在节点之间传播,遵循捕获阶段、目标阶段和冒泡阶段。Node 类提供了事件处理的相关方法,比如绑定事件监听器、分发事件等。当事件发生时,比如用户的点击或键盘操作,它会被分发到正确的 Node 对象,并且通过事件监听器进行相应的处理。

  3. 渲染:
    虽然 Node 类本身并不直接处理渲染,但它的派生类,如 Element 和特化后的 HTMLElement,会存储与渲染相关的属性(例如样式信息)。这些类将 Node 的基础功能扩展到了渲染管线中,这样渲染引擎就可以使用这些信息来呈现视觉元素。

  4. 类型多样性:
    DOM 中有不同类型的节点,包括但不限于元素节点(Element)、文本节点(Text)、注释节点(Comment)和文档节点(Document)。Node 类是这些具体节点类型的基类,通过继承和多态,不同类型的节点可以拥有特化的行为,并且仍然能够通过 Node 类的接口进行通用处理。

  5. API 和脚本接口:
    Node 类还提供了一系列的 API,供 JavaScript 脚本访问和操纵节点。开发者可以通过这些 API 查询节点信息、修改节点结构、动态添加或移除节点等。这为开发者提供了强大的能力来改变页面内容和行为。

总的来说,Node 类是 Blink 和 Web 开发者用来操作和理解 Web 页面结构的基础,它为构建、遍历和交互提供了基本的框架。通过 Node 及其派生类,Blink 渲染引擎能够将结构化的 HTML 文档转化为用户可以看到和交互的网页。

未完待续 ....

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

L45---506.相对名次(java)--排序

1.题目描述 2.知识点 &#xff08;1&#xff09;String.join(" ", words) 是 Java 中的一个语法&#xff0c;用于将数组或集合中的元素连接成一个单独的字符串&#xff0c;连接时使用指定的分隔符。这里的 " " 是作为分隔符使用的一个空格字符串。 Strin…

4、后端本地环境搭建

后端本地环境搭建 4.1 安装jdk 下载完成后双击安装的 jdk &#xff0c;点下一步&#xff0c;选择安装目录&#xff0c;一直点下一步&#xff0c;直到结束。 安装完成后同样需要配置环境变量 window s 搜索查看高级系统设置—— 高级 —— 环境变量 —— 系统变量 1、新建一…

API接口测试工具:jmeter的安装、汉化、Jmeter桌面快捷图标和基本使用

文章目录 测试工具&#xff1a;JmeterJmeter安装和配置Jmeter汉化设置中文语言&#xff1a;永久方式设置中文语言&#xff1a;临时方式 设置Jmeter桌面快捷图标jmeter基本用法Jmeter无法保存测试问题解决 测试工具&#xff1a;Jmeter Jmeter依赖于JDK&#xff0c;所以必须确保…

第十一届蓝桥杯C++青少年组中/高级组国赛2020年10月真题解析

一、单选题 第1题 在数组中&#xff0c;数组名表示&#xff08; &#xff09;. A:数组第1个元素的首地址 B:数组第2个元素的首地址 C:数组所有元素的首地址&#xff0c; D:数组最后1个元素的首地址 答案&#xff1a;A 数组名是一个地址&#xff0c;指向第一个元素 第2题 …

中继器、集线器、网桥、交换机、路由器和网关

目录 前言一、中继器、集线器1.1 中继器1.2 集线器 二、网桥、交换机2.1 网桥2.1.1 认识网桥2.1.2 网桥的工作原理2.1.3 生成树网桥 2.2 交换机2.2.1 交换机的特征2.2.2 交换机的交换模式2.2.3 交换机的功能 三、路由器、网关3.1 路由器的介绍3.2 路由器的工作过程3.2.1 前置知…

多客圈子论坛系统 httpGet 任意文件读取漏洞复现

0x01 产品简介 多客圈子论坛系统是一种面向特定人群或特定话题的社交网络&#xff0c;它提供了用户之间交流、分享、讨论的平台。在这个系统中&#xff0c;用户可以创建、加入不同的圈子&#xff0c;圈子可以是基于兴趣、地域、职业等不同主题的。用户可以在圈子中发帖、评论、…

17- Redis 中的 quicklist 数据结构

在 Redis 3.0 之前&#xff0c;List 对象的底层数据结构是双向链表或者压缩列表&#xff0c;然后在 Redis 3.2 的时候&#xff0c;List 对象的底层改由 quicklist 数据结构实现。 其实 quicklist 就是【双向链表 压缩列表】组合&#xff0c;因为一个 quicklist 就是一个链表&…

【产品研发】NPDP价值作用概述

导读&#xff1a;本文结合个人实践和思考对NPDP的价值和作用做了概述说明&#xff0c;对于产品经理而言掌握NPDP的知识体系并且应用到实际工作中&#xff0c;这是非常有必要的。走出以往狭隘的产品研发工作认知&#xff0c;以开放心态学习国际化产品创新开发流程将极大提升产品…

深度学习的舌象诊断:从舌头上了解系统性疾病!

首先 深度学习算法能否解决东方医学中依靠医生经验的诊断问题&#xff1f;而要实现这个目标&#xff0c;需要什么呢&#xff1f; 用舌头诊断被称为口腔健康的指标&#xff0c;但在东方医学中&#xff0c;舌头也被用来评估全身的状况。换句话说&#xff0c;通过分析舌头的图像…

Java学习-JDBC(一)

JDBC 概念 JDBC(Java Database Connectivity)Java数据库连接JDBC提供了一组独立于任何数据库管理系统的APIJava提供接口规范&#xff0c;由各个数据库厂商提供接口的实现&#xff0c;厂商提供的实现类封装成jar文件&#xff0c;也就是我们俗称的数据库驱动jar包JDBC充分体现了…

C#上位机开发

目录 一、上位机简介二、C#语法三、新建VS工程四、WinForm控件4.1 属性4.2 事件4.3 窗体方法4.4 常用控件4.5 布局 五、Serial上位机5.1 UI界面设计5.2 功能设计 六、项目打包成安装包6.1 前提准备6.2 打包步骤 一、上位机简介 在单片机项目开发中&#xff0c;上位机也是一个很…

SwiftUI六组合复杂用户界面

代码下载 应用的首页是一个纵向滚动的地标类别列表&#xff0c;每一个类别内部是一个横向滑动列表。随后将构建应用的页面导航&#xff0c;这个过程中可以学习到如果组合各种视图&#xff0c;并让它们适配不同的设备尺寸和设备方向。 下载起步项目并跟着本篇教程一步步实践&a…

【C语言训练题库】扫雷->简单小游戏!

&#x1f525;博客主页&#x1f525;&#xff1a;【 坊钰_CSDN博客 】 欢迎各位点赞&#x1f44d;评论✍收藏⭐ 目录 1. 题目 2. 解析 3. 代码 4. 小结 1. 题目 小sun上课的时候非常喜欢玩扫雷。他现小sun有一个初始的雷矩阵&#xff0c;他希望你帮他生成一个扫雷矩阵。 扫雷…

Vue3_对接腾讯云COS_大文件分片上传和下载

目录 一、腾讯云后台配置 二、安装SDK 1.script 引入方式 2.webpack 引入方式 三、文件上传 1.new COS 实例 2.上传文件 四、文件下载 腾讯云官方文档&#xff1a; 腾讯云官方文档https://cloud.tencent.com/document/product/436/11459 一、腾讯云后台配置 1.登录 对…

Codeforces Round 951 (Div. 2) F. Kostyanych‘s Theorem(思维题 交互好题)

题目 交互题&#xff0c;n&#xff08;n<1e5&#xff09;个点的完全图&#xff0c;无向的&#xff0c;初始恰好删了n-2条边 每次询问可以输入一个d&#xff1a;? d 交互器会输出一个当前度>d的点v&#xff0c; 如果有多个这样的点&#xff0c;输出度最小的&#xff…

【CS.CN】优化HTTP传输:揭示Transfer-Encoding: chunked的奥秘与应用

文章目录 0 序言0.1 由来0.2 使用场景 1 Transfer-Encoding: chunked的机制2 语法 && 通过设置Transfer-Encoding: chunked优化性能3 总结References 0 序言 0.1 由来 Transfer-Encoding头部字段在HTTP/1.1中被引入&#xff0c;用于指示数据传输过程中使用的编码方式…

InternLM-XComposer2-4KHD开拓性的4K高清视觉-语言模型

大型视觉-语言模型&#xff08;LVLM&#xff09;在图像字幕和视觉问答&#xff08;VQA&#xff09;等任务中表现出色。然而&#xff0c;受限于分辨率&#xff0c;这些模型在处理包含细微视觉内容的图像时面临挑战。 分辨率的限制严重阻碍了模型处理含有丰富细节的图像的能力。…

网络空间安全数学基础·多项式环与有限域

5.1 多项式环&#xff08;掌握&#xff09; 5.2 多项式剩余类环&#xff08;理解&#xff09; 5.3 有限域&#xff08;熟练&#xff09; 5.1 多项式环 定义&#xff1a;设F是一个域&#xff0c;称是F上的一元多项式&#xff0e; 首项&#xff1a;如果an≠0&#xff0c;则称 a…

【Python】认识 Python

一、计算机基础概念 1、什么是计算机 很多老一辈的人&#xff0c;管下面这个叫做计算机。然而&#xff0c;它只是 “计算器”&#xff0c;和计算机是有很大区别的。 现在我们所说的计算机&#xff0c;不光能进行算术运算&#xff0c;还能进行逻辑判断、数据存储、网络通信等…

Qt之QGraphicsView —— 笔记3:矩形图元连接(附完整源码)

效果 完整源码 注意:在ui文件中拖入一个QGraphicsView类窗口控件,然后用MyGraphicsView提升该类。 main.cpp #include "widget.h" #include <QApplication>int main(