AlphaFold2源码解析(3)--数据预处理

news2024/11/23 16:36:53

AlphaFold2源码解析(3)–数据预处理

数据预处理整体流程


数据处理入口:
feature_dict = data_pipeline.process( input_fasta_path=fasta_path,# 输入序列目录 msa_output_dir=msa_output_dir) # MSA序列目录 可能是单体也可能是多聚体

主要调动的API是:

  • 通过使用run_msa_tool()函数调用jackhmer和hhblits对输入的Fasta文件进行MSA搜索,输出的格式为sto;
  • template_searcher()使用去冗余后的MSA序列对pdb70数据库进行搜索,得到TemplateHits;
  • template_featurizer()使用kalign程序对Hits的序列与input序列进行比对,得到模板信息;
  • 最后通过make_*_features()函数对特征进一步处理,与融合得到alphafold所需的所有特征字典。

预处理工具

从上文我们知道,Alphafold需要与专家经验库进行交互,抽取MSA特征。这里用到了多个生物学工具:

  • openmm:用于分析模拟的高性能工具包,是 Omnia(预测生物分子模拟的工具套件)的一部分。
  • kalign:一款针对大规模基因组序列的多序列对比工具,运行速度与准确度都比较高。
  • jackhmmer:一款高效的蛋白质搜索工具,用于从序列数据库中,找到同源的序列。
  • pdbfixer:用于修复PDB数据,对其中蛋白质结构进行基本的准备或者修复。
  • HHsuite:一款蛋白质研究软件,快速搜索分析蛋白质的功能特性。

jackhmmer

ackhmmer针对seqdb中的目标序列迭代搜索seqfile中的每个查询序列。第一次迭代与phmmer搜索相同。对于下一次迭代,将查询的多重比对与满足包含阈值的所有目标序列组合在一起,从该比对构建配置文件(与在比对上使用hmmbuild相同),并完成seqdb的配置文件搜索(与带有配置文件的hmmsearch)。

查询seqfile可以是“-”(破折号),在这种情况下,查询序列是从标准输入管道而不是从文件中读取的。无法从标准输入流中读取 seqdb,因为jackhmmer需要对数据库进行多次传递。

输出格式被设计成人类可读的,但往往过于庞大以至于阅读起来不切实际,解析起来也很痛苦。–tblout和–domtblout选项以简洁且易于解析的简单表格格式保存输出。-o选项允许重定向主要输出,包括将其丢弃在 /dev/null 中。

参数详情可以参考:https://www.mankier.com/1/jackhmmer

在alphaFold2的代码路径
有几个数据库使用了jackhmmer来搜索MSA,如 uniref90、mgnify
./alphafold/data/tools/jackhmmer.py

def _query_chunk(self,
                   input_fasta_path: str,
                   database_path: str,
                   max_sequences: Optional[int] = None) -> Mapping[str, Any]:
    """Queries the database chunk using Jackhmmer."""
    with utils.tmpdir_manager() as query_tmp_dir:
      sto_path = os.path.join(query_tmp_dir, 'output.sto')

      # The F1/F2/F3 are the expected proportion to pass each of the filtering
      # stages (which get progressively more expensive), reducing these
      # speeds up the pipeline at the expensive of sensitivity.  They are
      # currently set very low to make querying Mgnify run in a reasonable
      # amount of time.
      cmd_flags = [
          # Don't pollute stdout with Jackhmmer output.
          '-o', '/dev/null', # https://www.mankier.com/1/jackhmmer  /dev/null 系统自带的不保存文件
          '-A', sto_path, # 在最终迭代之后,将所有命中的带注释的多个对齐方式保存满足包含阈值(还包括原始查询)的多个对齐,以<f>在Stockholm格式中。
          '--noali', # 在最终迭代之后,将所有命中的带注释的多个对齐方式保存满足包含阈值(还包括原始查询)的多个对齐,以<f>在Stockholm格式中。
          '--F1', str(self.filter_f1), # 第一个滤波器阈值;为MSV滤波器步骤设置P值阈值。默认值为0.02,这意味着预计最高得分的非同源目标的2%将通过过滤器。
          '--F2', str(self.filter_f2), # 第二滤波阈值;设置维特比滤波步骤的p值阈值。默认值是0.001
          '--F3', str(self.filter_f3), # 第三滤波器阈值;为正滤波器步骤设置p值阈值。默认值为1E-5。
          '--incE', str(self.e_value), # 包括e值<= <x>的序列在后续迭代或由-A输出的最终对齐中。默认值是0.001。
          # Report only sequences with E-values <= x in per-sequence output.
          '-E', str(self.e_value), 
          '--cpu', str(self.n_cpu),
          '-N', str(self.n_iter)
      ]
      if self.get_tblout:
        tblout_path = os.path.join(query_tmp_dir, 'tblout.txt') # 在最后的迭代之后,将最高序列命中的表格摘要保存到<f>中
        cmd_flags.extend(['--tblout', tblout_path])

      if self.z_value: # 声明数据库的总大小为<x个>序列,以用于e值计算。通常情况下,e值是根据实际搜索的数据库大小计算的(例如,目标seqdb中的序列数量)。在某些情况下(例如,如果您已将目标序列数据库拆分为多个文件以并行化搜索),您可能更了解搜索空间的实际大小。
        cmd_flags.extend(['-Z', str(self.z_value)])

      if self.dom_e is not None:
        cmd_flags.extend(['--domE', str(self.dom_e)]) # 报告每个域输出中条件e值<= <x>的域,以及每个显著序列命中得分最高的域。默认值是10.0。

      if self.incdom_e is not None:
        cmd_flags.extend(['--incdomE', str(self.incdom_e)]) #在后续迭代或由-A输出的最终对齐输出中包括条件e值<= <x>的域,除了每个显著序列命中的得分最高的域。默认值是0.001。

      cmd = [self.binary_path] + cmd_flags + [input_fasta_path,
                                              database_path]

      logging.info('Launching subprocess "%s"', ' '.join(cmd))
      process = subprocess.Popen(
          cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
      with utils.timing(
          f'Jackhmmer ({os.path.basename(database_path)}) query'):
        _, stderr = process.communicate()
        retcode = process.wait()

      if retcode:
        raise RuntimeError(
            'Jackhmmer failed\nstderr:\n%s\n' % stderr.decode('utf-8'))

      # Get e-values for each target name
      tbl = ''
      if self.get_tblout:
        with open(tblout_path) as f:
          tbl = f.read()

      if max_sequences is None:
        with open(sto_path) as f:
          sto = f.read()
      else:
        sto = parsers.truncate_stockholm_msa(sto_path, max_sequences)

    raw_output = dict(
        sto=sto,
        tbl=tbl,
        stderr=stderr,
        n_iter=self.n_iter,
        e_value=self.e_value)

    return raw_output

HHsuite

HHsuite 工具简要教程
hhblits:迭代地使用查询序列或 MSA 搜索 HHsuite 数据库
hhsearch:使用查询 MSA 或 HMM 搜索 HHsuite 数据库
hhmake:从输入 MSA 构建 HMM
hhfilter:按最大序列标识、覆盖率和其他标准过滤 MSA
hhalign:计算两个 HMM/MSA 的成对对齐等
hhconsensus:计算 A3M/FASTA 输入文件的一致序列
reformat.pl:重新格式化一个或多个 MSA
adds.pl:将 PSIPRED 预测的二级结构添加到 MSA 或 HHM 文件
hhmakemodel.pl:从 HHsearch 或 HHblits 结果生成 MSA 或粗略 3D 模型
hhmakemodel.py:从 HHsearch 或 HHblits 结果生成粗略的 3D 模型并修改 cif 文件以使其与 MODELLER 兼容
hhsuitedb.py:使用预过滤、打包的 MSA/HMM 和索引文件构建 HHsuite 数据库
splitfasta.pl : 将一个多序列 FASTA 文件拆分成多个单序列文件
renumberpdb.pl:生成 PDB 文件,索引重新编号以匹配输入序列索引
HHPaths.pm:带有 PDB、BLAST、PSIPRED 等路径的配置文件。
mergeali.pl:根据种子序列的 MSA 以 A3M 格式合并 MSA
pdb2fasta.pl:从全局 pdb 文件的 SEQRES 记录生成 FASTA 序列文件
cif2fasta.py:从 globbed cif 文件的 entity_poly 的 pdbx_seq_one_letter_code 条目生成 FASTA 序列
pdbfilter.pl:从 pdb2fasta.pl 输出中生成一组具有代表性的 PDB/SCOP 序列
pdbfilter.py:从 cif2fasta.py 输出生成一组具有代表性的 PDB/SCOP 序列
调用不带参数或带-h选项的程序以获得更详细的解释。

具体参数参考:https://github.com/soedinglab/hh-suite/wiki#hhsearch–search-a-database-of-hmms-with-a-query-msa-or-hmm

HHSearch

AlphaFold 主要用到的地方时模版搜索,使用的是HHSearch在uniref90中搜索同源模版
alphafold/data/tools/hhsearch.py

## 入口
 pdb_template_hits = self.template_searcher.get_template_hits(
        output_string=pdb_templates_result, input_sequence=input_sequence)
.....
## hhsearch d8li/output.hhr -maxseq 1000000 -d /data2/datasets/pdb70/pdb70

  def query(self, a3m: str) -> str:
    """Queries the database using HHsearch using a given a3m."""
    with utils.tmpdir_manager() as query_tmp_dir:
      input_path = os.path.join(query_tmp_dir, 'query.a3m')
      hhr_path = os.path.join(query_tmp_dir, 'output.hhr')
      with open(input_path, 'w') as f:
        f.write(a3m)

      db_cmd = []
      for db_path in self.databases:# 使用的数据库
        db_cmd.append('-d')
        db_cmd.append(db_path)
      cmd = [self.binary_path,
             '-i', input_path,# 输出
             '-o', hhr_path, # 输出
             '-maxseq', str(self.maxseq) # 最大序列个数
             ] + db_cmd

      logging.info('Launching subprocess "%s"', ' '.join(cmd))
      process = subprocess.Popen(
          cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
      with utils.timing('HHsearch query'):
        stdout, stderr = process.communicate()
        retcode = process.wait()

      if retcode:
        # Stderr is truncated to prevent proto size errors in Beam.
        raise RuntimeError(
            'HHSearch failed:\nstdout:\n%s\n\nstderr:\n%s\n' % (
                stdout.decode('utf-8'), stderr[:100_000].decode('utf-8')))

      with open(hhr_path) as f:
        hhr = f.read()
    return hhr

hhblits

与hhsearch类似, 区别HHblits 的运行速度比 HHsearch 快 30 到 3000 倍,但灵敏度仅降低了几个百分点。(这里使用的原因是bdf的数据比uniref90大,加快搜索速度)

def query(self, input_fasta_path: str) -> List[Mapping[str, Any]]:
    """Queries the database using HHblits."""
    with utils.tmpdir_manager() as query_tmp_dir:
      a3m_path = os.path.join(query_tmp_dir, 'output.a3m')

      db_cmd = []
      for db_path in self.databases:
        db_cmd.append('-d')
        db_cmd.append(db_path)
      cmd = [
          self.binary_path,
          '-i', input_fasta_path,
          '-cpu', str(self.n_cpu),
          '-oa3m', a3m_path,
          '-o', '/dev/null',
          '-n', str(self.n_iter),
          '-e', str(self.e_value),
          '-maxseq', str(self.maxseq),
          '-realign_max', str(self.realign_max),
          '-maxfilt', str(self.maxfilt),
          '-min_prefilter_hits', str(self.min_prefilter_hits)]
      if self.all_seqs:
        cmd += ['-all']
      if self.alt:
        cmd += ['-alt', str(self.alt)]
      if self.p != _HHBLITS_DEFAULT_P:
        cmd += ['-p', str(self.p)]
      if self.z != _HHBLITS_DEFAULT_Z:
        cmd += ['-Z', str(self.z)]
      cmd += db_cmd

      logging.info('Launching subprocess "%s"', ' '.join(cmd))
      process = subprocess.Popen(
          cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

      with utils.timing('HHblits query'):
        stdout, stderr = process.communicate()
        retcode = process.wait()

      if retcode:
        # Logs have a 15k character limit, so log HHblits error line by line.
        logging.error('HHblits failed. HHblits stderr begin:')
        for error_line in stderr.decode('utf-8').splitlines():
          if error_line.strip():
            logging.error(error_line.strip())
        logging.error('HHblits stderr end')
        raise RuntimeError('HHblits failed\nstdout:\n%s\n\nstderr:\n%s\n' % (
            stdout.decode('utf-8'), stderr[:500_000].decode('utf-8')))

      with open(a3m_path) as f:
        a3m = f.read()

    raw_output = dict(
        a3m=a3m,
        output=stdout,
        stderr=stderr,
        n_iter=self.n_iter,
        e_value=self.e_value)
    return [raw_output]

kalign

之前提到的clustalo, muscle, mafft 适用于几千到几万条序列的多序列比对,在比较基因组学的分析中,需要对不同基因组的序列进行多序列比对。对于基因组规模的多序列比对而言,之前的工具运行速度上就不够理想了。

kalign 是一款针对大规模序列的多序列比对工具,无论是运行速度,还是比对的准确度,都令人满意。

Kalign 期望输入是一组 fasta 格式的未对齐序列或对齐的 fasta、MSF 或 clustal 格式的对齐序列。如果序列已经对齐,kalign 将删除所有间隙字符并重新对齐序列。
默认情况下,Kalign 会自动检测输入序列是蛋白质还是 DNA,并选择合适的比对参数。
详细参数请参考: https://github.com/TimoLassmann/kalign
alphafold/data/tools/kalign.py

def align(self, sequences: Sequence[str]) -> str:
    logging.info('Aligning %d sequences', len(sequences))

    for s in sequences:
      if len(s) < 6:
        raise ValueError('Kalign requires all sequences to be at least 6 '
                         'residues long. Got %s (%d residues).' % (s, len(s)))

    with utils.tmpdir_manager() as query_tmp_dir:
      input_fasta_path = os.path.join(query_tmp_dir, 'input.fasta')
      output_a3m_path = os.path.join(query_tmp_dir, 'output.a3m')

      with open(input_fasta_path, 'w') as f:
        f.write(_to_a3m(sequences))

      cmd = [
          self.binary_path,
          '-i', input_fasta_path,
          '-o', output_a3m_path,
          '-format', 'fasta',
      ]

      logging.info('Launching subprocess "%s"', ' '.join(cmd))
      process = subprocess.Popen(cmd, stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE)

      with utils.timing('Kalign query'):
        stdout, stderr = process.communicate()
        retcode = process.wait()
        logging.info('Kalign stdout:\n%s\n\nstderr:\n%s\n',
                     stdout.decode('utf-8'), stderr.decode('utf-8'))

      if retcode:
        raise RuntimeError('Kalign failed\nstdout:\n%s\n\nstderr:\n%s\n'
                           % (stdout.decode('utf-8'), stderr.decode('utf-8')))

      with open(output_a3m_path) as f:
        a3m = f.read()

      return a3m

预处理格式(包括输出和中间结果)

MSA 特征提取

  • bfd_uniclust_hits.a3m 主要是通过uniclust30_2018_08bfd_metaclust_clu_complete_id30_c90_final_seq两个数据集通过HHBlits构建
  • uniref90_hits.sto 通过uniref90数据集Jackhmmer搜索得到
  • mgnify_hits.sto 通过uniref90数据集mgnify搜索得到

    构建MSA特征入口:
    msa_features = make_msa_features((uniref90_msa, bfd_msa, mgnify_msa)) # 构造MSA特征
    对MSA特征去重、MSA序列数字list化以及更新特征:
def make_msa_features(msas: Sequence[parsers.Msa]) -> FeatureDict:
  """Constructs a feature dict of MSA features."""
  if not msas:
    raise ValueError('At least one MSA must be provided.')

  int_msa = []
  deletion_matrix = []
  species_ids = []
  seen_sequences = set()
  for msa_index, msa in enumerate(msas):
    if not msa:
      raise ValueError(f'MSA {msa_index} must contain at least one sequence.')
    for sequence_index, sequence in enumerate(msa.sequences):
      if sequence in seen_sequences:
        continue
      seen_sequences.add(sequence)
      int_msa.append(
          [residue_constants.HHBLITS_AA_TO_ID[res] for res in sequence])
      deletion_matrix.append(msa.deletion_matrix[sequence_index])
      identifiers = msa_identifiers.get_identifiers(
          msa.descriptions[sequence_index])
      species_ids.append(identifiers.species_id.encode('utf-8'))

  num_res = len(msas[0].sequences[0])
  num_alignments = len(int_msa)
  features = {}
  features['deletion_matrix_int'] = np.array(deletion_matrix, dtype=np.int32)
  features['msa'] = np.array(int_msa, dtype=np.int32)
  features['num_alignments'] = np.array(
      [num_alignments] * num_res, dtype=np.int32)
  features['msa_species_identifiers'] = np.array(species_ids, dtype=np.object_)
  return features

MSA特征字典:

  • deletion_matrix_int:检测MSA中每条序列中是否存在小写字符的氨基酸信息,此区域代表同源序列中的序列被删除。(在推理中貌似没用,矩阵的维度是NxL),可能的信息Training时在Residue cropping部分。
  • msa:将MSA每条序列转为以数字替代的list,方便后续one-hot化
  • num_alignments:对齐数量
  • msa_species_identifiers:种属信息,貌似我提供的MSA中没有这部分东西

Template特征提取

pdb_hits.hhruniref90MSA通过HHSearch检索pdb70库得到的信息, 其中主要记录的是可用模板的PDB ID,序列相似度,结构与序列match的区间

读取.hhr文件信息

pdb_template_hits = self.template_searcher.get_template_hits(output_string=pdb_templates_result, input_sequence=input_sequence)

@dataclasses.dataclass(frozen=True)
class TemplateHit:
  """Class representing a template hit."""
  index: int
  name: str
  aligned_cols: int
  sum_probs: Optional[float]
  query: str
  hit_sequence: str
  indices_query: List[int]
  indices_hit: List[int]
  • aligned_cols:指query sequence被模板覆盖的区间大小
  • sum_probs被用于对template进行打分排名
  • indices_queryindices_hit是最重要的信息,这里记录了模板和query sequence的匹配区间信息

template_hits 特征化

TEMPLATE_FEATURES = {
    'template_aatype': np.float32,
    'template_all_atom_masks': np.float32,
    'template_all_atom_positions': np.float32, #对template atom 位置信息
    'template_domain_names': np.object, # 领域
    'template_sequence': np.object, # template序列
    'template_sum_probs': np.float32, # 对template进行打分排名
}

def get_templates(
      self,
      query_sequence: str,
      hits: Sequence[parsers.TemplateHit]) -> TemplateSearchResult:
    """Computes the templates for given query sequence (more details above). 计算给定查询序列的模板(以上详细信息)。"""
    logging.info('Searching for template for: %s', query_sequence)
........
      result = _process_single_hit(
          query_sequence=query_sequence,
          hit=hit,
          mmcif_dir=self._mmcif_dir,# pdb mmcif文件地址
          max_template_date=self._max_template_date, # 模板日期
          release_dates=self._release_dates,
          obsolete_pdbs=self._obsolete_pdbs,
          strict_error_check=self._strict_error_check,
          kalign_binary_path=self._kalign_binary_path)

      ........

    return TemplateSearchResult(
        features=template_features, errors=errors, warnings=warnings)

.....

def _extract_template_features(....)
    .......
	return (
      {
          'template_all_atom_positions': np.array(templates_all_atom_positions),
          'template_all_atom_masks': np.array(templates_all_atom_masks),
          'template_sequence': output_templates_sequence.encode(),
          'template_aatype': np.array(templates_aatype),
          'template_domain_names': f'{pdb_id.lower()}_{chain_id}'.encode(),
      }
    

template的feature特征包括: N N N指模板的数量

  • template_aatype: 模板序列的one-hot representation,shape = NxLx22,包括unknown和gap;
  • template_all_atom_masks: shape = NxLx37,代表在模板中,原子是否存在,存在=1,不存在=0;
  • template_all_atom_positions: shape = Lx37x3, 其中37为所有的可能的蛋白原子类型,3维代表xyz坐标值。
  • template_domain_names: 模板的名称
  • template_sequence: shape =NxL 序列字符串
  • template_sum_probs: match的打分值 (np.float32)

最后返回的时TemplateSearchResult实例。

input sequence特征提取

这里主要是对输入序列进行特征化:

### 入口
sequence_features = make_sequence_features(
        sequence=input_sequence,
        description=input_description,
        num_res=num_res)## 构造输入序列特征

def make_sequence_features(
    sequence: str, description: str, num_res: int) -> FeatureDict:
  """Constructs a feature dict of sequence features. 构造序列特征的特征字典。"""
  features = {}
  features['aatype'] = residue_constants.sequence_to_onehot(
      sequence=sequence,
      mapping=residue_constants.restype_order_with_x,
      map_unknown_to_x=True)#残基one-hot
  features['between_segment_residues'] = np.zeros((num_res,), dtype=np.int32)
  features['domain_name'] = np.array([description.encode('utf-8')],
                                     dtype=np.object_)
  features['residue_index'] = np.array(range(num_res), dtype=np.int32)
  features['seq_length'] = np.array([num_res] * num_res, dtype=np.int32)
  features['sequence'] = np.array([sequence.encode('utf-8')], dtype=np.object_)
  return features

特征字典信息:

  • aatype: one-hot编码的序列
  • between_segment_residues?含义不明(可能在multimer的文章中会有解释)
  • domain_name:序列名,字符串信息
  • residue_index: 残基编号,从0开始
  • seq_length:序列长度,为什么会重复N次?
  • sequence:人类可读的序列3字母缩写序列,类型字符串

参考

https://zhuanlan.zhihu.com/p/492381344

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何让Java项目兼容更多的客户端设备(二)

如何让Java项目兼容更多的客户端设备&#xff08;二&#xff09; ​ ​ 一、Token认证的原理 传统的单体JavaWeb项目通常采用HttpSession保存登陆成功的凭证&#xff0c;但是HttpSession需要浏览器的Cookie机制配合。也就是说Web项目的客户端只能是浏览器&#xff0c;不可以…

torch.nn.functional.grid_sample(F.grid_sample)函数的说明 3D空间中的点向图像投影的易错点

由于二者有一定共通之处&#xff0c;因此放在一篇文章内介绍。 1. 关于torch.nn.functional.grid_sample函数的说明&#xff08;F.grid_sample&#xff09; 该函数的作用是在图像/体素空间中采样特征。 1.1 输入和输出&#xff1a; 变量名数据类型默认值含义备注inputTensor-…

训练神经网络的各种优化算法【文末赠书】

正确的优化算法可以成倍地减少训练时间 许多人在训练神经网络时可能会使用优化器&#xff0c;而不知道该方法称为优化。优化器是用于更改神经网络属性&#xff08;例如权重和学习率&#xff09;以减少损失的算法或方法。 文章目录梯度下降随机梯度下降小批量梯度下降其它优化算…

C/C++指针之提高篇详解(二)

一、引言 C/C语言中引入了指针&#xff0c;使得程序能够直接访问内存地址&#xff0c;使得很多复杂的操作变得简单&#xff0c;同时也提高了程序的运行效率。指针即是地址&#xff0c;但是地址却是通过指针变量来存储的。这就好比我们的教室&#xff0c;每个教室都有一个房间号…

第3章 Tomcatservlet

1.BS与CS *CS&#xff1a;客户端服务器架构模式 优点&#xff1a;充分利用客户端机器的资源&#xff0c;减轻服务器的负荷 缺点&#xff1a;需要安装&#xff1b;升级维护成本较高 *BS&#xff1a;浏览器服务器架构模式 优点&#xff1a;客户端不需要安装&#xff0c;维护成本…

Zlibrary已死,找了一个替代品,找了一个替代品免费的电子书下载平台...

大家好&#xff0c;我是鸟哥。一个半路出家的程序员。 提到Zlibrary&#xff0c;想必大家都不陌生吧。全球最大的数字图书馆&#xff0c;截止被封前共收录了591万本书&#xff0c;7751万篇文章&#xff0c;并且还在不断的增加中&#xff0c;关键是可以免费下载。 反正我是很熟悉…

Rust之常用集合(二):字符串(String)

开发环境 Windows 10Rust 1.65.0VS Code 1.73.1 项目工程 这里继续沿用上次工程rust-demo 用字符串存储UTF-8编码的文本 我们在之前的章节中讨论了字符串&#xff0c;但现在我们将更深入地研究它们。新的Rust人会因为三个原因而陷入字符串:Rust倾向于暴露可能的错误&#x…

【季报分析】美团:真的很美

11月25日&#xff0c;港股盘后美团发布了2022年第三季度业绩报告。整体来看&#xff0c;财报数据还算不错&#xff0c;毕竟大部分指标都已经超预期&#xff0c;探员利用这两天假期&#xff0c;把美团的这份财报仔细过了一遍&#xff0c;当然探员也把2022年Q1、Q2的数据也进行了…

Linux代码调试----gdb使用介绍

目录 一、简介 二、gdb使用流程&#xff1a; &#xff08;1&#xff09;gdb的启动 &#xff08;2&#xff09;调试中查看源代码 &#xff08;3&#xff09;开始调试 一、简介 GDB 全称“GNU symbolic debugger”&#xff0c;是 Linux 下常用的程序调试器。发展至今&#xff…

[附源码]SSM计算机毕业设计校园超市进销存管理系统JAVA

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

【Node.js】第九章 数据库

目录 1. 数据库的基本概念 1.1 数据库的概念 1.2 数据库的分类 1.3 数据组织结构 2. MySQL使用介绍 2.1 安装MySQL和MySQL Workbench 2.2 MySQL的基本使用 2.3 使用SQL管理数据库 3. 在项目中使用MySQL 3.1 安装和配置MySQL模块 3.2 操作数据 1. 数据库的基本概念…

word怎么转pdf?word转pdf借助pdf软件即可搞定!

我们在办公的时候&#xff0c;会有word转pdf的办公需求&#xff0c;但是很多人都不清楚word转pdf的方法&#xff0c;那么word怎么转pdf呢&#xff1f;其实方法很简单&#xff0c;利用pdf软件来进行word转pdf的操作即可&#xff0c;如今&#xff0c;市面上pdf软件应接不暇&#…

五、Javascript 空间坐标[尺寸、滑动]

一、尺寸 1.视窗尺寸 document.documentElement.clientWidth&#xff1a;视窗宽度document.documentElement.clientHeight&#xff1a;视窗高度 2.各种尺寸 举例&#xff1a;<div id"gao"></div> 前提&#xff1a;var a document.getElementById(g…

多重共线性如何分析?

判断标准 常见的直观判断方法共有四个&#xff0c;如下&#xff1a; &#xff08;1&#xff09;某些自变量的相关系数值较大&#xff08;比如大于0.8&#xff09;等&#xff0c;可以利用pearson相关系数检验法一般是利用解释变量之间的线性相关程度判断&#xff0c;一般标准是…

Java常用类(二)

目录 JDK8之前的日期时间API java.lang.System类 java.util.Date类 两个构造器的使用 两个方法的使用 java.sql.Date类 涉及两个问题&#xff1a; java.text.SimpleDateFormat类 格式化&#xff1a;日期--->字符串 解析&#xff1a;字符串--->日期&#xff08;格…

基于TM的遥感数据的叶面积指数估算解决方案及或取途径

1、背景与技术路线 叶面积指数是重要的植被结构参数&#xff0c;反演叶面积指数是植被遥感的重要研究内容之一&#xff0c;其影响生 态系统的物质和能量循环&#xff0c;成为作物生长、路面过程、水文和生态等模型的输入参数或状态变量。今 年来&#xff0c;对也铭记指数的反演…

Spark系列之Spark的RDD详解

title: Spark系列 第五章 Spark 的RDD详解 5.1 RDD概述 ​ RDD 是 Spark 的基石&#xff0c;是实现 Spark 数据处理的核心抽象。那么 RDD 为什么会产生呢&#xff1f; ​ Hadoop的MapReduce是一种基于数据集的工作模式&#xff0c;面向数据&#xff0c;这种工作模式一般是从…

Python_数据容器_集合set

一、集合set的定义 考虑使用集合的场景&#xff0c;通过已经学习的列表、元组、字符串三个数据容器特性来分析&#xff1a; 列表可以修改、支持重复元素且有序 元组、字符串、不可修改、支持重复元素且有序 局限就在于&#xff1a;它们支持重复元素 集合定义语法&#xff1…

KubeVirt with DPDK

发布于2022-11-25 15:52:32阅读 1020 Kubernetes优秀的架构设计&#xff0c;借助multus cni intel userspace cni 可以屏蔽了DPDK底层的复杂&#xff0c;让KubeVirt 支持DPDK变得比较容易。 因为 e2e验证 等原因&#xff0c;KubeVirt社区至今未加入对DPDK支持&#xff0c;本篇…

有用的CSS代码块

文章目录调试 DOM 元素的 border通用的网页样式调试 DOM 元素的 border 显示所有DOM元素的border&#xff0c;方便调试网页元素的相对布局。 * {outline: auto; }如何用javascript设置某个网页的style(复制以下代码到浏览器控制台执行即可)&#xff1f; // wuyujin1997 var …