Que conceitos de Ciência da Computação devo saber? [fechadas]

94

Que conceitos da Ciência da Computação você acha que o tornaram um programador melhor?

Minha graduação foi em Engenharia Mecânica então, tendo acabado como programador, estou um pouco carente do básico. Existem alguns conceitos padrão de CS que aprendi recentemente que me deram uma compreensão muito mais profunda do que estou fazendo, especificamente:

Características da linguagem

  • Dicas e recursão (Obrigado, Joel!)

Estruturas de dados

  • Listas Ligadas
  • Hashtables

Algoritmos

  • Tipos de bolha

Obviamente, a lista é um pouco curta no momento, então eu esperava sugestões sobre:

  1. Que conceitos devo entender,
  2. Quaisquer bons recursos para compreendê-los adequadamente (já que a Wikipedia pode ser um pouco densa e acadêmica às vezes).
Jon Artus
fonte
5
Tipos de bolha? Fique o mais longe possível deles! Em vez disso, aprenda como funciona o quicksort / heapsort.
Carra de
18
Sim, aprenda o Bubblesort. Aprenda porque é terrível. Aprenda quicksort, mergesort e todo o resto, incluindo seus pontos fracos individuais. Mas não os escreva em código de produção: chame as funções de classificação fornecidas por qualquer plataforma em que você esteja.
Brian Ensink,
@Roger Pate - +1 para você, deve-se saber para que serve um algoritmo ou estrutura de dados e para que é ruim. Ambos Quicksort e Bubblesort têm o mesmo desempenho de pior caso [O (n ^ 2)], mas para tipos de entrada muito diferentes, e Bubblesort tem o desempenho de melhor caso de O (n), onde QS ainda é O (n log n). Claro, se você está considerando Bubblesort, então você pode querer ir para a classificação por inserção.
Andre Artus

Respostas:

60

Dê uma olhada nesta postagem do blog de Steve Yegge (ex-Amazon, agora no Google):

Ele fornece alguns detalhes sobre os cinco conceitos mais importantes que os desenvolvedores devem saber:

  1. Programação básica (incluindo recursão, E / S de arquivo, saída formatada, loops, etc.)
  2. Design orientado a objetos (incluindo padrões de design, etc.). Você deve ser capaz de produzir designs OO sensatos, bem como compreender os conceitos.
  3. Scripting e regexes.
  4. Estruturas de dados - listas, conjuntos, hashtables, árvores, gráficos e assim por diante - assim como notação Big O e complexidade algorítmica.
  5. Bits, bytes e números binários - como os números são representados no computador e como manipulá-los.
2 rotações
fonte
Link legal. Um pouco focado no lado unix, (faltando o .NET completamente), mas ainda bom.
Toon Krijthe
Ótimo link - há muito para eu trabalhar, só gostaria que tivesse alguns links para boas páginas explicando essas coisas.
Jon Artus
O link será muito útil para eu verificar e atualizar os fundamentos. Obrigado ..
rpr
Concordo, ótimo link. Embora muitas das soluções possíveis identificadas sejam baseadas em Unix, os conceitos gerais envolvidos são muito agnósticos de linguagem / plataforma. Para a maioria dos programadores, coisas como recursão, escrever ADT como árvores e operações bit a bit são muito raros, entretanto, são uma base importante.
Zach Burlingame de
4
Eu concordaria com tudo, exceto regexes. Esses são um bom bônus, mas a maioria das coisas é o básico no nível do solo, a base sobre a qual tudo é construído ... regexes são ótimos, mas eu conheço muitos programadores excelentes que nunca os usam e nunca precisam.
Beska
35

Você definitivamente deve compreender os Big-O estimativas notação e Big-O de algoritmos - o que é, como ele é usado, porque é importante, como você comparar dois algoritmos dadas as suas estimativas Big-O, como você construir estimativas Big-O para os algoritmos simples.

sharptooth
fonte
1
Você pode começar com um artigo da Wikipedia ao qual criei um link - é bastante simples e matematicamente correto.
sharptooth
3
Você deve ter uma opinião muito baixa sobre matemática avançada. Eu entendi isso no meu primeiro ano de faculdade, quando estava apenas parcialmente no cálculo.
GoatRider de
1
Não se esqueça do conceito de NP e quando um problema está contido nele, um desenvolvedor que tenta codificar um TSP (Caixeiro Viajante) em cada transação de banco de dados para um propósito de pesquisa ou alguma outra idiotice é um grande problema =]
Ed James,
2
Você também deve saber que o grande O não indica qual algoritmo leva menos tempo. Algo que a maioria dos formandos de CS não entende
Martin Beckett,
3
É meio que sim. Diz a você qual tem o melhor pior caso, não necessariamente qual é o 'mais rápido', pois isso depende do conjunto de entrada.
Ed James
30

Acho um pouco engraçado que você esteja procurando disciplinas de ciência da computação , mas acho a wikipedia muito acadêmica: D

Enfim, aqui vai, em nenhuma ordem particular:

Rik
fonte
2
+1 porque você mencionou bancos de dados, frequentemente esquecidos nesses tipos de listas, mas um conceito muito importante para qualquer graduado em ciência da computação bem informado.
Brian Ensink,
14

Alguns conceitos que ajudaram meu desenvolvimento (intelecto e código):

  • Lexing, Parsing, String matching, Regex
  • Memoização
    • encapsulamento / escopo / fechamentos
    • caching
  • Recursão
  • Iteradores / Geradores
  • Programação funcional - o incrível artigo de John Hughes me mostrou "por quê"

Esses são domínios inteiros da matemática discreta, mas uma introdução séria é necessária para o CS:

  • Matriz / Álgebra Linear
  • Teoria dos Grafos

Embora as palestras e artigos de Mark Jason-Dominus sejam frequentemente direcionados a hackers Perl, acho que qualquer programador se beneficiaria de sua apresentação clara e código real, especialmente em Higher Order Perl .

bubaker
fonte
10

Eu diria que hoje em dia é necessário entender a Programação Orientada a Objetos, mesmo que você não precise usá-la no dia a dia.

Com isso, eu também diria que entender os padrões mais comuns também pode ajudar.

Jeremy francês
fonte
10

Vejo vários bons conceitos de CS identificados, mas pouca conversa sobre matemática.

Eu sugiro que você procure matemática discreta . Ele tem uma ampla variedade de problemas úteis, começando com provas lógicas que o ajudam a escrever condições no código. A teoria dos grafos e a combinatória também ajudam na resolução de problemas complexos e na otimização de algoritmos.

Enquanto estamos no assunto de matemática, álgebra linear é normalmente um pré-requisito para aulas avançadas de computação gráfica.

Berkshire
fonte
1
Se eu tivesse que escolher apenas um, seria matemática discreta. É muito CS 101. Tenho dificuldade em pensar em uma área ou paradigma na programação geral que não seja tocado de alguma forma pelo DM.
Andre Artus
6

A Matriz de Competências do Programador cobriu isso em detalhes, mas vou destacar alguns:

  • Estruturas de dados
    • Estruturas de dados avançadas como árvores B, montes binomiais e fibonacci, árvores AVL / Red Black, Árvores Splay, Listas de Ignorar, tentativas, etc.
  • Algoritmos
    • Os algoritmos Tree, Graph, greedy simples e dividir e conquistar, são capazes de compreender a relevância dos níveis desta matriz.
  • Programação de sistemas
    • Compreende toda a pilha de programação, hardware (CPU + Memória + Cache + Interrupções + microcódigo), código binário, montagem, vinculação estática e dinâmica, compilação, interpretação, compilação JIT, coleta de lixo, heap, pilha, endereçamento de memória ...
  • Controle de versão do código fonte
    • Conhecimento de sistemas VCS distribuídos. Experimentou Bzr / Mercurial / Darcs / Git
  • Automação de construção
    • Pode configurar um script para construir o sistema e também documentação, instaladores, gerar notas de versão e marcar o código no controle de origem
  • Teste automatizado
    • Compreende e é capaz de configurar testes funcionais, de carga / desempenho e de IU automatizados
  • Decomposição do problema
    • Uso de estruturas de dados e algoritmos apropriados e fornece código genérico / orientado a objetos que encapsula aspectos do problema que estão sujeitos a mudanças.
  • Decomposição de sistemas
    • Capaz de visualizar e projetar sistemas complexos com várias linhas de produtos e integrações com sistemas externos. Também deve ser capaz de projetar sistemas de suporte de operações, como monitoramento, relatórios, falhas, etc.
cgp
fonte
5

Eu acho gráficos e alguns algoritmos aplicados como profundidade primeiro, respiração primeiro pesquisa, caminhos mais curtos etc muito úteis. A orientação a objetos também é um conceito muito comum.

Mork0075
fonte
4

Regra 1: Software é Captura de Conhecimento . Software significa algo. Se você não tiver certeza do significado, passe mais tempo conversando com os usuários para entender o que eles fazem.

Algoritmos e estruturas de dados são as duas faces da mesma moeda. O algoritmo depende da estrutura de dados, a estrutura de dados depende do algoritmo.

Desaprenda a classificação por bolhas o mais rápido possível. Seriamente. Todas as linguagens modernas (Java, Python, etc.) têm classes de coleção que implementam uma classificação melhor do que a classificação por bolha. Não há absolutamente nenhuma circunstância em que você deva usar a classificação por bolha para qualquer coisa. Você deve estar procurando por uma classe de coleção que inclua um método de classificação. Melhor, você deve procurar um algoritmo que evite completamente a classificação.

Você deve aprender vários idiomas.

  • Linguagem de programação (Java, Python, etc.)

  • Linguagem Shell.

  • Linguagem de banco de dados (SQL)

  • Linguagens de apresentação (HTML e CSS)

  • Outras linguagens de representação de dados (XML, JSON)

Você deve aprender várias estruturas de dados.

  • Sequências (listas, tuplas, arquivos)

  • Hierárquico (como documentos XML e HTML, bem como o sistema de arquivos básico)

  • Relacional (como bancos de dados e o sistema de arquivos com links físicos e virtuais inseridos)

  • Mapas (ou índices ou matrizes associativas), incluindo mapas de hash e mapas de árvore

  • Jogos

Além de algumas análises de complexidade algorítmica. Às vezes chamado de "Big O". A classificação por bolha é ruim porque é O ( n ^ 2), onde uma classificação rápida é O ( n log n ).

S.Lott
fonte
Só para constar, eu nunca usaria um tipo de bolha! Acabei de descobrir que aprender como funciona é uma experiência interessante e descobri que existem alguns outros algoritmos desse tipo que as pessoas devem entender bem o suficiente para escrever no idioma de sua escolha.
Jon Artus
Existem inúmeros algoritmos. A maioria deles é ruim. Alguns deles bons. O Bubble Sort é simplesmente mau. Compre QUALQUER livro sobre algoritmos e siga em frente.
S.Lott,
Apenas nit picking, mas Quicksort é o pior caso O (n ^ 2). Só aponto isso porque acho que entender por que isso é verdade é um exercício educacional valioso ao estudar algoritmos fundamentais.
Brian Ensink,
Para quicksort, sim - um exercício importante. Para classificação por bolha, a única coisa é ver o quão ruim é um algoritmo. Compreender o caso típico e o pior caso é importante em geral.
S.Lott,
4

Bem, a lata de minhocas está aberta agora! :)
Comecei na Engenharia Elétrica.

Design de banco de dados relacional: acompanhar os dados é como Arnold em "Kindergarden Cop".
Pode ser um caos total. Deve ser controlado.
Como manter seus dados, no menor número de locais, com o mínimo de duplicações de informações. Como manter seus dados leves e facilmente acessíveis. Como controlar o crescimento e a integridade dos dados.

Design da interface do usuário (IU): é assim que o usuário deve acessar os dados que estamos monitorando.
A maioria das interfaces do usuário é projetada por desenvolvedores. Portanto, a maioria das UIs, infelizmente, é paralela ao design do banco de dados. Os usuários não se importam com o design dos dados. Eles simplesmente querem, o que eles querem. Eles querem obtê-lo facilmente. Normalmente, isso exige uma grande separação do design de dados e da interface do usuário. Aprenda a separar você "engenheiro" da "hospitalidade sulista".

Programação orientada a objetos: muitas linguagens se resumem a este formato.

Processamento paralelo - Multi-Threading: Muitos processadores tornam o trabalho rápido!
Os computadores paralelos existem há décadas. Eles estão em nossos desktops há algum tempo. Com o caso da "computação em nuvem", o processamento paralelo massivo não é apenas obrigatório, mas também preferível. É incrivelmente poderoso! Há muito potencial de trabalho para desenvolvedores paralelos.

Noções básicas sobre regras de negócios: Isso o ajuda a fazer muito de sua lógica baseada em tabelas.
Muitas condições de IFblock podem estar em tabelas de regras de negócios. Para alterar a lógica, basta alterar as informações de uma tabela. Pouca / nenhuma recodificação. Pouca / nenhuma recompilação.

Supervisionar eventos ... Os métodos fazem o trabalho:
mantenha as coisas separadas em seu código. Isso torna mais fácil para outras pessoas fazerem atualizações no futuro. Ele também se assemelha um pouco à estrutura Model / View / Controller (MVC).

PJ

PJ
fonte
3

Para mim, ganhei muito com o seguinte curso no time do colégio

  • Gerenciamento de Projetos
  • Interação Homem-Computador (nos ajuda geeks a criar telas mais amigáveis)
  • Projeto de banco de dados (incluindo o funcionamento dos bancos de dados, registros de transações, bloqueio, etc.)
  • Armazenamento de dados
  • Gráficos (OpenGL)
  • Algoritmos Avançados
  • Estruturas de dados

Coisas que eu gostaria de ter feito no time do colégio

  • Construção do Compilador
  • Padrões de design
  • Teoria dos autômatos
uriDium
fonte
3

LÓGICA - Eu apenas exagero a importância da lógica na programação. Você disse que fez Engenharia Mecânica, então deve saber o quanto a matemática pode tornar sua vida mais fácil.

Lógica proposicional , lógica de primeira ordem , lógica de segunda ordem : essas são ferramentas muito poderosas. Provavelmente as coisas mais (e únicas) importantes que aprendi na universidade. A lógica é como a artilharia pesada de um programador - muitos problemas muito complexos (assim como os menos complexos) tornam-se muito mais simples uma vez que você os coloca em uma forma lógica e organizada. É como a Álgebra Linear para os Engenheiros Mecânicos.

Tamas Czinege
fonte
3

Acho que é bom saber como funciona um compilador. Aho tem o livro clássico sobre conceitos usados ​​na criação de um compilador. O título é Compiladores: princípios, técnicas e ferramentas. Seu apelido é o Livro do Dragão. Para realmente entender esse livro, você deve ter uma compreensão de linguagens formais. Hopcroft tem um bom livro sobre isso - Introdução à Teoria dos Autômatos, Linguagens e Computação.

zooropa
fonte
2

Muitas boas respostas já foram mencionadas aqui, mas eu queria adicionar um subconjunto do que é importante, mas não foi abordado até agora.

Após 15 anos de pós-graduação em desenvolvimento profissional de software, descobri que uso regularmente alguns dos seguintes conceitos na escola:

  • Conceitos gerais OO e recursos de linguagem de programação moderna (classes, ocultação de dados, etc).
  • Métricas de desempenho do algoritmo (notação Big O). Ao projetar um algoritmo, realizar uma análise Big O para determinar o custo do algoritmo e procurar alternativas mais eficientes em áreas de gargalo.
  • Listas vinculadas e outras estruturas de dados complexas.
  • Classificação rápida e diferentes conceitos de classificação.
  • Árvores e manipulação rápida de árvores.

Se o seu idioma / plataforma não suportar a Coleta de Lixo, a alocação e a limpeza da memória são críticas e seriam adicionadas à lista.

Pearcewg
fonte
2

Eu votei positivamente em matemática discreta. A ciência da computação é abstração. aprender a pensar como um matemático é muito útil.

Eu também queria acrescentar algo ao que S.Lott disse sobre idiomas. Aprender vários TIPOS de idiomas também é importante. Não apenas compilado versus script. Mas funcional (ML, Lisp, Haskell) lógico (Prolog) orientado a objeto (C ++, Java, Smalltalk) imperativo (C, Pascal, FORTRAN até).

Quanto mais paradigmas de programação você conhece, mais fácil é aprender novas linguagens quando a nova linguagem quente aparecer!

Brian Postow
fonte
2

Alguns dos conceitos do sistema operacional

 ( memory, IO, Scheduling, process\Threads, multithreading )

[um bom livro " Modern Operating Systems , 2nd Edition, Andrew S. Tanenbaum"]

Conhecimento básico de redes de computadores

[um bom livro de Tanenbaum

Conceitos OOPS

Autometa finito

Uma linguagem de programação (aprendi C primeiro, depois C ++)

Algoritmos (complexidade de tempo \ espaço, classificação, pesquisa, árvores, lista vinculada, pilha, fila)

[um bom livro Introdução aos Algoritmos ]

aJ.
fonte
auto meta? - certamente "autômatos" conforme a primeira edição.
Tom Duckering,
Ops! atolado para verificar a ortografia, eu acho. Eu vou corrigir isso. Obrigado.
aJ.
1

Tente compreender todos os níveis de programação. Do nível mais baixo (montagem) ao nível mais alto.

Pegue a recursão, por exemplo, que é um recurso fácil :) Tente aprender a montagem e crie um programa que usará a recursão na montagem.

Chrys
fonte
1

Algoritmos.

Aprender a usar uma linguagem de programação de forma descendente é algo que você pode aprender conforme avança, mas é virtualmente impossível inventar sozinho todos os algoritmos amplamente usados. Deve-se pelo menos estar ciente do que pode e não pode ser feito com alguns problemas.

Por exemplo, não se pode simplesmente escrever alguns programas com classificação por bolha e esperar que sejam considerados bons, não importa quão bom seja o código.

Para resumir - dê uma olhada em Introdução aos Algoritmos

Não há necessidade de dominar, apenas saiba o que está acontecendo ...

Liran Orevi
fonte
1

Como recém-formado em ciência da computação, eu recomendaria o seguinte:

CodeMonkey
fonte
1

É claramente um bom entendimento da programação orientada a objetos, bons princípios orientadores como os Princípios SOLID e seguir padrões e práticas estabelecidas.

Se você olhar para SOA, ou DDD, todos eles acabam caindo de volta para alguma forma de conceitos OOP.

Eu recomendo que você obtenha alguns bons livros OOP e também escolha uma linguagem rica como C # ou Java para começar

OOP por Grady Booch

(PHP, ruby, por favor, não votem em mim, estou apenas dando alguns exemplos para ele, para começar, vocês podem fornecer suas próprias respostas e sugestões aqui)

Srikar Doddi
fonte
1

Estrutura e Interpretação de Programas de Computador . Se você entende este livro, tudo o mais pode ser construído facilmente sobre essa base. Se você tiver problemas com os conceitos do livro, pode ser um desenvolvedor de software, mas não um cientista da computação.

lambdabunny
fonte
1

Não vou lhe dizer nenhum conceito específico para estudar, mas, em vez disso, recomendo que você faça muitas leituras leves sobre uma ampla gama de tópicos. Não se preocupe em obter uma compreensão aprofundada de cada assunto sobre o qual lê - neste ponto, é mais importante que você seja capaz de reconhecer de que tipo de problema que está olhando, para que possa fazer apenas ... estudar no tempo quando você realmente se depara com ele. Em outras palavras, está tudo bem se você não souber como resolver um problema de combinatória, desde que saiba o suficiente para pesquisar "combinatória" quando precisar ver de quantas maneiras pode organizar um conjunto de objetos ou escolher um subconjunto .

A Wikipedia é um recurso muito bom para esse tipo de navegação abrangente, especialmente se você estiver apenas folheando. Um ainda melhor, especialmente se você achar a Wikipedia muito acadêmica ou inacessível, é a wiki C2 . (Este é, curiosamente, o wiki original inventado por Ward Cunningham).

John Hyland
fonte
0

Eu acho que é essencial entender a teoria básica por trás do multi-threading, sem isso pode ser difícil até ver que pode haver um problema, até que você esteja depurando em um servidor ao vivo às 4 horas de uma manhã de domingo.

Semáforos, seções críticas e eventos.

Jim T
fonte
0

Não, não tipo bolha, quicksort. É o big-O - a classificação da bolha tem média O (n ^ 2), a classificação rápida é O (n * log (n)).

GoatRider
fonte
0

Eu diria que abaixo estão as coisas mais importantes

  • Programação Orientada a Objetos
  • Conceitos de sistema operacional
    • Processo e discussão
    • Algoritmos de escalonamento
  • Estrutura de dados
    • Tipo de armazenamento e coleta de dados, tipos (lista vinculada, hash, matriz etc.)
    • Algoritmos de classificação
    • Complexidade de algoritmos

Em seguida, vá para o material relacionado ao idioma específico. Espero que isto seja útil!!

Mutante
fonte
0

Eu começaria com a citação:

“se a única ferramenta que você tem é um martelo, você trata tudo como um prego”. (Abraham Maslow)

O princípio mais importante, IMO, é conhecer os mais diversos paradigmas de programação, linguagens e informar-se bem sobre as ferramentas à sua disposição. Qualquer problema pode ser resolvido em quase qualquer idioma que você escolher, seja em uma linguagem mainstream completa com sua enorme biblioteca padrão ou em uma pequena linguagem especializada como AutoHotKey. A primeira tarefa do programador é determinar o que usar de acordo com a especificação do problema. Alguns conceitos fornecem uma melhor abordagem ao tópico, seja qual for o seu objetivo principal - sofisticação, ofuscação, desempenho, portabilidade, manutenção, tamanho de código pequeno ...

Caso contrário, você terminará como alguns dos programadores que tentam desesperadamente fazer algo em uma linguagem que eles se especializaram, embora o problema possa ser trivial de resolver em diferentes contextos de programação.

Este conselho vai junto com a tendência atual para projetos multilíngues (tome os aplicativos da web, por exemplo, que podem envolver várias linguagens em um único aplicativo, como C #, JS, CSS, XPath, SQL, XML, HMTL, RegExp .... e até mesmo diferentes paradigmas de programação (por exemplo, C # introduziu recentemente alguns conceitos de paradigmas de programação funcional, lambdas).

Então, o básico é o aprendizado constante, para sempre :)

majkinetor
fonte
0

Acho que gráficos 3D é algo que todos deveriam aprender. Ou pelo menos como usar vetores homogêneos e transformadas de matriz.

Pode ser útil não apenas para a criação de aplicativos 3D, mas também nos campos da mecânica como cinemática inversa em robôs, cálculos de momentos e muitas outras coisas.

Eu não entendia totalmente de álgebra linear até ler gráficos 3D, um dos melhores cursos que já fiz, embora nosso professor fosse ruim.

TheDude
fonte
0

Uma vez que máquinas com vários núcleos (CPU e GPU) estão se tornando o padrão, eu diria para incluir Algoritmos Distribuídos (de vários threads a várias máquinas). É fundamental compreender o processamento distribuído e multithread. Lamentamos que o link não forneça muita ajuda.

Erich Mirabal
fonte