招银网科面试题汇总part1

招银网科面试题汇总part1

  • 1. C++声明变量是放在什么位置?
  • 2. 全局变量、静态变量、静态全局变量、静态局部变量的区别
  • 3. C++的源文件是怎么样一步步编译为可执行文件的?
  • 4. 进程死锁是什么?
  • 5. 深拷贝与浅拷贝的区别
  • 6. 数组和链表的区别
  • 7. 指针和引用的区别
  • 8. 指针传递参数和引用传递参数的不同
  • 9. new和malloc的区别
  • 10. 排序算法比较

1. C++声明变量是放在什么位置?

“声明”:意味着告诉编译器关于变量名称、变量类型、变量大小、函数名称、结构名称、大小等等信息,并且在声明阶段不会给变量分配任何的内存。

“定义”:定义就是在变量声明后,给它分配上内存。可以看成“定义 = 声明 + 内存分配”。

在C++中,内存分为5个区:堆、栈、自由存储区、全局/静态存储区、常量存储区

栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清除的变量的存储区。里面的变量通常是局部变量、函数参数等。

堆,就是那些由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete。如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。

自由存储区,就是那些由malloc等分配的内存块,他和堆是十分相似的,不过它是用free来结束自己的生命的。

全局/静态存储区,全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,在C++里面没有这个区分了,他们共同占用同一块内存区。

常量存储区,这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改。

2. 全局变量、静态变量、静态全局变量、静态局部变量的区别

C++ 变量根据定义的位置的不同的生命周期,具有不同的作用域,作用域可分为 6 种:全局作用域,局部作用域,语句作用域,类作用域,命名空间作用域和文件作用域。

1)全局变量具有全局作用域。全局变量只需在一个源文件中定义,就可以作用于所有的源文件。当然,其他不包含全局变量定义的源文件需要用extern 关键字再次声明这个全局变量。

2)静态局部变量具有局部作用域,它只被初始化一次,自从第一次被初始化直到程序运行结束都一直存在,它和全局变量的区别在于全局变量对所有的函数都是可见的,而静态局部变量只对定义自己的函数体始终可见。

3)局部变量也只有局部作用域,它是自动对象(auto),它在程序运行期间不是一直存在,而是只在函数执行期间存在,函数的一次调用执行结束后,变量被撤销,其所占用的内存也被收回。

4)静态全局变量也具有全局作用域,它与全局变量的区别在于如果程序包含多个文件的话,它作用于定义它的文件里,不能作用到其它文件里,即被static关键字修饰过的变量具有文件作用域。这样即使两个不同的源文件都定义了相同名字的静态全局变量,它们也是不同的变量。

全局变量,静态局部变量,静态全局变量都在静态存储区分配空间,而局部变量在栈里分配空间。

静态变量会被放在程序的静态数据存储区(数据段)(全局可见)中,这样可以在下一次调用的时候还可以保持原来的赋值。这一点是它与堆栈变量和堆变量的区别。

变量用static告知编译器,自己仅仅在变量的作用范围内可见。这一点是它与全局变量的区别。

把局部变量改变为静态局部变量后,是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。因此static 这个说明符在不同的地方所起的作用是不同的。

3. C++的源文件是怎么样一步步编译为可执行文件的?

1)预处理:预处理的过程主要处理那些源代码文件中只能够以“#”开始的预处理指令。

2)编译:编译就是将预处理的文件进行一系列的词法分析,语法分析,语义分析,以及优化后产生相应的汇编代码文件。

3)汇编:汇编过程实际上指把汇编语言代码翻译成目标机器指令的过程,即生成目标文件。

4)链接:链接就是把每个源代码独立的编译,然后按照它们的要求将它们组装起来,链接主要解决的是源代码之间的相互依赖问题。

静态链接:在链接阶段,会将汇编生成的目标文件.o与引用到的库一起链接打包到可执行文件中,因此对应的链接方式称为静态链接。静态库的缺点在于:浪费空间和资源,因为所有相关的目标文件与牵涉到的函数库被链接合成一个可执行文件。

动态链接:动态库在程序编译时并不会被连接到目标代码中,而是在程序运行时才被载入。不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例,规避了空间浪费问题。动态库在程序运行是才被载入,也解决了静态库对程序的更新、部署和发布页会带来麻烦。用户只需要更新动态库即可,增量更新。

4. 进程死锁是什么?

死锁问题被认为是线程/进程间切换消耗系统性能的一种极端情况。在死锁时,线程/进程间相互等待资源,而又不释放自身的资源,导致无穷无尽的等待,其结果是任务永远无法执行完成。

打个比方,假设有P1和P2两个进程,都需要A和B两个资源,现在P1持有A等待B资源,而P2持有B等待A资源,两个都等待另一个资源而不肯释放资源,就这样无限等待中,这就形成死锁,这也是死锁的一种情况。给死锁下个定义,如果一组进程中每一个进程都在等待仅由该组进程中的其他进程才能引发的事件,那么该组进程是死锁的。

当然死锁的产生是必须要满足一些特定条件的:
  1.互斥条件:某资源只能被一个进程使用,其他进程请求该资源时,只能等待,知道资源使用完毕后释放资源。
  2.请求和保持条件:程序已经保持了至少一个资源,但是又提出了新要求,而这个资源被其他进程占用,自己占用资源却保持不放。
  3.不剥夺条件:任何一个资源在没被该进程释放之前,任何其他进程都无法对他剥夺占用
  4.循环等待条件:当发生死锁时,所等待的进程必定会形成一个环路(类似于死循环),造成永久阻塞。

5. 深拷贝与浅拷贝的区别

浅拷贝只是对指针的拷贝,拷贝后两个指针指向同一个内存空间,深拷贝不但对指针进行拷贝,而且对指针指向的内容进行拷贝,经深拷贝后的指针是指向两个不同地址的指针。

class Student
{
private:int num;char *name;
public:Student();~Student();
};
Student::Student()
{name = new char(20);cout << "Student" << endl;
}
Student::~Student()
{cout << "~Student " << (int)name << endl;delete name;name = NULL;
}
int main()
{{// 花括号让s1和s2变成局部对象,方便测试Student s1;Student s2(s1);// 复制对象}system("pause");return 0;
}

执行结果:调用一次构造函数,调用两次析构函数,两个对象的指针成员所指内存相同,这会导致什么问题呢?name指针被分配一次内存,但是程序结束时该内存却被释放了两次,会导致崩溃!
加入语句

Student::Student(const Student &s)
{name = new char(20);memcpy(name, s.name, strlen(s.name));cout << "copy Student" << endl;
} //拷贝构造函数,const防止对象被改变

执行结果:调用一次构造函数,一次自定义拷贝构造函数,两次析构函数。两个对象的指针成员所指内存不同。
总结:浅拷贝只是对指针的拷贝,拷贝后两个指针指向同一个内存空间,深拷贝不但对指针进行拷贝,而且对指针指向的内容进行拷贝,经深拷贝后的指针是指向两个不同地址的指针。
当对象中存在指针成员时,除了在复制对象时需要考虑自定义拷贝构造函数,还应该考虑以下两种情形:
1.当函数的参数为对象时,实参传递给形参的实际上是实参的一个拷贝对象,系统自动通过拷贝构造函数实现;
2.当函数的返回值为一个对象时,该对象实际上是函数内对象的一个拷贝,用于返回函数调用处。3.浅拷贝带来问题的本质在于析构函数释放多次堆内存,使用std::shared_ptr,可以完美解决这个问题。

6. 数组和链表的区别

数组在分配内存的时候是一块连续的空间,并且每个元素的内存是一样的,因此可以用下标快速访问;但正因为如此,在其中插入或者删除的操作就比较麻烦,要移动别的元素的位置,因此需要快速访问存取并且不频繁增删就用数组。

链表的每个元素使用指针相互链接,分配的空间比较自由,每个元素可以不同类型不同大小,但是访问就必须链式线扫且没有下标,插入删除比较方便,只用替换和删除指针即可,适合频繁增删的操作需求。

7. 指针和引用的区别

  1. 引用必须被初始化,但是不分配存储空间。指针不声明时初始化,在初始化的时候需要分配存储空间。
  2. 引用初始化后不能被改变,指针可以改变所指的对象。
    引用“从一而终”,指针可以“见异思迁”。引用没有const,指针有const,const的指针不可变。
  3. 不存在指向空值的引用,但是存在指向空值的指针。
  4. sizeof 引用得到的是所指向的变量(对象)的大小,而sizeof 指针得到的是指针本身的大小.
  5. 自增运算不同
  6. 引用是类型安全的,而指针不是 (引用比指针多了类型检查)

8. 指针传递参数和引用传递参数的不同

  1. 指针传递参数本质上是值传递的方式,它所传递的是一个地址值。值传递过程中,被调函数的形式参数作为被调函数的局部变量处理,即在栈中开辟了内存空间以存放由主调函数放进来的 实参的值,从而成为了实参的一个副本。值传递的特点是被调函数对形式参数的任何操作都是作为局部变量进行,不会影响主调函数的实参变量的值。
  2. 而在引用传递过程中, 被调函数的形式参数虽然也作为局部变量在栈中开辟了内存空间,但是这时存放的是由主调函数放进来的实参变量的地址。被调函数对形参的任何操作都被处理成间 接寻址,即通过栈中存放的地址访问主调函数中的实参变量。正因为如此,被调函数对形参做的任何操作都影响了主调函数中的实参变量。
  3. 引用传递和指针传递是不同的,虽然它们都是在被调函数栈空间上的一个局部变量,但是任何对于引用参数的处理都会通过一个间接寻址的方式操作到主调函数中的相关变量。而对于指针传递的参数,如果改变被调函数中的指针地址,它将影响不到主调函数的相关变量。如果想通过指针参数传递来改变主调函数中的相关变量,那就得使用指向指针的指针,或者指针引用。
    程序在编译时分别将指针和引用添加到符号表上,符号表上记录的是变量名及变量所对应地址。指针变量在符号表上对应的地址值为指针变量的地址值,而引用在符号表上对应的地址值为 引用对象的地址值。符号表生成后就不会再改,因此指针可以改变其指向的对象(指针变量中的值可以改),而引用对象则不能修改。

9. new和malloc的区别

  1. new和delete是C++关键字,需要编译器支持;malloc和free是库函数,需要头文件支持。
  2. 使用new操作符申请内存分配时无须指定内存块的大小,编译器会根据类型信息自行计算。而malloc则需要显式地指出所需内存的尺寸。
A * ptr = new A;
A * ptr = (A *)malloc(sizeof(A)); //需要显式指定所需内存大小sizeof(A);
  1. new操作符内存分配成功时,返回的是对象类型的指针,类型严格与对象匹配,无须进行类型转换,故new是符合类型安全性的操作符。而malloc内存分配成功则是返回void * ,需要通过强制类型转换将void*指针转换成我们需要的类型。
  2. C++允许重载new/delete操作符,malloc不允许重载。
  3. new操作符从自由存储区(free store)上为对象动态分配内存空间,而malloc函数从堆上动态分配内存。自由存储区是C++基于new操作符的一个抽象概念,凡是通过new操作符进行内存申请,该内存即为自由存储区。而堆是操作系统中的术语,是操作系统所维护的一块特殊内存,用于程序的内存动态分配,C语言使用malloc从堆上分配内存,使用free释放已分配的对应内存。
    在这里插入图片描述

10. 排序算法比较

排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。

当n较大,则应采用时间复杂度为O(nlog2n)的排序方法:快速排序、堆排序或归并排序。快速排序是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短;

冒泡排序、插入排序、归并排序、计数排序、桶排序、基数排序是稳定的。
在这里插入图片描述
冒泡排序:
1、对数组array[n]进行从0n-1项的扫描,每碰到相邻两项数值大的在前小的在后时,对二者进行交换。当扫描进行完成后,0n-1中最大的元素必然已经在array[n-1]就位,而所有数值较小,序号却靠后的元素,序号也减小了1。
2、既然最大的元素已在array[n-1]的位置就位,接下来的扫描只需从0n-2。具体过程同1。同样的,扫描结束后0n-2中最大的元素(全数组第二大的元素)必然已经在array[n-2]就位,而所有数值较小,序号却靠后的元素,序号也减小了1。
3、如此不断重复,直到最小的元素在array[0]的位置就位。
从上述描述中我们可以看到“冒泡排序”这个名字的由来:每一次扫描,都可以使得数值较小,序号却靠后的元素的序号减少1,宏观来看这些元素就像是从数组底部向上慢慢上浮的泡泡。

void BubbleSort(int a[],long size)
{for(long i=0;i<size;i++){bool flag=true;for(long j=0;j<size-i-1;j++){if(a[j]>a[j+1]){swap(a[j+1],a[j]);flag=false;}}if(true==flag)return;}
}

插入排序:
插入排序和人们打牌时所用的排序方式类似:
1、抽第一张牌,此时手上的牌只有一张,所以是有序的。
2、再抽一张牌,和手上的那张牌的大小进行比较,比它大就放在后面,否则放在前面。
3、再抽一张牌,和手上的牌进行比较,插入在合适的位置,保持手上的牌有序。
4、不断重复3,直到牌抽完。
从宏观来看,插入排序把数组分割成两部分,前段有序后段无序,随着插入排序的进行,后段无序的牌也越来越少,直到后段全部融入前段,排序也就结束了。

void InsertSort(int arr[],long size)
{for(int i=1;i<size;i++){int temp=arr[i];int j=i-1;while(j>=0){if(arr[j]>temp)arr[j+1]=arr[j];else break;j--;}arr[j+1]=temp;}
}

选择排序:
1、从数组中找出最小的元素,找出来后,将其和数组首元素互换位置。
2、此时待排序的数组规模-1。对这个规模减小的数组进行步骤1、直到待排序的数组规模为0。

void SelectSort(int arr[],long size)
{for(long i=size-1;i>=0;i--){int maxnum=arr[i];long rank=i;for(long j=0;j<i;j++){if(arr[j]>=maxnum){maxnum=arr[j];rank=j;}}swap(arr[rank], arr[i]);}
}

快速排序:
1、从数组中随机选出一个元素,和数组首元素互换位置,并记下其大小。
2、使用两个指针,指针a指向数组头,指针b指向数组尾。
3、指针b从后向前扫描,找到一个数比选出元素小时,暂停,将其值保存在指针a所指的位置中。
4、指针a从前往后扫描,找到一个数比选出元素大时,暂停,将其值保存在指针b所指的位置中。
5、循环重复3、4,直到a<b不再成立。
6、将选出元素放在指针a、b同时指向的位置,并用此位置将数组分割成前后不包含选出元素的两个子数组,对子数组进行步骤1~6。

void QuickSort(int arr[],long lo,long hi)
{if(hi-lo<2)return;long rank=rand()%(hi-lo)+lo,ranklo=lo,rankhi=hi;swap(arr[ranklo],arr[rank]);int key=arr[lo];hi--;while(lo<hi){while(lo<hi&&key<=arr[hi])hi--;arr[lo]=arr[hi];while(lo<hi&&arr[lo]<=key)lo++;arr[hi]=arr[lo];}arr[lo]=key;QuickSort(arr, ranklo,lo);QuickSort(arr, lo+1,rankhi);
}

归并排序:
归并排序的操作有两步,分割和归并.
1、分割:将数组二等分,并将得到的子数组继续二等分,直到每个子数组只剩下一个元素为止。
2、归并:不断将原本属于同一个数组的两个子数组归并成一个有序的数组,方法为不断比较子数组的首元素,并弹出较小的放入合并后组成的数组中。直到所有子数组合并为一个数组。

void MergeSort(int arr[],long lo,long hi)
{if(hi-lo<2)return;long mi=(lo+hi)/2;MergeSort(arr,lo, mi);MergeSort(arr,mi, hi);Merge(arr,lo,mi,hi);
}
void Merge(int arr[],long lo,long mi,long hi)
{long ml=mi-lo;int *b=new int[ml];for(long i=0;i<ml;i++)b[i]=arr[lo+i];//print(b, ml);long x=0,y=mi;for(long i=lo;i<hi;){if((b[x]<=arr[y]&&x<ml)||y>=hi){arr[i++]=b[x++];}if((arr[y]<b[x]&&y<hi)||x>=ml){arr[i++]=arr[y++];}}delete []b;
}

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

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

相关文章

【面试】面试官问的几率较大的网络安全面试题

文章目录 防范常见的 Web 攻击1、什么是SQL注入攻击2、什么是XSS攻击3、什么是CSRF攻击4、什么是文件上传漏洞5、DDos 攻击 重要协议分布图1、arp协议的工作原理ARP协议工作原理&#xff1a; 2、什么是RARP&#xff1f;工作原理3、dns是什么&#xff1f;dns的工作原理4、rip协议…

招银网络科技笔试面试

昨晚收到招银的面试通知&#xff0c;面试岗位&#xff1a;数据仓库。这两天准备下笔试、面试&#xff0c;网上搜了些资料&#xff0c;记录在这里&#xff1a; 一、上图所示数据库开发答案解析如下&#xff1a; --建表-------------------------------------------------------…

【面试大全】互联网面试软实力【必看】

软实力 推荐大家使用Markdown语法写简历,然后再将Markdown格式转换为PDF格式后进行简历投递。如果你对Markdown语法不太了解的话,可以花半个小时简单看一下Markdown语法说明: http://www.markdown.cn/ 面试 假如你是网络申请者【拉勾、boss等】,你的简历必然会经过HR的筛选,…

银行金融风险管理面试问题汇总(附答案)

最近有些学员在咨询换工作的事&#xff0c;包括一些金融上市公司的高管。我收集了一些金融风险管理面试问题相关资料&#xff0c;希望能帮助大家。记得收藏此文章&#xff0c;以防之后找不到文章。 风险经理识别和分析潜在的公司风险&#xff0c;并找到减少或避免风险的方法。…

招商银行面试问题20200416

招商银行面试&#xff1a; 如何保证MySQL和Redis的双写一致性&#xff1f; 只考虑以下三种更新策略&#xff1a; 先更新数据库&#xff0c;再更新缓存&#xff1a; 1 线程A更新了数据库 2 线程B更新了数据库 3 线程B更新了缓存 4 线程A更新了缓存 这本该请求A先更新缓存…

面试常考:C#用两个线程交替打印1-100的五种方法

"C#用两个线程交替打印1-100的五种方法"是.NET工程师面试多线程常考的试题之一&#xff0c;主要考察对C#语法和对多线程的熟悉程度。本文将用5种方法实现这个面试题。 方法1&#xff1a;使用Mutex或lock 这种方法涉及使用Mutex或lock对象来同步两个线程。其中一个线…

ChatGPT为什么火?|掀起热潮的对话革命|小智ai

ChatGPT丨小智ai丨chatgpt丨人工智能丨OpenAI丨聊天机器人丨AI语音助手丨GPT-3.5丨开源AI平台|人工智能巨头OpenAI开发的聊天机器人引发全球关注 近期&#xff0c;人工智能领域迎来了一股前所未有的热潮&#xff0c;而其中的主角正是由OpenAI开发的聊天机器人ChatGPT。作为一项…

数据分析案例-股票数据分析

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

图形化跟踪个股RPS走势,挖掘出源源不断的牛股!股票量化分析工具QTYX-V2.5.7...

概述RPS选股策略 威廉欧奈尔把投资理念集中于他自创的CANSLIM选股系统&#xff0c;凭借着这个系统驰骋股票市场数十年&#xff0c;无论在牛市还是熊市&#xff0c;这个系统都是最稳定、表现最好的系统之一。 CANSLIM选股系统中有一个RPS指标&#xff08;Relative Price Strengt…

【树莓派烹饪日记】#1 系统安装与环境配置

0 引言 这个系列用于记录入门树莓派期间踩的各种坑及解决办法。 只记录一些我觉得重要的地方&#xff0c;不一定很全面。 目前暂定的一个目标是拿树莓派接管小爱音箱并接入ChatGPT。 今天的计划是将一个新的树莓派主板 烧录并启动系统系统配置安装VPN安装conda环境 需要用到…

RWKV配上ChatGPTBox让我们在浏览器中感受AI带来的魅力

这次我们来讲讲RWKV搭配ChatGPTBox结合使用带来的功能体验&#xff0c;这两个项目都是同一个大神创建的&#xff0c;完全可以无缝搭配进行使用。 以下是我之前在本地部署了AI模型RWKV的教程&#xff0c;如果还没有本地部署过AI的童鞋可以查看我之前发布的教程&#xff0c;在自…

总结谷歌身份验证器 Google Authenticator 的详细使用方法

谷歌身份验证器Google Authenticator是谷歌推出的一款动态口令工具&#xff0c;解决大家各平台账户遭到恶意攻击的问题&#xff0c;一般在相关的服务平台登陆中除了用正常用户名和密码外&#xff0c;需要再输入一次谷歌认证器生成的动态口令才能验证成功&#xff0c;相当于输入…

快速接入Google两步认证Google Authenticator

(一)介绍 既然来看该文章就应该知道Google的两步认证是干什么的&#xff0c;这边再提供一次app的下载链接 (apkpure搜索谷歌身份验证器) 验证原理讲解&#xff1a; 在数据库中查找该登陆用户之前绑定的32位随机码&#xff08;该码一般会存入数据库&#xff09;调用API传入32位…

身份验证器 Authenticator 插件

1.插件支持浏览器 ChromeFirefoxEdge 2.关键特性 通过扫描二维码添加账号使用密码加密数据在浏览器之间同步数据备份数据到云服务或导出数据到文件智能过滤和搜索 官网地址: Authenticator Extension 官方说明文档&#xff1a;What is Authenticator Extension? | Authen…

前后端身份验证

1、web 开发模式 【】基于服务端渲染的传统 Web 开发模式 【】基于前后端分离的新型 Web 开发模式&#xff1a;依赖于 Ajax 技术的广泛应用。后端只负责提供 API 接口&#xff0c;前端使用 Ajax 调用接口的开发模式 2、身份认证 【】服务端渲染推荐使用 Session 认证机制 【】…

生信工作流框架搭建 | 04-nextflow与Slurm高性能计算

目录 生信工作流框架搭建 | 04-nextflow与Slurm高性能计算前情提要什么是HPC高性能计算什么是slurm nextflow配置注意事项下期预告 生信工作流框架搭建 | 04-nextflow与Slurm高性能计算 本篇为biodoge《生信工作流框架搭建》系列笔记的第5篇&#xff0c;该系列将持续更新。 前情…

评价基于GPT和Bert的方法并用于生信文本识别PPI

检测蛋白质-蛋白质相互作用&#xff08;PPI&#xff09;对于理解遗传机制、疾病发病机制和药物设计至关重要。然而&#xff0c;随着生物医学文献的快速增长&#xff0c;越来越需要自动和准确地提取PPI以促进科学知识发现。预训练语言模型&#xff0c;例如生成式预训练Transform…

Limma | 三个组的差异分析怎么分析做呢!?~

1写在前面 高考结束了&#xff0c;不知道各位考生考的怎么样&#xff0c;这种时候总是几家欢喜几家忧&#xff0c;但这也是实现阶级流动的最佳机会。&#x1f914; 回想自己高考过去10几年了&#xff0c;不能说学了医后悔吧&#xff0c;只能说后悔至极&#xff0c;苦不堪言啊&a…

生信分析案例 Python简明教程 | 视频13

开源生信 Python教程 生信专用简明 Python 文字和视频教程 源码在&#xff1a;https://github.com/Tong-Chen/Bioinfo_course_python 目录 背景介绍 编程开篇为什么学习Python如何安装Python如何运行Python命令和脚本使用什么编辑器写Python脚本Python程序事例Python基本语法 数…

生信分析案例 Python简明教程 | 视频12

开源生信 Python教程 生信专用简明 Python 文字和视频教程 源码在&#xff1a;https://github.com/Tong-Chen/Bioinfo_course_python 目录 背景介绍 编程开篇为什么学习Python如何安装Python如何运行Python命令和脚本使用什么编辑器写Python脚本Python程序事例Python基本语法 数…