MySQL内核技术之"线程操作"
来源:SegmentFault
时间:2023-02-24 19:58:41 158浏览 收藏
对于一个数据库开发者来说,牢固扎实的基础是十分重要的,golang学习网就来带大家一点点的掌握基础知识点。今天本篇文章带大家了解《MySQL内核技术之"线程操作"》,主要介绍了MySQL、数据库,希望对大家的知识积累有所帮助,快点收藏起来吧,否则需要时就找不到了!
预处理
当一个新的连接进来时,MySQL会创建对应的thread(pfs.cc):
/** Implementation of the thread instrumentation interface. @sa PSI_v1::spawn_thread. */ int pfs_spawn_thread_v1(PSI_thread_key key, my_thread_handle *thread, const my_thread_attr_t *attr, void *(*start_routine)(void*), void *arg) { PFS_spawn_thread_arg *psi_arg; PFS_thread *parent; /* psi_arg can not be global, and can not be a local variable. */ psi_arg= (PFS_spawn_thread_arg*) my_malloc(PSI_NOT_INSTRUMENTED, sizeof(PFS_spawn_thread_arg), MYF(MY_WME)); if (unlikely(psi_arg == NULL)) return EAGAIN; psi_arg->m_child_key= key; psi_arg->m_child_identity= (arg ? arg : thread); psi_arg->m_user_start_routine= start_routine; psi_arg->m_user_arg= arg; parent= my_thread_get_THR_PFS(); if (parent != NULL) { /* Make a copy of the parent attributes. This is required, because instrumentation for this thread (the parent) may be destroyed before the child thread instrumentation is created. */ psi_arg->m_thread_internal_id= parent->m_thread_internal_id; memcpy(psi_arg->m_username, parent->m_username, sizeof(psi_arg->m_username)); psi_arg->m_username_length= parent->m_username_length; memcpy(psi_arg->m_hostname, parent->m_hostname, sizeof(psi_arg->m_hostname)); psi_arg->m_hostname_length= parent->m_hostname_length; } else { psi_arg->m_thread_internal_id= 0; psi_arg->m_username_length= 0; psi_arg->m_hostname_length= 0; } int result= my_thread_create(thread, attr, pfs_spawn_thread, psi_arg); if (unlikely(result != 0)) my_free(psi_arg); return result; }
注意上面代码中最后的位置:
my_thread_create(thread, attr, pfs_spawn_thread, psi_arg);这个函数直接调用
pthread_create(&thread->thread, attr, func, arg)创建pthead。
这里最重要的事情是把当前thread的执行环境传到新的thread。所以上面代码前半部分都是在做这个事情。让我们看一下都需要传入哪些上下文。参数
psi_arg就是要传入的上下文。开始用
my_malloc创建,最后用
my_free销毁。中间是对
psi_arg进行赋值。
和当前线程有关的是
parent= my_thread_get_THR_PFS()。然后把需要的
parent内容取出来并赋值给
psi_arg:
/* Make a copy of the parent attributes. This is required, because instrumentation for this thread (the parent) may be destroyed before the child thread instrumentation is created. */ psi_arg->m_thread_internal_id= parent->m_thread_internal_id; memcpy(psi_arg->m_username, parent->m_username, sizeof(psi_arg->m_username)); psi_arg->m_username_length= parent->m_username_length; memcpy(psi_arg->m_hostname, parent->m_hostname, sizeof(psi_arg->m_hostname)); psi_arg->m_hostname_length= parent->m_hostname_length;
主要是对三个变量赋值:
m_thread_internal_id,
m_username,
m_hostname。
生成PFS_thread
从上面可以看到,生成的thread具体执行的pfs_spawn_thread函数,其内容如下:
extern "C" void* pfs_spawn_thread(void *arg) { PFS_spawn_thread_arg *typed_arg= (PFS_spawn_thread_arg*) arg; void *user_arg; void *(*user_start_routine)(void*); PFS_thread *pfs; /* First, attach instrumentation to this newly created pthread. */ PFS_thread_class *klass= find_thread_class(typed_arg->m_child_key); if (likely(klass != NULL)) { pfs= create_thread(klass, typed_arg->m_child_identity, 0); if (likely(pfs != NULL)) { pfs->m_thread_os_id= my_thread_os_id(); clear_thread_account(pfs); pfs->m_parent_thread_internal_id= typed_arg->m_thread_internal_id; memcpy(pfs->m_username, typed_arg->m_username, sizeof(pfs->m_username)); pfs->m_username_length= typed_arg->m_username_length; memcpy(pfs->m_hostname, typed_arg->m_hostname, sizeof(pfs->m_hostname)); pfs->m_hostname_length= typed_arg->m_hostname_length; set_thread_account(pfs); } } else { pfs= NULL; } std::cout m_user_start_routine; user_arg= typed_arg->m_user_arg; my_free(typed_arg); /* Then, execute the user code for this thread. */ (*user_start_routine)(user_arg); return NULL; }
代码改动
由于开发原因,我加入了一个boost线程池,那么从原始线程产生任务塞入boost线程池中的时候,需要做类似的操作,即要传入一个
psi_arg参数。因为PSI是performance schema,所以其本身对执行并没有影响,我们可以把子线程的PSI设置为NULL。在psi.h中,我们可以看到:
/** Instrumented thread key. To instrument a thread, a thread key must be obtained using @c register_thread. Using a zero key always disable the instrumentation. */ typedef unsigned int PSI_thread_key;
获取当前的pfs:
/** Implementation of the thread instrumentation interface. @sa PSI_v1::get_thread_id. */ PSI_thread* pfs_get_thread_v1(void) { PFS_thread *pfs= my_thread_get_THR_PFS(); return reinterpret_cast(pfs); }
注意,不能直接用my_thread_get_THR_PFS()获取,因为其为static函数,只能用于本文件使用。同理设置pfs:
/** Implementation of the thread instrumentation interface. @sa PSI_v1::set_thread. */ void pfs_set_thread_v1(PSI_thread* thread) { PFS_thread *pfs= reinterpret_cast(thread); my_thread_set_THR_PFS(pfs); std::cout
附录:
定义的PSI结构(psi.h):
/** Performance Schema Interface, version 1. @since PSI_VERSION_1 */ struct PSI_v1 { /** @sa register_mutex_v1_t. */ register_mutex_v1_t register_mutex; /** @sa register_rwlock_v1_t. */ register_rwlock_v1_t register_rwlock; /** @sa register_cond_v1_t. */ register_cond_v1_t register_cond; /** @sa register_thread_v1_t. */ register_thread_v1_t register_thread; /** @sa register_file_v1_t. */ register_file_v1_t register_file; /** @sa register_stage_v1_t. */ register_stage_v1_t register_stage; /** @sa register_statement_v1_t. */ register_statement_v1_t register_statement; /** @sa register_socket_v1_t. */ register_socket_v1_t register_socket; /** @sa init_mutex_v1_t. */ init_mutex_v1_t init_mutex; /** @sa destroy_mutex_v1_t. */ destroy_mutex_v1_t destroy_mutex; /** @sa init_rwlock_v1_t. */ init_rwlock_v1_t init_rwlock; /** @sa destroy_rwlock_v1_t. */ destroy_rwlock_v1_t destroy_rwlock; /** @sa init_cond_v1_t. */ init_cond_v1_t init_cond; /** @sa destroy_cond_v1_t. */ destroy_cond_v1_t destroy_cond; /** @sa init_socket_v1_t. */ init_socket_v1_t init_socket; /** @sa destroy_socket_v1_t. */ destroy_socket_v1_t destroy_socket; /** @sa get_table_share_v1_t. */ get_table_share_v1_t get_table_share; /** @sa release_table_share_v1_t. */ release_table_share_v1_t release_table_share; /** @sa drop_table_share_v1_t. */ drop_table_share_v1_t drop_table_share; /** @sa open_table_v1_t. */ open_table_v1_t open_table; /** @sa unbind_table_v1_t. */ unbind_table_v1_t unbind_table; /** @sa rebind_table_v1_t. */ rebind_table_v1_t rebind_table; /** @sa close_table_v1_t. */ close_table_v1_t close_table; /** @sa create_file_v1_t. */ create_file_v1_t create_file; /** @sa spawn_thread_v1_t. */ spawn_thread_v1_t spawn_thread; /** @sa new_thread_v1_t. */ new_thread_v1_t new_thread; /** @sa set_thread_id_v1_t. */ set_thread_id_v1_t set_thread_id; /** @sa set_thread_THD_v1_t. */ set_thread_THD_v1_t set_thread_THD; /** @sa set_thread_os_id_v1_t. */ set_thread_os_id_v1_t set_thread_os_id; /** @sa get_thread_v1_t. */ get_thread_v1_t get_thread; /** @sa set_thread_user_v1_t. */ set_thread_user_v1_t set_thread_user; /** @sa set_thread_account_v1_t. */ set_thread_account_v1_t set_thread_account; /** @sa set_thread_db_v1_t. */ set_thread_db_v1_t set_thread_db; /** @sa set_thread_command_v1_t. */ set_thread_command_v1_t set_thread_command; /** @sa set_connection_type_v1_t. */ set_connection_type_v1_t set_connection_type; /** @sa set_thread_start_time_v1_t. */ set_thread_start_time_v1_t set_thread_start_time; /** @sa set_thread_state_v1_t. */ set_thread_state_v1_t set_thread_state; /** @sa set_thread_info_v1_t. */ set_thread_info_v1_t set_thread_info; /** @sa set_thread_v1_t. */ set_thread_v1_t set_thread; /** @sa delete_current_thread_v1_t. */ delete_current_thread_v1_t delete_current_thread; /** @sa delete_thread_v1_t. */ delete_thread_v1_t delete_thread; /** @sa get_thread_file_name_locker_v1_t. */ get_thread_file_name_locker_v1_t get_thread_file_name_locker; /** @sa get_thread_file_stream_locker_v1_t. */ get_thread_file_stream_locker_v1_t get_thread_file_stream_locker; /** @sa get_thread_file_descriptor_locker_v1_t. */ get_thread_file_descriptor_locker_v1_t get_thread_file_descriptor_locker; /** @sa unlock_mutex_v1_t. */ unlock_mutex_v1_t unlock_mutex; /** @sa unlock_rwlock_v1_t. */ unlock_rwlock_v1_t unlock_rwlock; /** @sa signal_cond_v1_t. */ signal_cond_v1_t signal_cond; /** @sa broadcast_cond_v1_t. */ broadcast_cond_v1_t broadcast_cond; /** @sa start_idle_wait_v1_t. */ start_idle_wait_v1_t start_idle_wait; /** @sa end_idle_wait_v1_t. */ end_idle_wait_v1_t end_idle_wait; /** @sa start_mutex_wait_v1_t. */ start_mutex_wait_v1_t start_mutex_wait; /** @sa end_mutex_wait_v1_t. */ end_mutex_wait_v1_t end_mutex_wait; /** @sa start_rwlock_rdwait_v1_t. */ start_rwlock_rdwait_v1_t start_rwlock_rdwait; /** @sa end_rwlock_rdwait_v1_t. */ end_rwlock_rdwait_v1_t end_rwlock_rdwait; /** @sa start_rwlock_wrwait_v1_t. */ start_rwlock_wrwait_v1_t start_rwlock_wrwait; /** @sa end_rwlock_wrwait_v1_t. */ end_rwlock_wrwait_v1_t end_rwlock_wrwait; /** @sa start_cond_wait_v1_t. */ start_cond_wait_v1_t start_cond_wait; /** @sa end_cond_wait_v1_t. */ end_cond_wait_v1_t end_cond_wait; /** @sa start_table_io_wait_v1_t. */ start_table_io_wait_v1_t start_table_io_wait; /** @sa end_table_io_wait_v1_t. */ end_table_io_wait_v1_t end_table_io_wait; /** @sa start_table_lock_wait_v1_t. */ start_table_lock_wait_v1_t start_table_lock_wait; /** @sa end_table_lock_wait_v1_t. */ end_table_lock_wait_v1_t end_table_lock_wait; /** @sa start_file_open_wait_v1_t. */ start_file_open_wait_v1_t start_file_open_wait; /** @sa end_file_open_wait_v1_t. */ end_file_open_wait_v1_t end_file_open_wait; /** @sa end_file_open_wait_and_bind_to_descriptor_v1_t. */ end_file_open_wait_and_bind_to_descriptor_v1_t end_file_open_wait_and_bind_to_descriptor; /** @sa end_temp_file_open_wait_and_bind_to_descriptor_v1_t. */ end_temp_file_open_wait_and_bind_to_descriptor_v1_t end_temp_file_open_wait_and_bind_to_descriptor; /** @sa start_file_wait_v1_t. */ start_file_wait_v1_t start_file_wait; /** @sa end_file_wait_v1_t. */ end_file_wait_v1_t end_file_wait; /** @sa start_file_close_wait_v1_t. */ start_file_close_wait_v1_t start_file_close_wait; /** @sa end_file_close_wait_v1_t. */ end_file_close_wait_v1_t end_file_close_wait; /** @sa start_stage_v1_t. */ start_stage_v1_t start_stage; /** @sa get_current_stage_progress_v1_t. */ get_current_stage_progress_v1_t get_current_stage_progress; /** @sa end_stage_v1_t. */ end_stage_v1_t end_stage; /** @sa get_thread_statement_locker_v1_t. */ get_thread_statement_locker_v1_t get_thread_statement_locker; /** @sa refine_statement_v1_t. */ refine_statement_v1_t refine_statement; /** @sa start_statement_v1_t. */ start_statement_v1_t start_statement; /** @sa set_statement_text_v1_t. */ set_statement_text_v1_t set_statement_text; /** @sa set_statement_lock_time_t. */ set_statement_lock_time_t set_statement_lock_time; /** @sa set_statement_rows_sent_t. */ set_statement_rows_sent_t set_statement_rows_sent; /** @sa set_statement_rows_examined_t. */ set_statement_rows_examined_t set_statement_rows_examined; /** @sa inc_statement_created_tmp_disk_tables. */ inc_statement_created_tmp_disk_tables_t inc_statement_created_tmp_disk_tables; /** @sa inc_statement_created_tmp_tables. */ inc_statement_created_tmp_tables_t inc_statement_created_tmp_tables; /** @sa inc_statement_select_full_join. */ inc_statement_select_full_join_t inc_statement_select_full_join; /** @sa inc_statement_select_full_range_join. */ inc_statement_select_full_range_join_t inc_statement_select_full_range_join; /** @sa inc_statement_select_range. */ inc_statement_select_range_t inc_statement_select_range; /** @sa inc_statement_select_range_check. */ inc_statement_select_range_check_t inc_statement_select_range_check; /** @sa inc_statement_select_scan. */ inc_statement_select_scan_t inc_statement_select_scan; /** @sa inc_statement_sort_merge_passes. */ inc_statement_sort_merge_passes_t inc_statement_sort_merge_passes; /** @sa inc_statement_sort_range. */ inc_statement_sort_range_t inc_statement_sort_range; /** @sa inc_statement_sort_rows. */ inc_statement_sort_rows_t inc_statement_sort_rows; /** @sa inc_statement_sort_scan. */ inc_statement_sort_scan_t inc_statement_sort_scan; /** @sa set_statement_no_index_used. */ set_statement_no_index_used_t set_statement_no_index_used; /** @sa set_statement_no_good_index_used. */ set_statement_no_good_index_used_t set_statement_no_good_index_used; /** @sa end_statement_v1_t. */ end_statement_v1_t end_statement; /** @sa get_thread_transaction_locker_v1_t. */ get_thread_transaction_locker_v1_t get_thread_transaction_locker; /** @sa start_transaction_v1_t. */ start_transaction_v1_t start_transaction; /** @sa set_transaction_xid_v1_t. */ set_transaction_xid_v1_t set_transaction_xid; /** @sa set_transaction_xa_state_v1_t. */ set_transaction_xa_state_v1_t set_transaction_xa_state; /** @sa set_transaction_gtid_v1_t. */ set_transaction_gtid_v1_t set_transaction_gtid; /** @sa set_transaction_trxid_v1_t. */ set_transaction_trxid_v1_t set_transaction_trxid; /** @sa inc_transaction_savepoints_v1_t. */ inc_transaction_savepoints_v1_t inc_transaction_savepoints; /** @sa inc_transaction_rollback_to_savepoint_v1_t. */ inc_transaction_rollback_to_savepoint_v1_t inc_transaction_rollback_to_savepoint; /** @sa inc_transaction_release_savepoint_v1_t. */ inc_transaction_release_savepoint_v1_t inc_transaction_release_savepoint; /** @sa end_transaction_v1_t. */ end_transaction_v1_t end_transaction; /** @sa start_socket_wait_v1_t. */ start_socket_wait_v1_t start_socket_wait; /** @sa end_socket_wait_v1_t. */ end_socket_wait_v1_t end_socket_wait; /** @sa set_socket_state_v1_t. */ set_socket_state_v1_t set_socket_state; /** @sa set_socket_info_v1_t. */ set_socket_info_v1_t set_socket_info; /** @sa set_socket_thread_owner_v1_t. */ set_socket_thread_owner_v1_t set_socket_thread_owner; /** @sa create_prepared_stmt_v1_t. */ create_prepared_stmt_v1_t create_prepared_stmt; /** @sa destroy_prepared_stmt_v1_t. */ destroy_prepared_stmt_v1_t destroy_prepared_stmt; /** @sa reprepare_prepared_stmt_v1_t. */ reprepare_prepared_stmt_v1_t reprepare_prepared_stmt; /** @sa execute_prepared_stmt_v1_t. */ execute_prepared_stmt_v1_t execute_prepared_stmt; /** @sa digest_start_v1_t. */ digest_start_v1_t digest_start; /** @sa digest_end_v1_t. */ digest_end_v1_t digest_end; /** @sa set_thread_connect_attrs_v1_t. */ set_thread_connect_attrs_v1_t set_thread_connect_attrs; /** @sa start_sp_v1_t. */ start_sp_v1_t start_sp; /** @sa start_sp_v1_t. */ end_sp_v1_t end_sp; /** @sa drop_sp_v1_t. */ drop_sp_v1_t drop_sp; /** @sa get_sp_share_v1_t. */ get_sp_share_v1_t get_sp_share; /** @sa release_sp_share_v1_t. */ release_sp_share_v1_t release_sp_share; /** @sa register_memory_v1_t. */ register_memory_v1_t register_memory; /** @sa memory_alloc_v1_t. */ memory_alloc_v1_t memory_alloc; /** @sa memory_realloc_v1_t. */ memory_realloc_v1_t memory_realloc; /** @sa memory_claim_v1_t. */ memory_claim_v1_t memory_claim; /** @sa memory_free_v1_t. */ memory_free_v1_t memory_free; unlock_table_v1_t unlock_table; create_metadata_lock_v1_t create_metadata_lock; set_metadata_lock_status_v1_t set_metadata_lock_status; destroy_metadata_lock_v1_t destroy_metadata_lock; start_metadata_wait_v1_t start_metadata_wait; end_metadata_wait_v1_t end_metadata_wait; };
该结构在
psi.cc被赋值:
/** Implementation of the instrumentation interface. @sa PSI_v1. */ PSI_v1 PFS_v1= { pfs_register_mutex_v1, pfs_register_rwlock_v1, pfs_register_cond_v1, pfs_register_thread_v1, pfs_register_file_v1, pfs_register_stage_v1, pfs_register_statement_v1, pfs_register_socket_v1, pfs_init_mutex_v1, pfs_destroy_mutex_v1, pfs_init_rwlock_v1, pfs_destroy_rwlock_v1, pfs_init_cond_v1, pfs_destroy_cond_v1, pfs_init_socket_v1, pfs_destroy_socket_v1, pfs_get_table_share_v1, pfs_release_table_share_v1, pfs_drop_table_share_v1, pfs_open_table_v1, pfs_unbind_table_v1, pfs_rebind_table_v1, pfs_close_table_v1, pfs_create_file_v1, pfs_spawn_thread_v1, pfs_new_thread_v1, pfs_set_thread_id_v1, pfs_set_thread_THD_v1, pfs_set_thread_os_id_v1, pfs_get_thread_v1, pfs_set_thread_user_v1, pfs_set_thread_account_v1, pfs_set_thread_db_v1, pfs_set_thread_command_v1, pfs_set_connection_type_v1, pfs_set_thread_start_time_v1, pfs_set_thread_state_v1, pfs_set_thread_info_v1, pfs_set_thread_v1, pfs_delete_current_thread_v1, pfs_delete_thread_v1, pfs_get_thread_file_name_locker_v1, pfs_get_thread_file_stream_locker_v1, pfs_get_thread_file_descriptor_locker_v1, pfs_unlock_mutex_v1, pfs_unlock_rwlock_v1, pfs_signal_cond_v1, pfs_broadcast_cond_v1, pfs_start_idle_wait_v1, pfs_end_idle_wait_v1, pfs_start_mutex_wait_v1, pfs_end_mutex_wait_v1, pfs_start_rwlock_rdwait_v1, pfs_end_rwlock_rdwait_v1, pfs_start_rwlock_wrwait_v1, pfs_end_rwlock_wrwait_v1, pfs_start_cond_wait_v1, pfs_end_cond_wait_v1, pfs_start_table_io_wait_v1, pfs_end_table_io_wait_v1, pfs_start_table_lock_wait_v1, pfs_end_table_lock_wait_v1, pfs_start_file_open_wait_v1, pfs_end_file_open_wait_v1, pfs_end_file_open_wait_and_bind_to_descriptor_v1, pfs_end_temp_file_open_wait_and_bind_to_descriptor_v1, pfs_start_file_wait_v1, pfs_end_file_wait_v1, pfs_start_file_close_wait_v1, pfs_end_file_close_wait_v1, pfs_start_stage_v1, pfs_get_current_stage_progress_v1, pfs_end_stage_v1, pfs_get_thread_statement_locker_v1, pfs_refine_statement_v1, pfs_start_statement_v1, pfs_set_statement_text_v1, pfs_set_statement_lock_time_v1, pfs_set_statement_rows_sent_v1, pfs_set_statement_rows_examined_v1, pfs_inc_statement_created_tmp_disk_tables_v1, pfs_inc_statement_created_tmp_tables_v1, pfs_inc_statement_select_full_join_v1, pfs_inc_statement_select_full_range_join_v1, pfs_inc_statement_select_range_v1, pfs_inc_statement_select_range_check_v1, pfs_inc_statement_select_scan_v1, pfs_inc_statement_sort_merge_passes_v1, pfs_inc_statement_sort_range_v1, pfs_inc_statement_sort_rows_v1, pfs_inc_statement_sort_scan_v1, pfs_set_statement_no_index_used_v1, pfs_set_statement_no_good_index_used_v1, pfs_end_statement_v1, pfs_get_thread_transaction_locker_v1, pfs_start_transaction_v1, pfs_set_transaction_xid_v1, pfs_set_transaction_xa_state_v1, pfs_set_transaction_gtid_v1, pfs_set_transaction_trxid_v1, pfs_inc_transaction_savepoints_v1, pfs_inc_transaction_rollback_to_savepoint_v1, pfs_inc_transaction_release_savepoint_v1, pfs_end_transaction_v1, pfs_start_socket_wait_v1, pfs_end_socket_wait_v1, pfs_set_socket_state_v1, pfs_set_socket_info_v1, pfs_set_socket_thread_owner_v1, pfs_create_prepared_stmt_v1, pfs_destroy_prepared_stmt_v1, pfs_reprepare_prepared_stmt_v1, pfs_execute_prepared_stmt_v1, pfs_digest_start_v1, pfs_digest_end_v1, pfs_set_thread_connect_attrs_v1, pfs_start_sp_v1, pfs_end_sp_v1, pfs_drop_sp_v1, pfs_get_sp_share_v1, pfs_release_sp_share_v1, pfs_register_memory_v1, pfs_memory_alloc_v1, pfs_memory_realloc_v1, pfs_memory_claim_v1, pfs_memory_free_v1, pfs_unlock_table_v1, pfs_create_metadata_lock_v1, pfs_set_metadata_lock_status_v1, pfs_destroy_metadata_lock_v1, pfs_start_metadata_wait_v1, pfs_end_metadata_wait_v1 };
每一个值都是一个函数。感兴趣的可以去看对应实现。
今天关于《MySQL内核技术之"线程操作"》的内容就介绍到这里了,是不是学起来一目了然!想要了解更多关于mysql的内容请关注golang学习网公众号!
声明:本文转载于:SegmentFault 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
-
499 收藏
-
244 收藏
-
235 收藏
-
157 收藏
-
101 收藏
最新阅读
更多>
-
481 收藏
-
284 收藏
-
316 收藏
-
437 收藏
-
412 收藏
-
364 收藏
课程推荐
更多>
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 507次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 484次学习