ARTES #004
ARTES #004
ARTS é uma atividade iniciada por
由左耳朵耗子--陈皓: Faça pelo menos uma pergunta sobre o algoritmo leetcode toda semana, leia e comente pelo menos um artigo técnico em inglês, aprenda pelo menos uma habilidade técnica e compartilhe um artigo com opiniões e pensamentos. (Ou seja, Algoritmo, Revisão, Dica e Compartilhamento são chamados de ARTS) e persistem por pelo menos um ano.
ARTES 004
Este é o quarto artigo. Está relativamente mal escrito. Espero que fique cada vez melhor no futuro.
Pergunta sobre algoritmo de algoritmo
Pergunta do algoritmo leetcode 321 Criar número máximo (número máximo de emenda) Poderia ser: difícil
Given two arrays of length m and n with digits 0-9 representing two numbers. Create the maximum number of length k <= m + n from digits of the two. The relative order of the digits from the same array must be preserved. Return an array of the k digits.
Note: You should try to optimize your time and space complexity.
Example 1:
Input:
nums1 = [3, 4, 6, 5]
nums2 = [9, 1, 2, 5, 8, 3]
k = 5
Output:
[9, 8, 6, 5, 3]
Example 2:
Input:
nums1 = [6, 7]
nums2 = [6, 0, 4]
k = 5
Output:
[6, 7, 6, 0, 4]
Example 3:
Input:
nums1 = [3, 9]
nums2 = [8, 9]
k = 3
Output:
[9, 8, 9]
给定长度分别为 m 和 n 的两个数组,其元素由 0-9 构成,表示两个自然数各位上的数字。现在从这两个数组中选出 k (k <= m + n) 个数字拼接成一个新的数,要求从同一个数组中取出的数字保持其在原数组中的相对顺序。
求满足该条件的最大数。结果返回一个表示该最大数的长度为 k 的数组。
说明: 请尽可能地优化你算法的时间和空间复杂度。
示例 1:
输入:
nums1 = [3, 4, 6, 5]
nums2 = [9, 1, 2, 5, 8, 3]
k = 5
输出:
[9, 8, 6, 5, 3]
示例 2:
输入:
nums1 = [6, 7]
nums2 = [6, 0, 4]
k = 5
输出:
[6, 7, 6, 0, 4]
示例 3:
输入:
nums1 = [3, 9]
nums2 = [8, 9]
k = 3
输出:
[9, 8, 9]
Ideias para resolução de problemas:
-
1 Determine quantos números cada uma das duas matrizes leva, por exemplo, k=5, que pode ser dividido em 1, 4; 2, 3; 3, 2; 4, 1; e deve ser menor que o número de nums1 ou nums2. Esta etapa é relativamente simples.
-
2 Combine as submatrizes que atendem às condições em uma Esta etapa é mais complicada. Por exemplo, nums1 = [6, 7, 0]; nums2 = [6, 0, 4], k=5; k pode ser dividido em 2, 3; 3, 2; Agora considere os casos 2 e 3, nums1_1 = [6, 7]; nums2_1 = [6, 0, 4]; Então, como você combina essas duas submatrizes em um número máximo? À primeira vista, parece bastante simples. Basta pegar um de cada uma das duas matrizes e escolher o que for maior. Mas há uma armadilha aqui. O que devo fazer se os tamanhos forem iguais? Por exemplo, os primeiros números de nums1_1 e nums2_1 são ambos 6, qual deles deve ser escolhido? Vamos ver o que há de diferente. Se você pegar 6 de nums2_1 pela primeira vez, depois de pegá-lo, nums1_1 = [6, 7]; nums2_1 = [0, 4]; Na segunda vez que nums1_1 leva 6, nums2_1 só pode levar 0, 6 é maior que 0, então pegue 6, depois de pegá-lo, nums1_1 = [7]; nums2_1 = [0, 4];, o resultado final é [6,6,7,0,4]
Se você pegar 6 de nums1_1 pela primeira vez, depois de pegá-lo, nums1_1 = [7]; nums2_1 = [6,0, 4]; Pela segunda vez, nums1_1 leva 7 e nums2_1 leva 6. 7 é maior que 6, então 7 é levado. Depois de pegá-lo, nums1_1 = []; nums2_1 = [6,0, 4];, o resultado final é [6,7,6,0,4]
Os resultados são diferentes, obviamente o segundo está certo. O método de mesclagem que usamos acima é semelhante ao algoritmo usado na classificação por mesclagem, mas ao mesclar arrays na classificação por mesclagem, os dois arrays estão em ordem, mas os dois arrays que mesclamos aqui estão desordenados, então encontraremos esse problema. Meu código de estágio é o seguinte:
/**
* Return an array of size *returnSize.
* Note: The returned array must be malloced, assume caller calls free().
*/
int maxInexd(int* nums,int max,int min){
int maxindex = min;
int count = nums[maxindex];
for (int i = min; i<=max; i++) {
if (nums[i] > count) {
count = nums[i];
maxindex = i;
}
}
return maxindex;
}
int* maxNumber1(int* nums, int numsSize, int numcount){
int *a = (int *)malloc(numcount*sizeof(int));
int index = -1;
for (int i = 0; i < numcount; i++) {
index = maxInexd(nums, numsSize - numcount +i, index+1);
a[i] = nums[index];
}
return a;
}
int* merge(int* num11, int nums1count, int* num22, int nums2count, int k){
//把两个数组合并为一个
int* tempReturnSize = (int *)malloc(k*sizeof(int));
int mm = 0;
int nn = 0;
for (int i = 0; i < k; i++) {
if (mm == nums1count) {
int a = num22[nn];
tempReturnSize[i] = a;
nn++;
continue;
}
if (nn == nums2count) {
int b = num11[mm];
tempReturnSize[i] = b;
mm++;
continue;
}
int aa = num11[mm];
int bb = num22[nn];
if (aa >bb) {
tempReturnSize[i] = aa;
mm++;
}
else if (aa == bb){
int aa1 = aa;
int bb1 = bb;
int ii = 0;
while (mm + ii +1 != nums1count && nn + ii+1 != nums2count && aa1 ==bb1 ) {
ii++;
aa1 = num11[mm + ii];
bb1 = num22[nn + ii];
}
if (aa1 > bb1) {
tempReturnSize[i] = aa;
mm++;
continue;
}
else if(aa1 < bb1){
tempReturnSize[i] = bb;
nn++;
continue;
}
if (mm + ii +1 == nums1count) {//说明没有下一个
tempReturnSize[i] = bb;
nn++;
continue;
}
if (nn + ii +1 == nums2count) {//说明没有下一个
tempReturnSize[i] = bb;
mm++;
continue;
}
}
else{
tempReturnSize[i] = bb;
nn++;
}
}
return tempReturnSize;
}
int* maxNumber(int* nums1, int nums1Size, int* nums2, int nums2Size, int k, int* returnSize) {
*returnSize = k; //在leetcode提交的时候,不知道为什么要加上这个
if (nums1Size ==0) {
return nums2;
}
if (nums2Size ==0) {
return nums1;
}
int* relsut = (int*)malloc(sizeof(int) * k);
memset(relsut, 0, sizeof(int) * k);
int nums1count, nums2count;
for (nums1count = 1; nums1count <= nums1Size; nums1count++) {//nums1count 表示从nums1数组取的数的个数 最少是1 最大是nums1Size
nums2count = k - nums1count;
if (nums2count > nums2Size) {
continue;
}
if(nums2count == 0){//不能不从nums2取值
break;
}
//从nums1中按序取出nums1count个数,且这个几个数按序组装成整数之后是最大的
int *num11 = maxNumber1(nums1, nums1Size,nums1count);
//从nums2中按序取出nums2count个数,且这个几个数按序组装成整数之后是最大的
int *num22 = maxNumber1(nums2, nums2Size,nums2count);
//把两个数组合并为一个
int* tempReturnSize =merge( num11, nums1count, num22, nums2count, k);
//比较最大的数值
for (int i = 0; i < k; i++) {
int aa = tempReturnSize[i];
int bb = relsut[i];
if (aa > bb) {
for (int j = 0; j < k; j++){
relsut[j] = tempReturnSize[j];
}
break;
}
else if (bb >aa){
break;
}
}
free(tempReturnSize);
free(num11);
free(num22);
}
return relsut;
}
O tempo de execução no LeetCode é de 20ms. O código a seguir é um código enviado em LeetCode com tempo de execução de 8ms. Parece semelhante à minha implementação. Não sei onde é mais rápido:
void maxNum(int*, int, int, int*);
void merge(int*, int, int*, int, int*);
void max(int*, int*, int);
int* maxNumber(int* nums1, int nums1Size, int* nums2, int nums2Size, int k, int* returnSize)
{
*returnSize = k;
int* result = (int*)malloc(sizeof(int) * k);
memset(result, 0, sizeof(int) * k);
int* merged = (int*)malloc(sizeof(int) * k);
int *max1 = NULL, *max2 = NULL;
for (int i = 0; i <= k; i++) {
int n1 = i, n2 = k - i;
if (n1 > nums1Size || n2 > nums2Size)
continue;
max1 = realloc(max1, sizeof(int) * n1);
maxNum(nums1, nums1Size, n1, max1);
max2 = realloc(max2, sizeof(int) * n2);
maxNum(nums2, nums2Size, n2, max2);
merge(max1, n1, max2, n2, merged);
max(result, merged, k);
}
free(max1), free(max2), free(merged);
return result;
}
void maxNum(int* nums, int n, int k, int* r)
{
for (int i = 0, j = 0; i < n; i++) {
// drop last one
while (j > 0 && k - j < n - i && nums[i] > r[j - 1])
j--;
if (j < k)
r[j++] = nums[i];
}
}
void merge(int* nums1, int n1, int* nums2, int n2, int* r)
{
for (int i = 0, j = 0, k = 0; k < n1 + n2; k++) {
int val1 = i < n1 ? nums1[i] : -1;
int val2 = j < n2 ? nums2[j] : -1;
int t = 1;
while (val1 == val2 && val1 != -1) {
val1 = i + t < n1 ? nums1[i + t] : -1;
val2 = j + t < n2 ? nums2[j + t] : -1;
t++;
}
if (val1 > val2)
r[k] = nums1[i++];
else if (val1 < val2)
r[k] = nums2[j++];
else
// val1 == val2 == -1
r[k] = nums1[i++];
}
}
void max(int* nums1, int* nums2, int n)
{
int i;
for (i = 0; i < n; i++) {
if (nums1[i] < nums2[i])
break;
if (nums1[i] > nums2[i])
return;
}
if (i != n)
// set the new max
for (i = 0; i < n; i++)
nums1[i] = nums2[i];
}
Revisão
Este artigo vem de: https://medium.com/exploring-code/why-should-you-learn-go-f607681fad65
Por que você deveria aprender Go? (Por que você deveria aprender Go)

Imagem de: http://kirael-art.deviantart.com/art/Go-lang-Mascot-458285682
“Go será a linguagem de servidor do futuro.” —Tobias Lütke, Shopify
Nos últimos anos, houve o surgimento de uma nova linguagem de programação: Go ou GoLang. Nada deixa um desenvolvedor louco do que uma nova linguagem de programação, certo? Então, comecei a aprender Go antes dos 4 a 5 meses e aqui vou contar porque você também deveria aprender esse novo idioma.
Nos últimos anos, surgiu uma nova linguagem de programação: Go ou GoLang. Nada enlouquece os desenvolvedores, exceto novas linguagens de programação, certo? Então, comecei a aprender Go há 4 a 5 meses e aqui vou contar porque você também deveria aprender esse novo idioma.
Não vou te ensinar como você pode escrever “Hello World!!” neste artigo. Existem muitos outros artigos online sobre isso. I am going the explain current stage of computer hardware-software and why we need new language like Go? Porque se não houver problema, então não precisamos de solução, certo?
Neste artigo não vou te ensinar como escrever “Hello World!!”. Já existem muitos artigos semelhantes na Internet. “Vou explicar agora por que precisamos de uma nova linguagem como Go no estágio atual de hardware e software de computador?” Porque se não houver problemas, então não precisamos de solução, certo?
#####Limitações de hardware: A lei de Moore está falhando. O primeiro processador Pentium 4 com velocidade de clock de 3,0 GHz foi lançado em 2004 pela Intel. Hoje, meu Mackbook Pro 2016 tem velocidade de clock de 2,9 GHz. Assim, em quase uma década, não há muito ganho no poder de processamento bruto. Você pode ver a comparação do aumento do poder de processamento com o tempo no gráfico abaixo.
摩尔定律失效了
A Intel lançou o primeiro processador Pentium 4 com velocidade de clock de 3,0 GHz em 2004. Hoje, meu Mackbook Pro 2016 tem velocidade de clock de 2,9 GHz. Portanto, durante quase dez anos, o poder de processamento bruto não melhorou muito. Você pode ver o aumento no poder de processamento em função do tempo no gráfico abaixo.

No gráfico acima você pode ver que o desempenho de thread único e a frequência do processador permaneceram estáveis por quase uma década. Se você está pensando que adicionar mais transistores é a solução, você está errado. Isso ocorre porque em menor escala algumas propriedades quânticas começam a surgir (como tunelamento) e porque na verdade custa mais colocar mais transistores (por quê?) e o número de transistores que você pode adicionar por dólar começa a cair.
Como você pode ver no gráfico acima, o desempenho de thread único e a frequência do processador permaneceram estáveis por quase uma década. Se você acha que adicionar mais transistores é a solução, você está errado. Isso ocorre porque em escalas menores, algumas propriedades quânticas começam a aparecer (como tunelamento) e porque colocar mais transistores na verdade custa mais por que, e o número de transistores que podem ser adicionados por dólar começa a cair.
Então, para a solução do problema acima, Portanto, a solução para o problema acima é a seguinte,
- Os fabricantes começaram a adicionar cada vez mais núcleos ao processador. Hoje em dia temos CPUs quad-core e octa-core disponíveis.
- Os fabricantes começaram a adicionar cada vez mais núcleos aos processadores. Hoje temos CPUs quad-core e oito núcleos disponíveis.
- Também introduzimos o hyper-threading.
- Também introduzimos o Hyper-Threading.
- Adicionado mais cache ao processador para aumentar o desempenho.
- Adicionado mais cache ao processador para melhorar o desempenho.
Mas as soluções acima também têm suas próprias limitações. Não podemos adicionar cada vez mais cache ao processador para aumentar o desempenho, pois o cache tem limites físicos: quanto maior o cache, mais lento ele fica. Adicionar mais núcleos ao processador também tem seu custo. Além disso, isso não pode ser dimensionado indefinidamente. Esses processadores multi-core podem executar vários threads simultaneamente e isso traz simultaneidade ao cenário. Discutiremos isso mais tarde.
Mas as soluções acima também têm as suas próprias limitações. Não podemos adicionar cada vez mais cache ao processador para melhorar o desempenho porque o cache tem limitações físicas: quanto maior o cache, mais lento você fica. Adicionar mais núcleos a um processador também tem seus custos. E isso não aumenta infinitamente. Esses processadores multi-core podem executar vários threads simultaneamente, trazendo simultaneidade às imagens. Discutiremos isso mais tarde.Portanto, se não podemos contar com melhorias de hardware, o único caminho a percorrer é um software mais eficiente para aumentar o desempenho. Mas, infelizmente, as linguagens de programação modernas não são muito eficientes. Portanto, se não podemos contar com melhorias de hardware, a única saída é melhorar o desempenho do software. Mas, infelizmente, as linguagens de programação modernas não são muito eficientes.
“Modern processors are a like nitro fueled funny cars, they excel at the quarter mile. Unfortunately modern programming languages are like Monte Carlo, they are full of twists and turns.” — David Ungar
“现代处理器就像硝基燃料有趣的汽车,他们擅长四分之一英里。 不幸的是,现代编程语言就像蒙特卡罗,它们充满了曲折。“ - David Ungar
Go tem goroutines!!
Conforme discutimos acima, os fabricantes de hardware estão adicionando cada vez mais núcleos aos processadores para aumentar o desempenho. Todos os data centers estão rodando nesses processadores e devemos esperar um aumento no número de núcleos nos próximos anos. Mais do que isso, os aplicativos atuais usam vários microsserviços para manter conexões de banco de dados, filas de mensagens e manter caches. Portanto, o software que desenvolvemos e as linguagens de programação devem suportar facilmente a simultaneidade e devem ser escaláveis com maior número de núcleos.
Conforme mencionado acima, os fabricantes de hardware estão adicionando cada vez mais núcleos aos processadores para melhorar o desempenho. Todos os data centers funcionam com esses processadores e esperamos que o número de núcleos aumente nos próximos anos. Além do mais, os aplicativos atuais usam vários microsserviços para manter conexões de banco de dados, filas de mensagens e manter caches. Portanto, o software e as linguagens de programação que desenvolvemos devem suportar facilmente a simultaneidade e devem ser escalonáveis à medida que o número de núcleos aumenta.
Porém, a maioria das linguagens de programação modernas (como Java, Python etc.) são do ambiente de thread único dos anos 90. A maioria dessas linguagens de programação oferece suporte a multithreading. Mas o verdadeiro problema vem com execução simultânea, bloqueio de threads, condições de corrida e impasses. Essas coisas dificultam a criação de um aplicativo multithread nessas linguagens.
No entanto, a maioria das linguagens de programação modernas, como Java, Python, etc., vêm do ambiente de thread único dos anos 90. A maioria das linguagens de programação oferece suporte a multithreading. Mas os verdadeiros problemas são execução simultânea, bloqueio de threads, condições de corrida e impasses. Essas coisas dificultam a criação de aplicativos multithread nessas linguagens.
Por exemplo, criar um novo thread em Java não é uma memória eficiente. Como cada thread consome aproximadamente 1 MB do tamanho do heap de memória e, eventualmente, se você começar a girar milhares de threads, eles colocarão uma pressão tremenda no heap e causarão o desligamento devido à falta de memória. Além disso, se você quiser se comunicar entre dois ou mais threads, é muito difícil. Por exemplo, criar um novo thread em Java não consome muita memória. Porque cada thread consome cerca de 1 MB de tamanho de heap de memória e, eventualmente, se você começar a girar milhares de threads, eles colocarão uma pressão enorme no heap e causarão desligamentos devido à memória insuficiente. Além disso, se você quiser se comunicar entre dois ou mais threads, será muito difícil.
Por outro lado, Go foi lançado em 2009, quando os processadores multi-core já estavam disponíveis. É por isso que o Go foi criado tendo em mente a simultaneidade. Go tem goroutines em vez de threads. Eles consomem quase 2 KB de memória do heap. Assim, você pode girar milhões de goroutines a qualquer momento.
Já o Go foi lançado em 2009, quando já existiam processadores multi-core. É por isso que o Go foi criado com a simultaneidade em mente. Go tem goroutines em vez de threads. Eles consomem cerca de 2 KB de memória do heap. Assim, você pode ativar milhões de goroutines a qualquer momento.
Como funcionam as Goroutines? Refrança: http://golangtutorials.blogspot.in/2011/06/goroutines.html
Outros benefícios são:
- Goroutines têm pilhas segmentadas que podem ser aumentadas. Isso significa que eles usarão mais memória somente quando necessário.
- Goroutines têm pilhas segmentadas que podem ser aumentadas. Isso significa que eles só usam mais memória quando necessário.
- Goroutines têm um tempo de inicialização mais rápido que threads.
- Goroutines têm tempo de inicialização mais rápido que threads.
- Goroutines vêm com primitivos integrados para comunicação segura entre si (canais).
- Goroutines vêm com primitivos integrados para comunicação segura entre eles (canais).
- Goroutines permitem que você evite recorrer ao bloqueio mutex ao compartilhar estruturas de dados.
- Goroutines permitem evitar o uso de bloqueios mutex ao compartilhar estruturas de dados.
- Além disso, goroutines e threads de sistema operacional não possuem mapeamento 1:1. Uma única goroutine pode ser executada em vários threads. Goroutines são multiplexadas em um pequeno número de threads do sistema operacional.
- Além disso, não há mapeamento 1:1 entre goroutines e threads do sistema operacional. Uma única goroutine pode ser executada em vários threads. Goroutines são multiplexadas em um pequeno número de threads do sistema operacional.
You can see Rob Pike’s excellent talk [concurrency is not parallelism](https://blog.golang.org/concurrency-is-not-parallelism) to get more deep understanding on this.
Todos os pontos acima tornam o Go muito poderoso para lidar com simultaneidade como Java, C e C++, ao mesmo tempo que mantém o código de execução de simultaneidade estreito e bonito como Erlang. Os pontos acima tornam o Go muito poderoso. Pode ser tão eficiente quanto Java, C e C++ ao lidar com operações simultâneas e tão bonito quanto Erlang.
Go tira proveito de ambos os mundos. Fácil de escrever simultaneamente e eficiente para gerenciar a simultaneidade
Go se destaca em ambos os mundos. Simultaneidade fácil de escrever e gerenciamento eficiente de simultaneidade
#####Go é executado diretamente no hardware subjacente (Go é executado diretamente no hardware subjacente). Um benefício mais considerável do uso de C, C++ em relação a outras linguagens modernas de nível superior, como Java/Python, é seu desempenho. Porque C/C++ é compilado e não interpretado. Um dos maiores benefícios de usar C, C++ é seu desempenho em comparação com outras linguagens modernas de alto nível, como Java/Python. Porque C/C++ é compilado e não interpretado.Os processadores entendem binários. Geralmente, quando você constrói um aplicativo usando Java ou outras linguagens baseadas em JVM ao compilar seu projeto, ele compila o código legível por humanos em código de bytes que pode ser entendido pela JVM ou outras máquinas virtuais executadas no sistema operacional subjacente. Durante a execução, a VM interpreta esses bytecodes e os converte em binários que os processadores podem entender. O processador entende arquivos binários. Normalmente, ao construir um aplicativo usando Java ou outras linguagens baseadas em JVM ao compilar o projeto, ele compila o código legível por humanos em código de bytes que pode ser entendido pela JVM ou outra máquina virtual executada no sistema operacional subjacente. Quando executada, a VM interpreta esses bytecodes e os converte em binários que o processador pode entender
Etapas de execução para linguagens baseadas em VM
Por outro lado, C/C++ não executa em VMs e isso remove uma etapa do ciclo de execução e aumenta o desempenho. Ele compila diretamente o código legível por humanos em binários.
C/C++, por outro lado, não é executado na VM e remove esta etapa do ciclo de execução e melhora o desempenho. Ele compila código legível diretamente em binários.

Mas liberar e alocar variáveis nessas linguagens é uma grande dor. Embora a maioria das linguagens de programação lide com a alocação e remoção de objetos usando algoritmos Garbage Collector ou Reference Counting. No entanto, liberar e atribuir variáveis é uma grande dor nessas linguagens. Embora a maioria das linguagens de programação use um coletor de lixo ou algoritmo de contagem de referências para lidar com a criação e liberação de objetos.
Go traz o melhor dos dois mundos. Assim como linguagens de nível inferior como C/C++, Go é uma linguagem compilada. Isso significa que o desempenho está quase mais próximo das linguagens de nível inferior. Também utiliza coleta de lixo para alocação e remoção do objeto. Então, chega de instruções malloc() e free()!!! Legal!!! Go traz o melhor dos dois mundos. Assim como linguagens de baixo nível como C/C++, Go é uma linguagem compilada. Isso significa que o desempenho está quase próximo de linguagens de nível inferior. Ele também usa coleta de lixo para alocar e excluir objetos. Portanto, chega de instruções malloc() e free()! Legal! ! !
#####O código escrito em Go é fácil de manter (o código escrito em Go é fácil de manter). Deixe-me dizer uma coisa. Go não possui uma sintaxe de programação maluca como outras linguagens. Possui uma sintaxe muito organizada e limpa. Deixe-me dizer uma coisa. Go não possui uma sintaxe de programação maluca como outras linguagens. Possui uma sintaxe muito organizada e clara.
Os designers do Go no Google tinham isso em mente quando estavam criando a linguagem. Como o Google tem uma base de código muito grande e milhares de desenvolvedores estavam trabalhando nessa mesma base de código, o código deve ser simples de entender para outros desenvolvedores e um segmento de código deve ter efeito colateral mínimo em outro segmento do código. Isso tornará o código de fácil manutenção e modificação. Os designers do Go tinham isso em mente quando criaram a linguagem no Google. Como o Google tem uma base de código muito grande, com milhares de desenvolvedores trabalhando na mesma base de código, o código deve ser fácil de entender para outros desenvolvedores e uma seção do código deve ter efeitos colaterais mínimos em outra seção do código. Isso tornará o código sustentável e fácil de modificar.
Go deixa de fora intencionalmente muitos recursos das linguagens OOP modernas. Go deixa de fora intencionalmente muitos recursos das linguagens OOP modernas.
*Sem aulas. Tudo é dividido apenas em pacotes. Go tem apenas estruturas em vez de classes. *Sem aula. Tudo está dividido apenas em pacotes. Go só tem estruturas, não classes.
Does not support inheritance. Isso tornará o código fácil de modificar. Em outras linguagens como Java/Python, se a classe ABC herda a classe XYZ e você faz algumas alterações na classe XYZ, isso pode produzir alguns efeitos colaterais em outras classes que herdam XYZ. Ao remover a herança, Go também facilita a compreensão do código (já que não há superclasse para observar enquanto se olha um trecho de código). *不支持继承. Isso tornará o código fácil de modificar. Em outras linguagens como Java/Python, se a classe ABC herda a classe XYZ e você faz algumas alterações na classe XYZ, isso pode ter alguns efeitos colaterais em outras classes que herdam de XYZ. Ao remover a herança, Go facilita a compreensão do código (já que não há superclasse para observar ao examinar um trecho de código).- Sem construtores.
- Sem anotações. *Sem genéricos. *Sem exceções.
As alterações acima tornam o Go muito diferente de outras linguagens e tornam a programação em Go diferente das outras. Você pode não gostar de alguns pontos acima. Porém, não é como se você não pudesse codificar seu aplicativo sem os recursos acima. Tudo que você precisa fazer é escrever mais 2 a 3 linhas. Mas pelo lado positivo, isso tornará seu código mais limpo e adicionará mais clareza a ele. As mudanças acima tornam o Go muito diferente de outras linguagens, e a programação em Go também é diferente de outras linguagens. Você pode não gostar de alguns dos pontos acima. No entanto, você não pode codificar seu aplicativo sem os recursos acima. Tudo que você precisa fazer é escrever mais 2 a 3 linhas. Mas pelo lado positivo, isso tornará seu código mais limpo e adicionará mais clareza a ele.
Legibilidade do código versus eficiência.
O gráfico acima mostra que Go é quase tão eficiente quanto C/C++, enquanto mantém a sintaxe do código simples como Ruby, Python e outras linguagens. Essa é uma situação ganha-ganha tanto para humanos quanto para processadores!!! A imagem acima mostra que Go é quase tão eficiente quanto C/C++, mantendo a sintaxe do código simples como Ruby, Python e outras linguagens. É uma situação ganha-ganha tanto para humanos quanto para processadores!
Ao contrário de outras novas linguagens como Swift, a sintaxe do Go é muito estável. Permaneceu o mesmo desde o lançamento público inicial 1.0, no ano de 2012. Isso o torna compatível com versões anteriores. Ao contrário de outras novas linguagens como Swift, a sintaxe do Go é muito estável. Ele permaneceu inalterado desde o lançamento público inicial do 1.0 em 2012. Isso o torna compatível com versões anteriores.##### Go é apoiado pelo Google.(Go é apoiado pelo Google.)
- Eu sei que isso não é uma vantagem técnica direta. Porém, Go foi projetado e suportado pelo Google. O Google possui uma das maiores infraestruturas de nuvem do mundo e é enormemente dimensionada. Go foi projetado pelo Google para resolver seus problemas de suporte à escalabilidade e eficácia. Esses são os mesmos problemas que você enfrentará ao criar seus próprios servidores. *Eu sei que isso não é uma vantagem técnica direta. No entanto, Go foi projetado e suportado pelo Google. O Google possui uma das maiores infraestruturas de nuvem do mundo e é enorme. Go foi projetado pelo Google para resolver os problemas de suporte à escalabilidade e eficácia. Estas são as mesmas questões que você enfrentará ao criar seu próprio servidor.
- Mais ainda, Go também é usado por algumas grandes empresas como Adobe, BBC, IBM, Intel e até Medium. (Fonte: https://github.com/golang/go/wiki/GoUsers)
- O mais importante é que Go também é usado por algumas grandes empresas, como Adobe, BBC, IBM, Intel e até Medium. (Fonte: https://github.com/golang/go/wiki/GoUsers)
Conclusão:
- Embora Go seja muito diferente de outras linguagens orientadas a objetos, ainda é a mesma fera. Go oferece alto desempenho como C/C++, manipulação de simultaneidade supereficiente como Java e diversão para codificar como Python/Perl.
- Embora Go seja muito diferente de outras linguagens orientadas a objetos, ainda é a mesma fera. Go oferece alto desempenho como C/C++, processamento simultâneo ultraeficiente como Java e a alegria de codificar como Python/Perl.
- Se você não tem planos de aprender Go, ainda direi que o limite de hardware pressiona nós, desenvolvedores de software, a escrever códigos supereficientes. O desenvolvedor precisa entender o hardware e otimizar seu programa de acordo. O software otimizado pode ser executado em hardware mais barato e mais lento (como dispositivos IOT) e ter um impacto geral melhor na experiência do usuário final.
- Se você não tem planos de aprender Go, eu ainda diria que as limitações de hardware nos pressionam, como desenvolvedores de software, a escrever códigos supereficientes. Os desenvolvedores precisam entender o hardware e otimizar seus programas de acordo. O software otimizado pode ser executado em hardware mais barato e mais lento (como dispositivos IoT) e, em geral, ter um impacto melhor na experiência do usuário final.
Dica
Como coletar registros de falhas por meio do APP on-line
-
Use NSSetUncaughtExceptionHandler, uma função pronta fornecida no iOS SDK. NSSetUncaughtExceptionHandler é usado para tratamento de exceções. O uso é o seguinte:
//异常回调方法 void UncaughtExceptionHandler(NSException *exception) { NSArray *arr = [exception callStackSymbols]; NSString *reason = [exception reason]; NSString *name = [exception name]; NSLog(@"%@\n%@\n%@",arr, reason, name); } - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. NSSetUncaughtExceptionHandler(&UncaughtExceptionHandler);//注册异常回调方法 NSArray *arr = @[@(0), @(1)]; NSLog(@"%@", arr[2]); //模拟越界异常 return YES; }Uma coisa que você precisa prestar atenção ao usá-lo é que quando vários serviços de coleta de log de falhas coexistem, por exemplo, o SDK de terceiros usado no projeto pode ter seu próprio serviço integrado de coleta de falhas. Quando houver vários serviços de coleta de Crash, ocorrerá competição, fazendo com que alguns serviços de Crash não funcionem corretamente. Se várias partes registrarem manipuladores de exceção por meio de NSSetUncaughtExceptionHandler ao mesmo tempo, a abordagem pacífica será: o registrante posterior usará NSGetUncaughtExceptionHandler para retirar e fazer backup do manipulador previamente registrado por outros e, após seu próprio manipulador ser processado, registrar conscientemente os manipuladores de outras pessoas e repassá-los de maneira ordenada. A consequência de não passar na substituição forçada é que o log de falha gravado pelo serviço de coleta de log registrado anteriormente perderá o Backtrace de última exceção e outras informações porque não pode obter o NSException. (P.S. O Crash Reporter que vem com o sistema iOS não é afetado) Durante a fase de desenvolvimento e teste, você pode usar a estrutura fishhook para conectar o método NSSetUncaughtExceptionHandler, para que você possa ver claramente onde o processo de entrega do manipulador está quebrado e localizar rapidamente os poluidores ambientais. Não é recomendado usar o depurador para adicionar pontos de interrupção simbólicos para verificação porque algumas estruturas de coleta de falhas não funcionam no estado de depuração.
Exemplo de código de detecção:
static NSUncaughtExceptionHandler *g_vaildUncaughtExceptionHandler; static void (*ori_NSSetUncaughtExceptionHandler)( NSUncaughtExceptionHandler * ); void my_NSSetUncaughtExceptionHandler( NSUncaughtExceptionHandler * handler) { g_vaildUncaughtExceptionHandler = NSGetUncaughtExceptionHandler(); if (g_vaildUncaughtExceptionHandler != NULL) { NSLog(@"UncaughtExceptionHandler=%p",g_vaildUncaughtExceptionHandler); } ori_NSSetUncaughtExceptionHandler(handler); NSLog(@"%@",[NSThread callStackSymbols]); g_vaildUncaughtExceptionHandler = NSGetUncaughtExceptionHandler(); NSLog(@"UncaughtExceptionHandler=%p",g_vaildUncaughtExceptionHandler); }O parágrafo acima foi extraído de - Falando sobre iOS Crash Collection Framework: http://www.cocoachina.com/ios/20150701/12301.html
-
Usando sinal, NSSetUncaughtExceptionHandler não pode lidar com todas as exceções. Para falhas causadas por EXC_BAD_ACCESS, NSSetUncaughtExceptionHandler é impotente. Nesse caso, o sinal precisa ser usado para lidar com isso. O que é sinal?
Na ciência da computação, os sinais são um método restrito de comunicação entre processos em sistemas operacionais Unix, semelhantes ao Unix e outros sistemas operacionais compatíveis com POSIX. É um mecanismo de notificação assíncrona usado para lembrar ao processo que ocorreu um evento. Quando um sinal é enviado a um processo, o sistema operacional interrompe o fluxo normal de controle do processo. Neste momento, quaisquer operações não atômicas serão interrompidas. Se o processo definir um manipulador de sinal, ele será executado, caso contrário, o manipulador padrão será executado.
O método de uso é o mesmo acima, o que também é obtido registrando retornos de chamada. 1 Cadastre-se
void InstallUncaughtExceptionHandler(void){ //设置信号类型的异常处理 signal(SIGABRT, HandleSignal); signal(SIGILL, HandleSignal); signal(SIGSEGV, HandleSignal); signal(SIGFPE, HandleSignal); signal(SIGBUS, HandleSignal); signal(SIGPIPE, HandleSignal); } void HandleSignal(int signal){ int32_t exceptionCount= OSAtomicIncrement32(&exceptionCount); if (exceptionCount>exceptionMaximum) { return; } NSMutableDictionary *userInfo=[NSMutableDictionary dictionaryWithObject:[NSNumber numberWithInt:signal] forKey:UncaughtExceptionHandlerSignalKey]; NSArray *callBack=[UncaughtExceptionHandler backtrace]; [userInfo setObject:callBack forKey:UncaughtExceptionHandlerAddressesKey]; UncaughtExceptionHandler *uncaughtExceptionHandler=[[UncaughtExceptionHandler alloc] init]; NSException *signalException=[NSException exceptionWithName:UncaughtExceptionHandlerSignalExceptionName reason:[NSString stringWithFormat:@"Signal %d was raised.",signal] userInfo:userInfo]; [uncaughtExceptionHandler performSelectorOnMainThread:@selector(handleException:) withObject:signalException waitUntilDone:YES]; }Para obter detalhes, consulte o código: https://github.com/dandan2009/Signal
A coleção iOS Crash é um grande tópico. Este artigo é uma introdução preliminar. Se quiser se aprofundar, você precisa entender o sistema operacional e outros conhecimentos. Vamos estudá-lo em profundidade mais tarde.
Referência: Falando sobre a estrutura de coleta de iOS Crash: http://www.cocoachina.com/ios/20150701/12301.html Análise de falha do iOS: https://www.jianshu.com/p/1b804426d212、http://www.qidiandasheng.com/2016/04/10/crash-xuebeng/ Análise do log de falhas do aplicativo iOS: http://www.cocoachina.com/industry/20130725/6677.html Captura de exceção do iOS: http://www.iosxxx.com/blog/2015-08-29-iosyi-chang-bu-huo.html Use o sinal para permitir que o aplicativo trave com calma: https://www.cnblogs.com/daxiaxiaohao/p/4466097.html https://github.com/walkdianzi/DSSignalHandlerDemo
Compartilhar
Compartilhe alguns métodos de aprendizagem de inglês para alunos que não passaram no CET-4, têm uma base de inglês ruim e desejam melhorar seu inglês: (a maior parte do conteúdo a seguir foi extraído, clique no link correspondente para obter detalhes)
-
APLICATIVO para aprender inglês: Na verdade, vá até a App Store e pesquise as palavras-chave Inglês e Leitura em inglês. Existem muitos APPs, alguns são pagos e outros gratuitos. Você pode escolher de acordo com suas necessidades.
-
Site de aprendizagem de inglês https://www.rong-chang.com/ http://www.bbc.co.uk/learningenglish/ https://dictionary.cambridge.org/ http://www.dictionary.com/ Artigos científicos em inglês: https://medium.com/
-
Prática de pronúncia: Curso de símbolos fonéticos do Himalaya Lai Shixiong4. Rato na orelha esquerda - sugestão de Chen Hao (veja o curso https://time.geekbang.org/column/intro/48 Chen Hao para detalhes):
- Use palavras-chave em inglês do Google em vez de pesquisar em chinês no Google. 2 Somente em inglês no GitHub. Escreva comentários de código em inglês, escreva informações de Code Commit, escreva Issues e Pull Requests em inglês e escreva Wiki em inglês. 3 Comprometa-se a assistir 5 minutos de vídeos no YouTube todos os dias. Existem legendas de máquinas relacionadas no YouTube. Se não funcionar, basta ativar as legendas.
- Insista em usar um dicionário de inglês em vez de chinês. Por exemplo: Cambridge English Dictionary (https://dictionary.cambridge.org/) ou Dictionary.com (http://www.dictionary.com/). Você pode instalar uma extensão do Chrome chamada Google Dictionary (https://chrome.google.com/webstore/detail/google-dictionary-by-goog/mgijmajocgfcbeboacabfgobmjgjcoja).
- Insista em usar materiais didáticos de inglês em vez de chineses. Por exemplo: Learning English da BBC (http://www.bbc.co.uk/learningenglish/), ou confira alguns sites de ESL, como ESL: English as a Second Language (https://www.rong-chang.com/), que possui alguns cursos. 6 Gaste dinheiro para fazer alguns cursos de inglês online e praticar com estrangeiros por meio de vídeos.
-
Como aprendi inglês com tinyfool (Como aprender a ouvir, falar, ler e escrever sem passar no CET-4) (https://mp.weixin.qq.com/s?__biz=MjM5MjUwNzIyMA==&mid=207623278&idx=1&sn=051a2ecae8f0392631eb0967eefc607a#rd)摘录: Ler a documentação não exige que seu inglês seja tão bom quanto o meu. Basta procurar em um dicionário. Existem apenas algumas centenas de palavras na documentação técnica. Você não precisa memorizar nada. Basta procurar sempre que não entender alguma coisa. Você pode basicamente dominá-lo depois de assisti-lo por uma semana. Este método já foi dito inúmeras vezes, e aqueles que se recusarem a experimentá-lo permanecerão tecnicamente analfabetos em inglês pelo resto da vida.
Não passei no CET-4… Enfim, quando olho o documento, se encontro alguma palavra que não conheço, só uso o Google Translate… Verifico a API 3 ou 5 vezes e você nem consegue lembrar… São apenas algumas palavras técnicas…
-
Aprenda muito. Você tem que assistir dramas americanos que não entende, tem que ouvir podcasts que não entende, tem que ler livros que não entende, tem que ter conversas com estrangeiros que não consegue entender e tem que escrever artigos em inglês que não consegue escrever bem.
-
Passo a passo. Embora seja um aprendizado difícil, você certamente progredirá do mais superficial para o mais profundo no início, para ter sempre uma sensação de realização.
-
Busque a quantidade máxima de material. O objetivo do passo a passo é nunca se sentir frustrado, então você pode passar muito tempo assistindo séries de TV americanas (pelo menos milhares de horas), ouvindo podcasts (centenas de horas), falando bobagens para estrangeiros e escrevendo artigos.
-
Melhorar gradualmente e evoluir lentamente, desde o aprendizado do próprio idioma até o aprendizado da cultura e a comunicação com o mundo. Quanto mais profundo for esse processo, mais motivado você estará para aprender.
-
Não seja impaciente e não avance precipitadamente. Cada dia fará de você um peão e você não conseguirá nada rapidamente. Levei meio ano para começar a assistir séries de TV americanas, mas ainda assisto agora. Levei um mês para ouvir o Podcast para descobrir. Demorou alguns meses para falar e alguns meses para escrever. Parece uma perda de tempo, mas depois de alguns anos, quando quero melhorar minhas habilidades, sinto que o tempo que gastei não é muito, muito pouco, e vale muito a pena.
-
Fique feliz para poder persistir no aprendizado ao longo da vida. Meu nível de inglês é alto? É muito mais alto do que antes. É alto o suficiente? Não é alto o suficiente. Mas o que posso me orgulhar é que agora meu aprendizado de inglês é um aprendizado para toda a vida. Não importa se você é superior a mim. A maioria das pessoas não aprende tão rápido quanto eu e, ao contrário de mim, que continuo aprendendo, um dia irei superar você. (Claro, o mais importante é sempre se esforçar todos os dias para superar o ontem.)
-
-
Perguntas e respostas de Zhihu: Mas no final, descobri que o método mais eficaz é na verdade o método mais estúpido - leia mais, ouça mais, faça mais anotações, escreva mais, resuma, pratique de novo e de novo…
Na verdade, não existem tantas maneiras de aprender inglês.
Se você pensar bem, muitas vezes os chamados métodos de aprendizagem “mais eficientes” são frequentemente os menos eficientes. Porque eles só proporcionam satisfação de curto prazo.
A chave para o progresso a longo prazo é saber se você consegue persistir. Persistência significa fazer a mesma coisa repetidamente.
E gradualmente percebi,
Eu nunca vou aprender inglês,
Porque sempre há palavras e usos que não conheço,
Mas estou disposto a continuar aprendendo até o último dia.
Porque a aprendizagem ao longo da vida é a maneira mais legal de uma pessoa viver.
======== https://www.zhihu.com/question/19853667/answer/134793017 Meu método é muito simples e estúpido, e deve funcionar para estudantes que realmente amam e querem aprender bem inglês.
Sempre que vejo alguém memorizando palavras com seriedade, sinto que essa pessoa não deve ser capaz de aprender bem inglês. Quanto mais palavras ele memoriza e mais seriamente as memoriza, mais longe ele fica do objetivo de ser um mestre inglês.
Lembro-me de quando estava na faculdade, sempre ouvia alguns colegas recitando “abandonar, abandonar, a, b, a, n, d, o”, em voz alta no corredor.
n, a, b, a, n, d, o, n" repetidamente. Quanto mais eu recito, mais apaixonado fico. Começo a recitá-lo a partir da primeira página do livro de vocabulário. Posso recitar várias páginas em uma noite. Sou tão apaixonado por aprender. Não é um desperdício de esforço. Provavelmente esquecerei tudo no dia seguinte, depois de voltar a dormir à noite.
Se um aluno do ensino fundamental ou médio memoriza palavras como essa para aprender inglês, acho que não há nada de errado com isso. Se um estudante universitário que deseja fazer o exame CET-6 memoriza palavras como essa para se preparar para o exame, eu realmente quero ir até lá, tirar seus livros e dar-lhe uma mordida. Isso é realmente aprender inglês? Mais tarde, vi que aquelas pessoas que memorizavam palavras tinham membros relativamente desenvolvidos, então desisti da ideia.
Mas eu quero dizer que se você seguir esse método de aprendizagem para aprender inglês, então você deveria aprender chinês assim. A partir da primeira página da lista de vocabulário, você deve memorizar assim:
“Um, um, horizontal, horizontal, horizontal.”
“Dois, dois, horizontais, horizontais, horizontais.”
“Três, três, horizontal, horizontal, horizontal, horizontal, horizontal.”
“Quatro, quatro, vertical, dobra horizontal, canhoto, destro, horizontal, vertical, dobra horizontal, canhoto, destro, horizontal, vertical, dobra horizontal, canhoto, destro, horizontal.”
. . . . . .
Se você memorizar a porra do “macarrão biang biang” de Shaanxi, acho que você vai morrer.
Vamos ver como escrever a palavra biang! Realmente não é assim que você aprende inglês. Nunca vi ninguém aprender chinês desta forma, mas muitas pessoas aprendem inglês desta forma. Embora o inglês e o chinês sejam diferentes, os princípios são os mesmos.
Então, como devemos aprender isso?
Na verdade, você pode imaginar como aprende chinês e aprender inglês com isso.
Quando éramos jovens, aprendemos a escrever caracteres chineses, escrever novos caracteres e reconhecer palavras. Isso pode ser comparado a memorizar palavras, mas são coisas que você faz quando está no ensino fundamental. Você pode fazer isso quando aprender um idioma pela primeira vez, porque sua base é muito ruim neste estágio e você não conhece as palavras mais comuns, então você precisa escrever novas palavras e memorizá-las, mas você já está no ensino médio, está aprendendo chinês e começa a escrever novas palavras da lista de vocabulário dos livros didáticos do ensino fundamental. Qual é o conceito de escrever novas palavras? Você está na faculdade e precisa fazer o exame CET-6. Você passa a maior parte do tempo estudando inglês memorizando palavras. Não acredito que você possa aprender inglês bem.
Como aprendemos chinês no ensino médio?
Ler, ler e ler de novo, em inglês é ler, ler e ler, escrever, escrever e escrever de novo, em inglês é escrever, escrever e escrever.
Algumas pessoas certamente me refutarão e dirão: como posso ler se não conheço as palavras?
Você pode encontrar alguns artigos que são adequados para você ler e ler muito. Durante o processo de leitura, você certamente encontrará muitas palavras que não conhece. Você também encontrará palavras desconhecidas ou que não entende durante a leitura em chinês. Isso é normal. O que você deve fazer? Basta procurar no dicionário e continuar lendo. À medida que seu volume de leitura aumenta, você descobrirá que os artigos desse nível exigem que você procure cada vez menos palavras e, então, mudará para um artigo de alto nível para leitura. Apenas continue fazendo isso. Quando o seu volume de leitura em inglês atingir um determinado nível, seu vocabulário aumentará naturalmente.
Você entende o que quero dizer? Não memorize palavras, será muito chato lembrar. Leia muito, leia como um louco. Quando sua leitura atingir um determinado nível, exceto ouvir e falar, seu inglês será aprovado.
Tenho medo de que meu inglês piore se um dia eu esquecer de ler em inglês, então meu telefone está sempre no modo inglês. Às vezes as pessoas querem usar meu telefone, mas não podem.
Aprender inglês é tão simples e tão estúpido. https://www.zhihu.com/question/26677313/answer/230847636?group_id=892423340218806272
=======
Muitos dos conteúdos acima são trechos. Para obter detalhes, clique no link correspondente: Para resumir o método acima, não tenha medo do inglês, mas aprenda com afinco. O significado de aprender aqui é ousar ler artigos em inglês e não desistir. Ao encontrar palavras que não conhece, você deve consultar ativamente o dicionário em vez de desistir. Não deveria ser doloroso. Quando você sentir que aprender inglês é doloroso, pare de aprender. Na verdade, o efeito deve ser muito fraco neste momento.
Na verdade, minha nota de inglês no vestibular passou de uma nota baixa de 30 para mais de 100. Como melhorei naquela época? Na verdade, estava lendo. Ao ler, eu procurava palavras no dicionário e depois as memorizava. Memorizar palavras lendo artigos é muito melhor do que memorizar palavras apenas. Se a base não for boa, você pode começar primeiro com artigos simples e depois aumentar gradualmente a dificuldade. Para artigos técnicos, você pode ler a maioria deles com a ajuda do Google Translate. Depende se você consegue persistir. Contanto que você persista por meio ano e leia três artigos em inglês por semana, acho que sua habilidade em inglês 读 também melhorará.
=======
What to read next
Want more posts about ARTS?
Posts in the same category are usually the best next step for reading more on this topic.
View same categoryWant to keep following #iOS?
Tags are useful for related tools, specific problems, and similar troubleshooting notes.
View same tagWant to explore another direction?
If you are not sure what to read next, return to the homepage and start from categories, topics, or latest updates.
Back home